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,
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() = 2.0;
154 vestigial_frame->property_y2() = (double) trackview.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.height;
166 frame->property_outline_what() = 0xF;
167 frame->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_TimeAxisFrame.get();
168 frame->property_fill_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.height - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE);
202 name_highlight->property_y2() = (double) (trackview.height - 1);
203 name_highlight->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightFill.get();
204 name_highlight->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_NameHighlightOutline.get();
206 name_highlight->set_data ("timeaxisviewitem", this);
212 if (visibility & ShowNameText) {
213 name_text = new ArdourCanvas::Text (*group);
214 name_text->property_x() = (double) TimeAxisViewItem::NAME_X_OFFSET;
215 /* trackview.height is the bottom of the trackview. subtract 1 to get back to the bottom of the highlight,
216 then NAME_Y_OFFSET to position the text in the vertical center of the highlight
218 name_text->property_y() = (double) trackview.height - 1.0 - TimeAxisViewItem::NAME_Y_OFFSET;
219 name_text->property_font_desc() = *NAME_FONT;
220 name_text->property_anchor() = Gtk::ANCHOR_NW;
222 name_text->set_data ("timeaxisviewitem", this);
228 /* create our grab handles used for trimming/duration etc */
230 if (visibility & ShowHandles) {
231 frame_handle_start = new ArdourCanvas::SimpleRect (*group);
232 frame_handle_start->property_x1() = (double) 0.0;
233 frame_handle_start->property_x2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH;
234 frame_handle_start->property_y1() = (double) 1.0;
235 frame_handle_start->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH+1;
236 frame_handle_start->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
237 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
239 frame_handle_end = new ArdourCanvas::SimpleRect (*group);
240 frame_handle_end->property_x1() = (double) (trackview.editor.frame_to_pixel(get_duration())) - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
241 frame_handle_end->property_x2() = (double) trackview.editor.frame_to_pixel(get_duration());
242 frame_handle_end->property_y1() = (double) 1;
243 frame_handle_end->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH + 1;
244 frame_handle_end->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
245 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
248 frame_handle_start = 0;
249 frame_handle_end = 0;
252 set_color (base_color) ;
254 set_duration (item_duration, this) ;
255 set_position (start, this) ;
261 TimeAxisViewItem::~TimeAxisViewItem()
267 //---------------------------------------------------------------------------------------//
268 // Position and duration Accessors/Mutators
271 * Set the position of this item upon the timeline to the specified value
273 * @param pos the new position
274 * @param src the identity of the object that initiated the change
275 * @return true if the position change was a success, false otherwise
278 TimeAxisViewItem::set_position(nframes_t pos, void* src, double* delta)
280 if (position_locked) {
284 frame_position = pos;
286 /* This sucks. The GnomeCanvas version I am using
287 doesn't correctly implement gnome_canvas_group_set_arg(),
288 so that simply setting the "x" arg of the group
289 fails to move the group. Instead, we have to
290 use gnome_canvas_item_move(), which does the right
291 thing. I see that in GNOME CVS, the current (Sept 2001)
292 version of GNOME Canvas rectifies this issue cleanly.
295 double old_unit_pos ;
296 double new_unit_pos = pos / samples_per_unit ;
298 old_unit_pos = group->property_x();
300 if (new_unit_pos != old_unit_pos) {
301 group->move (new_unit_pos - old_unit_pos, 0.0);
305 (*delta) = new_unit_pos - old_unit_pos;
308 PositionChanged (frame_position, src) ; /* EMIT_SIGNAL */
314 * Return the position of this item upon the timeline
316 * @return the position of this item
319 TimeAxisViewItem::get_position() const
321 return frame_position;
325 * Sets the duration of this item
327 * @param dur the new duration of this item
328 * @param src the identity of the object that initiated the change
329 * @return true if the duration change was succesful, false otherwise
332 TimeAxisViewItem::set_duration (nframes_t dur, void* src)
334 if ((dur > max_item_duration) || (dur < min_item_duration)) {
335 warning << string_compose (_("new duration %1 frames is out of bounds for %2"), get_item_name(), dur)
346 reset_width_dependent_items (trackview.editor.frame_to_pixel (dur));
348 DurationChanged (dur, src) ; /* EMIT_SIGNAL */
353 * Returns the duration of this item
357 TimeAxisViewItem::get_duration() const
359 return (item_duration);
363 * Sets the maximum duration that this item make have.
365 * @param dur the new maximum duration
366 * @param src the identity of the object that initiated the change
369 TimeAxisViewItem::set_max_duration(nframes_t dur, void* src)
371 max_item_duration = dur ;
372 MaxDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
376 * Returns the maxmimum duration that this item may be set to
378 * @return the maximum duration that this item may be set to
381 TimeAxisViewItem::get_max_duration() const
383 return (max_item_duration) ;
387 * Sets the minimu duration that this item may be set to
389 * @param the minimum duration that this item may be set to
390 * @param src the identity of the object that initiated the change
393 TimeAxisViewItem::set_min_duration(nframes_t dur, void* src)
395 min_item_duration = dur ;
396 MinDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
400 * Returns the minimum duration that this item mey be set to
402 * @return the nimum duration that this item mey be set to
405 TimeAxisViewItem::get_min_duration() const
407 return(min_item_duration) ;
411 * Sets whether the position of this Item is locked to its current position
412 * Locked items cannot be moved until the item is unlocked again.
414 * @param yn set to true to lock this item to its current position
415 * @param src the identity of the object that initiated the change
418 TimeAxisViewItem::set_position_locked(bool yn, void* src)
420 position_locked = yn ;
421 set_trim_handle_colors() ;
422 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
426 * Returns whether this item is locked to its current position
428 * @return true if this item is locked to its current posotion
432 TimeAxisViewItem::get_position_locked() const
434 return (position_locked);
438 * Sets whether the Maximum Duration constraint is active and should be enforced
440 * @param active set true to enforce the max duration constraint
441 * @param src the identity of the object that initiated the change
444 TimeAxisViewItem::set_max_duration_active(bool active, void* src)
446 max_duration_active = active ;
450 * Returns whether the Maximum Duration constraint is active and should be enforced
452 * @return true if the maximum duration constraint is active, false otherwise
455 TimeAxisViewItem::get_max_duration_active() const
457 return(max_duration_active) ;
461 * Sets whether the Minimum Duration constraint is active and should be enforced
463 * @param active set true to enforce the min duration constraint
464 * @param src the identity of the object that initiated the change
467 TimeAxisViewItem::set_min_duration_active(bool active, void* src)
469 min_duration_active = active ;
473 * Returns whether the Maximum Duration constraint is active and should be enforced
475 * @return true if the maximum duration constraint is active, false otherwise
478 TimeAxisViewItem::get_min_duration_active() const
480 return(min_duration_active) ;
483 //---------------------------------------------------------------------------------------//
484 // Name/Id Accessors/Mutators
487 * Set the name/Id of this item.
489 * @param new_name the new name of this item
490 * @param src the identity of the object that initiated the change
493 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
495 if (new_name != item_name) {
496 std::string temp_name = item_name ;
497 item_name = new_name ;
498 name_text_width = ::pixel_width (new_name, *NAME_FONT);
499 NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */
504 * Returns the name/id of this item
506 * @return the name/id of this item
509 TimeAxisViewItem::get_item_name() const
514 //---------------------------------------------------------------------------------------//
518 * Set to true to indicate that this item is currently selected
520 * @param yn true if this item is currently selected
521 * @param src the identity of the object that initiated the change
524 TimeAxisViewItem::set_selected(bool yn)
526 if (_selected != yn) {
527 Selectable::set_selected (yn);
533 TimeAxisViewItem::set_should_show_selection (bool yn)
535 if (should_show_selection != yn) {
536 should_show_selection = yn;
541 //---------------------------------------------------------------------------------------//
542 // Parent Componenet Methods
545 * Returns the TimeAxisView that this item is upon
547 * @return the timeAxisView that this item is placed upon
550 TimeAxisViewItem::get_time_axis_view()
554 //---------------------------------------------------------------------------------------//
558 * Sets the displayed item text
559 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item
561 * @param new_name the new name text to display
564 TimeAxisViewItem::set_name_text(const ustring& new_name)
567 name_text->property_text() = new_name;
568 name_text_width = pixel_width (new_name, *NAME_FONT);
569 name_text_size_cache.clear ();
574 * Set the y position and height of this item.
576 * @param y the new y position
577 * @param h the new height
580 TimeAxisViewItem::set_y_position_and_height (double y, double h)
582 if (name_highlight) {
583 if (h < NAME_HIGHLIGHT_THRESH) {
584 name_highlight->hide();
589 name_highlight->show();
595 if (h > NAME_HIGHLIGHT_SIZE) {
596 name_highlight->property_y1() = (double) y + h + 1 - NAME_HIGHLIGHT_SIZE;
597 name_highlight->property_y2() = (double) y + h;
600 /* it gets hidden now anyway */
601 name_highlight->property_y1() = (double) y;
602 name_highlight->property_y2() = (double) y + h;
607 name_text->property_y() = y + h + 1 - NAME_Y_OFFSET;
608 if (h < NAME_HIGHLIGHT_THRESH) {
609 name_text->property_fill_color_rgba() = fill_color;
612 name_text->property_fill_color_rgba() = label_color;
617 frame->property_y1() = y;
618 frame->property_y2() = y + h + 1;
621 vestigial_frame->property_y1() = y;
622 vestigial_frame->property_y2() = y + h + 1;
629 TimeAxisViewItem::set_color(Gdk::Color& base_color)
631 compute_colors (base_color);
639 TimeAxisViewItem::get_canvas_frame()
648 TimeAxisViewItem::get_canvas_group()
657 TimeAxisViewItem::get_name_highlight()
659 return (name_highlight) ;
666 TimeAxisViewItem::get_name_text()
672 * Calculates some contrasting color for displaying various parts of this item, based upon the base color
674 * @param color the base color of the item
677 TimeAxisViewItem::compute_colors(Gdk::Color& base_color)
679 unsigned char radius ;
682 unsigned char r,g,b ;
684 /* FILL: this is simple */
685 r = base_color.get_red()/256 ;
686 g = base_color.get_green()/256 ;
687 b = base_color.get_blue()/256 ;
688 fill_color = RGBA_TO_UINT(r,g,b,160) ;
691 if the overall saturation is strong, make the minor colors light.
692 if its weak, make them dark.
694 we do this by moving an equal distance to the other side of the
695 central circle in the color wheel from where we started.
698 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f)) ;
699 minor_shift = 125 - radius ;
701 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
703 r = base_color.get_red()/256;
704 g = base_color.get_green()/256;
705 b = base_color.get_blue()/256;
711 /* red sector => green */
716 /* green sector => blue */
724 /* blue sector => red */
729 /* green sector => blue */
738 label_color = RGBA_TO_UINT(r,g,b,255);
739 r = (base_color.get_red()/256) + 127 ;
740 g = (base_color.get_green()/256) + 127 ;
741 b = (base_color.get_blue()/256) + 127 ;
743 label_color = RGBA_TO_UINT(r,g,b,255);
745 /* XXX can we do better than this ? */
746 /* We're trying ;) */
749 //frame_color_r = 192;
750 //frame_color_g = 192;
751 //frame_color_b = 194;
753 //selected_frame_color_r = 182;
754 //selected_frame_color_g = 145;
755 //selected_frame_color_b = 168;
757 //handle_color_r = 25 ;
758 //handle_color_g = 0 ;
759 //handle_color_b = 255 ;
760 //lock_handle_color_r = 235 ;
761 //lock_handle_color_g = 16;
762 //lock_handle_color_b = 16;
766 * Convenience method to set the various canvas item colors
769 TimeAxisViewItem::set_colors()
773 double height = NAME_HIGHLIGHT_THRESH;
776 height = frame->property_y2();
779 if (height < NAME_HIGHLIGHT_THRESH) {
780 name_text->property_fill_color_rgba() = fill_color;
783 name_text->property_fill_color_rgba() = label_color;
787 if (name_highlight) {
788 name_highlight->property_fill_color_rgba() = fill_color;
789 name_highlight->property_outline_color_rgba() = fill_color;
791 set_trim_handle_colors() ;
795 * Sets the frame color depending on whether this item is selected
798 TimeAxisViewItem::set_frame_color()
803 if (_selected && should_show_selection) {
804 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
805 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
807 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
808 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
814 * Sets the colors of the start and end trim handle depending on object state
818 TimeAxisViewItem::set_trim_handle_colors()
820 if (frame_handle_start) {
821 if (position_locked) {
822 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
823 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
825 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
826 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
832 TimeAxisViewItem::get_samples_per_unit()
834 return(samples_per_unit) ;
838 TimeAxisViewItem::set_samples_per_unit (double spu)
840 samples_per_unit = spu ;
841 set_position (this->get_position(), this);
842 reset_width_dependent_items ((double)get_duration() / samples_per_unit);
846 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
848 if (pixel_width < GRAB_HANDLE_LENGTH * 2) {
850 if (frame_handle_start) {
851 frame_handle_start->hide();
852 frame_handle_end->hide();
855 } if (pixel_width < 2.0) {
857 if (show_vestigial) {
858 vestigial_frame->show();
861 if (name_highlight) {
862 name_highlight->hide();
872 if (frame_handle_start) {
873 frame_handle_start->hide();
874 frame_handle_end->hide();
878 vestigial_frame->hide();
880 if (name_highlight) {
882 double height = name_highlight->property_y2 ();
884 if (height < NAME_HIGHLIGHT_THRESH) {
885 name_highlight->hide();
890 name_highlight->show();
891 if (name_text && !get_item_name().empty()) {
893 reset_name_width (pixel_width);
897 if (visibility & FullWidthNameHighlight) {
898 name_highlight->property_x2() = pixel_width;
900 name_highlight->property_x2() = pixel_width - 1.0;
907 frame->property_x2() = pixel_width;
910 if (frame_handle_start) {
911 if (pixel_width < (2*TimeAxisViewItem::GRAB_HANDLE_LENGTH)) {
912 frame_handle_start->hide();
913 frame_handle_end->hide();
915 frame_handle_start->show();
916 frame_handle_end->property_x1() = pixel_width - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
917 frame_handle_end->show();
918 frame_handle_end->property_x2() = pixel_width;
924 TimeAxisViewItem::reset_name_width (double pixel_width)
926 if (name_text == 0) {
930 int limit = (int) floor (pixel_width - NAME_X_OFFSET);
931 bool shrinking = (last_name_text_width > pixel_width);
934 ustring::size_type n;
936 if ((last_name_text_width && // we did this once
937 shrinking && // we're getting smaller
938 (name_text_width <= limit) && // fits the new size
939 (name_text_width <= last_name_text_width - NAME_X_OFFSET))) { // fit into the old size too
940 last_name_text_width = pixel_width;
944 /* now check the cache of existing truncations */
947 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout ("");
949 for (n = item_name.length(); n > 0; --n) {
951 map<ustring::size_type,int>::iterator i;
953 if ((i = name_text_size_cache.find (n)) != name_text_size_cache.end()) {
955 /* we know the length of this substring already */
957 if ((actual_width = (*i).second) < limit) {
959 /* it fits, use it */
961 ustr = item_name.substr (0, n);
967 /* we don't know the length of this substring already, so compute
968 it and put it into the cache.
971 layout->set_text (item_name.substr (0, n));
974 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
976 name_text_size_cache[n] = width;
978 if ((actual_width = width) < limit) {
979 ustr = item_name.substr (0, n);
986 name_text->property_text() = "";
987 last_name_text_width = pixel_width;
991 /* don't use name for event handling if it leaves no room
992 for trimming to work.
995 if (pixel_width - actual_width < (NAME_X_OFFSET * 2.0)) {
996 if (name_connected) {
997 name_connected = false;
1000 if (!name_connected) {
1001 name_connected = true;
1005 name_text->property_text() = ustr;
1006 name_text_width = actual_width;
1008 last_name_text_width = pixel_width;
1013 //---------------------------------------------------------------------------------------//
1014 // Handle time axis removal
1017 * Handles the Removal of this time axis item
1018 * This _needs_ to be called to alert others of the removal properly, ie where the source
1019 * of the removal came from.
1021 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
1022 * just now to capture the source of the removal
1024 * @param src the identity of the object that initiated the change
1027 TimeAxisViewItem::remove_this_item(void* src)
1030 defer to idle loop, otherwise we'll delete this object
1031 while we're still inside this function ...
1033 Glib::signal_idle().connect(bind (sigc::ptr_fun (&TimeAxisViewItem::idle_remove_this_item), this, src));
1037 * Callback used to remove this time axis item during the gtk idle loop
1038 * This is used to avoid deleting the obejct while inside the remove_this_item
1041 * @param item the TimeAxisViewItem to remove
1042 * @param src the identity of the object that initiated the change
1045 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1047 item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */