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;
44 //------------------------------------------------------------------------------
45 /** Initialize const static memeber data */
47 Pango::FontDescription* TimeAxisViewItem::NAME_FONT = 0;
48 bool TimeAxisViewItem::have_name_font = false;
49 const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
50 const double TimeAxisViewItem::GRAB_HANDLE_LENGTH = 6 ;
52 double TimeAxisViewItem::NAME_Y_OFFSET;
53 double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
54 double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
57 //---------------------------------------------------------------------------------------//
58 // Constructor / Desctructor
61 * Constructs a new TimeAxisViewItem.
63 * @param it_name the unique name/Id of this item
64 * @param parant the parent canvas group
65 * @param tv the TimeAxisView we are going to be added to
66 * @param spu samples per unit
68 * @param start the start point of this item
69 * @param duration the duration of this item
71 TimeAxisViewItem::TimeAxisViewItem(const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color& base_color,
72 nframes_t start, nframes_t duration, bool recording,
74 : trackview (tv), _recregion(recording)
76 if (!have_name_font) {
78 /* first constructed item sets up font info */
80 NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName"));
86 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
90 layout->set_font_description (*NAME_FONT);
91 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
93 NAME_Y_OFFSET = height + 6;
94 NAME_HIGHLIGHT_SIZE = height + 6;
95 NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 2;
97 have_name_font = true;
100 group = new ArdourCanvas::Group (parent);
102 init (it_name, spu, base_color, start, duration, vis);
106 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
107 : trackview (other.trackview)
113 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
114 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
116 /* share the other's parent, but still create a new group */
118 Gnome::Canvas::Group* parent = other.group->property_parent();
120 group = new ArdourCanvas::Group (*parent);
122 init (other.item_name, other.samples_per_unit, c, other.frame_position, other.item_duration, other.visibility);
127 TimeAxisViewItem::init (const string& it_name, double spu, Gdk::Color& base_color, nframes_t start, nframes_t duration, Visibility vis)
129 item_name = it_name ;
130 name_text_width = ::pixel_width (it_name, *NAME_FONT);
131 last_name_text_width = 0;
132 samples_per_unit = spu ;
133 should_show_selection = true;
134 frame_position = start ;
135 item_duration = duration ;
136 name_connected = false;
138 position_locked = false ;
139 max_item_duration = ARDOUR::max_frames;
140 min_item_duration = 0 ;
141 show_vestigial = true;
146 warning << "Time Axis Item Duration == 0" << endl ;
149 vestigial_frame = new ArdourCanvas::SimpleRect (*group);
150 vestigial_frame->property_x1() = (double) 0.0;
151 vestigial_frame->property_y1() = (double) 1.0;
152 vestigial_frame->property_x2() = 2.0;
153 vestigial_frame->property_y2() = (double) trackview.current_height();
154 vestigial_frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
155 vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
156 vestigial_frame->hide ();
158 if (visibility & ShowFrame) {
159 frame = new ArdourCanvas::SimpleRect (*group);
160 frame->property_x1() = (double) 0.0;
161 frame->property_y1() = (double) 1.0;
162 frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration);
163 frame->property_y2() = (double) trackview.current_height();
164 frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
165 frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
167 /* by default draw all 4 edges */
169 uint32_t outline_what = 0x1|0x2|0x4|0x8;
171 if (visibility & HideFrameLeft) {
172 outline_what &= ~(0x1);
175 if (visibility & HideFrameRight) {
176 outline_what &= ~(0x2);
179 if (visibility & HideFrameTB) {
180 outline_what &= ~(0x4 | 0x8);
183 frame->property_outline_what() = outline_what;
189 if (visibility & ShowNameHighlight) {
190 name_highlight = new ArdourCanvas::SimpleRect (*group);
191 if (visibility & FullWidthNameHighlight) {
192 name_highlight->property_x1() = (double) 0.0;
193 name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration));
195 name_highlight->property_x1() = (double) 1.0;
196 name_highlight->property_x2() = (double) (trackview.editor.frame_to_pixel(item_duration)) - 1;
198 name_highlight->property_y1() = (double) (trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
199 name_highlight->property_y2() = (double) (trackview.current_height() - 1);
200 name_highlight->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightFill.get();
201 name_highlight->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightOutline.get();
203 name_highlight->set_data ("timeaxisviewitem", this);
209 if (visibility & ShowNameText) {
210 name_text = new ArdourCanvas::Text (*group);
211 name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
212 /* trackview.current_height() is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
213 then NAME_Y_OFFSET to position the text in the vertical center of the highlight
215 name_text->property_y() = (double) trackview.current_height() - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
216 name_text->property_font_desc() = *NAME_FONT;
217 name_text->property_anchor() = Gtk::ANCHOR_NW;
219 name_text->set_data ("timeaxisviewitem", this);
225 /* create our grab handles used for trimming/duration etc */
227 if (visibility & ShowHandles) {
228 frame_handle_start = new ArdourCanvas::SimpleRect (*group);
229 frame_handle_start->property_x1() = (double) 0.0;
230 frame_handle_start->property_x2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH;
231 frame_handle_start->property_y1() = (double) 1.0;
232 frame_handle_start->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH+1;
233 frame_handle_start->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
234 frame_handle_start->property_fill_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();
242 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
245 frame_handle_start = 0;
246 frame_handle_end = 0;
249 set_color (base_color) ;
251 set_duration (item_duration, this) ;
252 set_position (start, this) ;
258 TimeAxisViewItem::~TimeAxisViewItem()
264 //---------------------------------------------------------------------------------------//
265 // Position and duration Accessors/Mutators
268 * Set the position of this item upon the timeline to the specified value
270 * @param pos the new position
271 * @param src the identity of the object that initiated the change
272 * @return true if the position change was a success, false otherwise
275 TimeAxisViewItem::set_position(nframes_t pos, void* src, double* delta)
277 if (position_locked) {
281 frame_position = pos;
283 /* This sucks. The GnomeCanvas version I am using
284 doesn't correctly implement gnome_canvas_group_set_arg(),
285 so that simply setting the "x" arg of the group
286 fails to move the group. Instead, we have to
287 use gnome_canvas_item_move(), which does the right
288 thing. I see that in GNOME CVS, the current (Sept 2001)
289 version of GNOME Canvas rectifies this issue cleanly.
292 double old_unit_pos ;
293 double new_unit_pos = pos / samples_per_unit ;
295 old_unit_pos = group->property_x();
297 if (new_unit_pos != old_unit_pos) {
298 group->move (new_unit_pos - old_unit_pos, 0.0);
302 (*delta) = new_unit_pos - old_unit_pos;
305 PositionChanged (frame_position, src) ; /* EMIT_SIGNAL */
311 * Return the position of this item upon the timeline
313 * @return the position of this item
316 TimeAxisViewItem::get_position() const
318 return frame_position;
322 * Sets the duration of this item
324 * @param dur the new duration of this item
325 * @param src the identity of the object that initiated the change
326 * @return true if the duration change was succesful, false otherwise
329 TimeAxisViewItem::set_duration (nframes_t dur, void* src)
331 if ((dur > max_item_duration) || (dur < min_item_duration)) {
332 warning << string_compose (_("new duration %1 frames is out of bounds for %2"), get_item_name(), dur)
343 reset_width_dependent_items (trackview.editor.frame_to_pixel (dur));
345 DurationChanged (dur, src) ; /* EMIT_SIGNAL */
350 * Returns the duration of this item
354 TimeAxisViewItem::get_duration() const
356 return (item_duration);
360 * Sets the maximum duration that this item make have.
362 * @param dur the new maximum duration
363 * @param src the identity of the object that initiated the change
366 TimeAxisViewItem::set_max_duration(nframes_t dur, void* src)
368 max_item_duration = dur ;
369 MaxDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
373 * Returns the maxmimum duration that this item may be set to
375 * @return the maximum duration that this item may be set to
378 TimeAxisViewItem::get_max_duration() const
380 return (max_item_duration) ;
384 * Sets the minimu duration that this item may be set to
386 * @param the minimum duration that this item may be set to
387 * @param src the identity of the object that initiated the change
390 TimeAxisViewItem::set_min_duration(nframes_t dur, void* src)
392 min_item_duration = dur ;
393 MinDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
397 * Returns the minimum duration that this item mey be set to
399 * @return the nimum duration that this item mey be set to
402 TimeAxisViewItem::get_min_duration() const
404 return(min_item_duration) ;
408 * Sets whether the position of this Item is locked to its current position
409 * Locked items cannot be moved until the item is unlocked again.
411 * @param yn set to true to lock this item to its current position
412 * @param src the identity of the object that initiated the change
415 TimeAxisViewItem::set_position_locked(bool yn, void* src)
417 position_locked = yn ;
418 set_trim_handle_colors() ;
419 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
423 * Returns whether this item is locked to its current position
425 * @return true if this item is locked to its current posotion
429 TimeAxisViewItem::get_position_locked() const
431 return (position_locked);
435 * Sets whether the Maximum Duration constraint is active and should be enforced
437 * @param active set true to enforce the max duration constraint
438 * @param src the identity of the object that initiated the change
441 TimeAxisViewItem::set_max_duration_active(bool active, void* src)
443 max_duration_active = active ;
447 * Returns whether the Maximum Duration constraint is active and should be enforced
449 * @return true if the maximum duration constraint is active, false otherwise
452 TimeAxisViewItem::get_max_duration_active() const
454 return(max_duration_active) ;
458 * Sets whether the Minimum Duration constraint is active and should be enforced
460 * @param active set true to enforce the min duration constraint
461 * @param src the identity of the object that initiated the change
464 TimeAxisViewItem::set_min_duration_active(bool active, void* src)
466 min_duration_active = active ;
470 * Returns whether the Maximum Duration constraint is active and should be enforced
472 * @return true if the maximum duration constraint is active, false otherwise
475 TimeAxisViewItem::get_min_duration_active() const
477 return(min_duration_active) ;
480 //---------------------------------------------------------------------------------------//
481 // Name/Id Accessors/Mutators
484 * Set the name/Id of this item.
486 * @param new_name the new name of this item
487 * @param src the identity of the object that initiated the change
490 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
492 if (new_name != item_name) {
493 std::string temp_name = item_name ;
494 item_name = new_name ;
495 name_text_width = ::pixel_width (new_name, *NAME_FONT);
496 NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */
501 * Returns the name/id of this item
503 * @return the name/id of this item
506 TimeAxisViewItem::get_item_name() const
511 //---------------------------------------------------------------------------------------//
515 * Set to true to indicate that this item is currently selected
517 * @param yn true if this item is currently selected
518 * @param src the identity of the object that initiated the change
521 TimeAxisViewItem::set_selected(bool yn)
523 if (_selected != yn) {
524 Selectable::set_selected (yn);
530 TimeAxisViewItem::set_should_show_selection (bool yn)
532 if (should_show_selection != yn) {
533 should_show_selection = yn;
538 //---------------------------------------------------------------------------------------//
539 // Parent Componenet Methods
542 * Returns the TimeAxisView that this item is upon
544 * @return the timeAxisView that this item is placed upon
547 TimeAxisViewItem::get_time_axis_view()
551 //---------------------------------------------------------------------------------------//
555 * Sets the displayed item text
556 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item
558 * @param new_name the new name text to display
561 TimeAxisViewItem::set_name_text(const ustring& new_name)
564 name_text->property_text() = new_name;
565 name_text_width = pixel_width (new_name, *NAME_FONT);
566 name_text_size_cache.clear ();
571 * Set the height of this item
573 * @param h the new height
576 TimeAxisViewItem::set_height (double height)
578 if (name_highlight) {
579 if (height < NAME_HIGHLIGHT_THRESH) {
580 name_highlight->hide();
585 name_highlight->show();
591 if (height > NAME_HIGHLIGHT_SIZE) {
592 name_highlight->property_y1() = (double) height+1 - NAME_HIGHLIGHT_SIZE;
593 name_highlight->property_y2() = (double) height;
596 /* it gets hidden now anyway */
597 name_highlight->property_y1() = (double) 1.0;
598 name_highlight->property_y2() = (double) height;
603 name_text->property_y() = height+1 - NAME_Y_OFFSET;
604 if (height < NAME_HIGHLIGHT_THRESH) {
605 name_text->property_fill_color_rgba() = fill_color;
608 name_text->property_fill_color_rgba() = label_color;
613 frame->property_y2() = height+1;
616 vestigial_frame->property_y2() = height+1;
623 TimeAxisViewItem::set_color(Gdk::Color& base_color)
625 compute_colors (base_color);
633 TimeAxisViewItem::get_canvas_frame()
642 TimeAxisViewItem::get_canvas_group()
651 TimeAxisViewItem::get_name_highlight()
653 return (name_highlight) ;
660 TimeAxisViewItem::get_name_text()
666 * Calculates some contrasting color for displaying various parts of this item, based upon the base color
668 * @param color the base color of the item
671 TimeAxisViewItem::compute_colors(Gdk::Color& base_color)
673 unsigned char radius ;
676 unsigned char r,g,b ;
678 /* FILL: this is simple */
679 r = base_color.get_red()/256 ;
680 g = base_color.get_green()/256 ;
681 b = base_color.get_blue()/256 ;
682 fill_color = RGBA_TO_UINT(r,g,b,255) ;
685 if the overall saturation is strong, make the minor colors light.
686 if its weak, make them dark.
688 we do this by moving an equal distance to the other side of the
689 central circle in the color wheel from where we started.
692 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f)) ;
693 minor_shift = 125 - radius ;
695 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
697 r = base_color.get_red()/256;
698 g = base_color.get_green()/256;
699 b = base_color.get_blue()/256;
705 /* red sector => green */
710 /* green sector => blue */
718 /* blue sector => red */
723 /* green sector => blue */
732 label_color = RGBA_TO_UINT(r,g,b,255);
733 r = (base_color.get_red()/256) + 127 ;
734 g = (base_color.get_green()/256) + 127 ;
735 b = (base_color.get_blue()/256) + 127 ;
737 label_color = RGBA_TO_UINT(r,g,b,255);
739 /* XXX can we do better than this ? */
740 /* We're trying ;) */
743 //frame_color_r = 192;
744 //frame_color_g = 192;
745 //frame_color_b = 194;
747 //selected_frame_color_r = 182;
748 //selected_frame_color_g = 145;
749 //selected_frame_color_b = 168;
751 //handle_color_r = 25 ;
752 //handle_color_g = 0 ;
753 //handle_color_b = 255 ;
754 //lock_handle_color_r = 235 ;
755 //lock_handle_color_g = 16;
756 //lock_handle_color_b = 16;
760 * Convenience method to set the various canvas item colors
763 TimeAxisViewItem::set_colors()
767 double height = NAME_HIGHLIGHT_THRESH;
770 height = frame->property_y2();
773 if (height < NAME_HIGHLIGHT_THRESH) {
774 name_text->property_fill_color_rgba() = fill_color;
777 name_text->property_fill_color_rgba() = label_color;
781 if (name_highlight) {
782 name_highlight->property_fill_color_rgba() = fill_color;
783 name_highlight->property_outline_color_rgba() = fill_color;
785 set_trim_handle_colors() ;
789 * Sets the frame color depending on whether this item is selected
792 TimeAxisViewItem::set_frame_color()
797 if (_selected && should_show_selection) {
798 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
799 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);// Lets still use the theme's opacity value if Opaque is not set
802 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
803 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
805 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
806 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
813 * Sets the colors of the start and end trim handle depending on object state
817 TimeAxisViewItem::set_trim_handle_colors()
819 if (frame_handle_start) {
820 if (position_locked) {
821 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
822 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
824 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
825 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
831 TimeAxisViewItem::get_samples_per_unit()
833 return(samples_per_unit) ;
837 TimeAxisViewItem::set_samples_per_unit (double spu)
839 samples_per_unit = spu ;
840 set_position (this->get_position(), this);
841 reset_width_dependent_items ((double)get_duration() / samples_per_unit);
845 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
847 if (pixel_width < GRAB_HANDLE_LENGTH * 2) {
849 if (frame_handle_start) {
850 frame_handle_start->hide();
851 frame_handle_end->hide();
854 } if (pixel_width < 2.0) {
856 if (show_vestigial) {
857 vestigial_frame->show();
860 if (name_highlight) {
861 name_highlight->hide();
871 if (frame_handle_start) {
872 frame_handle_start->hide();
873 frame_handle_end->hide();
877 vestigial_frame->hide();
879 if (name_highlight) {
881 double height = name_highlight->property_y2 ();
883 if (height < NAME_HIGHLIGHT_THRESH) {
884 name_highlight->hide();
889 name_highlight->show();
890 if (name_text && !get_item_name().empty()) {
892 reset_name_width (pixel_width);
896 if (visibility & FullWidthNameHighlight) {
897 name_highlight->property_x2() = pixel_width;
899 name_highlight->property_x2() = pixel_width - 1.0;
906 frame->property_x2() = pixel_width;
909 if (frame_handle_start) {
910 if (pixel_width < (2*TimeAxisViewItem::GRAB_HANDLE_LENGTH)) {
911 frame_handle_start->hide();
912 frame_handle_end->hide();
914 frame_handle_start->show();
915 frame_handle_end->property_x1() = pixel_width - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
916 frame_handle_end->show();
917 frame_handle_end->property_x2() = pixel_width;
923 TimeAxisViewItem::reset_name_width (double pixel_width)
925 if (name_text == 0) {
929 int limit = (int) floor (pixel_width - NAME_X_OFFSET);
930 bool shrinking = (last_name_text_width > pixel_width);
933 ustring::size_type n;
935 if ((last_name_text_width && // we did this once
936 shrinking && // we're getting smaller
937 (name_text_width <= limit) && // fits the new size
938 (name_text_width <= last_name_text_width - NAME_X_OFFSET))) { // fit into the old size too
939 last_name_text_width = pixel_width;
943 /* now check the cache of existing truncations */
946 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout ("");
948 for (n = item_name.length(); n > 0; --n) {
950 map<ustring::size_type,int>::iterator i;
952 if ((i = name_text_size_cache.find (n)) != name_text_size_cache.end()) {
954 /* we know the length of this substring already */
956 if ((actual_width = (*i).second) < limit) {
958 /* it fits, use it */
960 ustr = item_name.substr (0, n);
966 /* we don't know the length of this substring already, so compute
967 it and put it into the cache.
970 layout->set_text (item_name.substr (0, n));
973 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
975 name_text_size_cache[n] = width;
977 if ((actual_width = width) < limit) {
978 ustr = item_name.substr (0, n);
985 name_text->property_text() = "";
986 last_name_text_width = pixel_width;
990 /* don't use name for event handling if it leaves no room
991 for trimming to work.
994 if (pixel_width - actual_width < (NAME_X_OFFSET * 2.0)) {
995 if (name_connected) {
996 name_connected = false;
999 if (!name_connected) {
1000 name_connected = true;
1004 name_text->property_text() = ustr;
1005 name_text_width = actual_width;
1007 last_name_text_width = pixel_width;
1012 //---------------------------------------------------------------------------------------//
1013 // Handle time axis removal
1016 * Handles the Removal of this time axis item
1017 * This _needs_ to be called to alert others of the removal properly, ie where the source
1018 * of the removal came from.
1020 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
1021 * just now to capture the source of the removal
1023 * @param src the identity of the object that initiated the change
1026 TimeAxisViewItem::remove_this_item(void* src)
1029 defer to idle loop, otherwise we'll delete this object
1030 while we're still inside this function ...
1032 Glib::signal_idle().connect(bind (sigc::ptr_fun (&TimeAxisViewItem::idle_remove_this_item), this, src));
1036 * Callback used to remove this time axis item during the gtk idle loop
1037 * This is used to avoid deleting the obejct while inside the remove_this_item
1040 * @param item the TimeAxisViewItem to remove
1041 * @param src the identity of the object that initiated the change
1044 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1046 item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */