colinf's patch to make the cursor be the dbl vertical arrow when over the track resiz...
[ardour2.git] / gtk2_ardour / time_axis_view_item.cc
blobec0af7fb3b27f8a4f1fad3581e16b5dd90bb296e
1 /*
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"
32 #include "utils.h"
33 #include "canvas_impl.h"
34 #include "rgb_macros.h"
35 #include "ardour_ui.h"
37 #include "i18n.h"
39 using namespace std;
40 using namespace Editing;
41 using namespace Glib;
42 using namespace PBD;
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 int TimeAxisViewItem::NAME_HEIGHT;
53 double TimeAxisViewItem::NAME_Y_OFFSET;
54 double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
55 double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
57 //---------------------------------------------------------------------------------------//
58 // Constructor / Desctructor
60 /**
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
67 * @param base_color
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,
73 Visibility vis)
74 : trackview (tv), _height(1.0), _recregion(recording)
76 if (!have_name_font) {
78 /* first constructed item sets up font info */
80 NAME_FONT = get_font_for_style (N_("TimeAxisViewItemName"));
82 Gtk::Window win;
83 Gtk::Label foo;
84 win.add (foo);
86 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
87 int width;
88 int height;
90 layout->set_font_description (*NAME_FONT);
91 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
93 NAME_HEIGHT = height;
94 NAME_Y_OFFSET = (height / 2) + 8;
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)
109 , _height (other._height)
112 Gdk::Color c;
113 int r,g,b,a;
115 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
116 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
118 /* share the other's parent, but still create a new group */
120 Gnome::Canvas::Group* parent = other.group->property_parent();
122 group = new ArdourCanvas::Group (*parent);
124 init (other.item_name, other.samples_per_unit, c, other.frame_position, other.item_duration, other.visibility);
127 void
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 samples_per_unit = spu ;
132 should_show_selection = true;
133 frame_position = start ;
134 item_duration = duration ;
135 name_connected = false;
136 fill_opacity = 0;
137 position_locked = false ;
138 max_item_duration = ARDOUR::max_frames;
139 min_item_duration = 0 ;
140 show_vestigial = true;
141 visibility = vis;
142 _sensitive = true;
143 name_pixbuf_width = 0;
144 last_item_width = 0;
146 if (duration == 0) {
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_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
156 vestigial_frame->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VestigialFrame.get();
157 vestigial_frame->hide ();
159 if (visibility & ShowFrame) {
160 frame = new ArdourCanvas::SimpleRect (*group);
161 frame->property_x1() = (double) 0.0;
162 frame->property_y1() = (double) 1.0;
163 frame->property_x2() = (double) trackview.editor.frame_to_pixel(duration);
164 frame->property_y2() = (double) trackview.current_height();
165 frame->property_outline_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;
185 } else {
186 frame = 0;
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));
194 } else {
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);
201 name_highlight->set_data ("timeaxisviewitem", this);
203 } else {
204 name_highlight = 0;
207 /* create our grab handles used for trimming/duration etc */
209 if (visibility & ShowHandles) {
210 frame_handle_start = new ArdourCanvas::SimpleRect (*group);
211 frame_handle_start->property_x1() = (double) 0.0;
212 frame_handle_start->property_x2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH;
213 frame_handle_start->property_y1() = (double) 1.0;
214 frame_handle_start->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH+1;
215 frame_handle_start->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
217 frame_handle_end = new ArdourCanvas::SimpleRect (*group);
218 frame_handle_end->property_x1() = (double) (trackview.editor.frame_to_pixel(get_duration())) - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
219 frame_handle_end->property_x2() = (double) trackview.editor.frame_to_pixel(get_duration());
220 frame_handle_end->property_y1() = (double) 1;
221 frame_handle_end->property_y2() = (double) TimeAxisViewItem::GRAB_HANDLE_LENGTH + 1;
222 frame_handle_end->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_FrameHandle.get();
224 } else {
225 frame_handle_start = 0;
226 frame_handle_end = 0;
229 if (visibility & ShowNameText) {
230 name_pixbuf = new ArdourCanvas::Pixbuf(*group);
231 name_pixbuf->property_x() = NAME_X_OFFSET;
232 name_pixbuf->property_y() = trackview.current_height() - 1.0 - NAME_Y_OFFSET;
234 } else {
235 name_pixbuf = 0;
238 set_color (base_color) ;
240 set_duration (item_duration, this) ;
241 set_position (start, this) ;
245 * Destructor
247 TimeAxisViewItem::~TimeAxisViewItem()
249 delete group;
253 //---------------------------------------------------------------------------------------//
254 // Position and duration Accessors/Mutators
257 * Set the position of this item upon the timeline to the specified value
259 * @param pos the new position
260 * @param src the identity of the object that initiated the change
261 * @return true if the position change was a success, false otherwise
263 bool
264 TimeAxisViewItem::set_position(nframes_t pos, void* src, double* delta)
266 if (position_locked) {
267 return false;
270 frame_position = pos;
272 /* This sucks. The GnomeCanvas version I am using
273 doesn't correctly implement gnome_canvas_group_set_arg(),
274 so that simply setting the "x" arg of the group
275 fails to move the group. Instead, we have to
276 use gnome_canvas_item_move(), which does the right
277 thing. I see that in GNOME CVS, the current (Sept 2001)
278 version of GNOME Canvas rectifies this issue cleanly.
281 double old_unit_pos ;
282 double new_unit_pos = pos / samples_per_unit ;
284 old_unit_pos = group->property_x();
286 if (new_unit_pos != old_unit_pos) {
287 group->move (new_unit_pos - old_unit_pos, 0.0);
290 if (delta) {
291 (*delta) = new_unit_pos - old_unit_pos;
294 PositionChanged (frame_position, src) ; /* EMIT_SIGNAL */
296 return true;
300 * Return the position of this item upon the timeline
302 * @return the position of this item
304 nframes_t
305 TimeAxisViewItem::get_position() const
307 return frame_position;
311 * Sets the duration of this item
313 * @param dur the new duration of this item
314 * @param src the identity of the object that initiated the change
315 * @return true if the duration change was succesful, false otherwise
317 bool
318 TimeAxisViewItem::set_duration (nframes_t dur, void* src)
320 if ((dur > max_item_duration) || (dur < min_item_duration)) {
321 warning << string_compose (_("new duration %1 frames is out of bounds for %2"), get_item_name(), dur)
322 << endmsg;
323 return false;
326 if (dur == 0) {
327 group->hide();
330 item_duration = dur;
332 reset_width_dependent_items (trackview.editor.frame_to_pixel (dur));
334 DurationChanged (dur, src) ; /* EMIT_SIGNAL */
335 return true;
339 * Returns the duration of this item
342 nframes_t
343 TimeAxisViewItem::get_duration() const
345 return (item_duration);
349 * Sets the maximum duration that this item make have.
351 * @param dur the new maximum duration
352 * @param src the identity of the object that initiated the change
354 void
355 TimeAxisViewItem::set_max_duration(nframes_t dur, void* src)
357 max_item_duration = dur ;
358 MaxDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
362 * Returns the maxmimum duration that this item may be set to
364 * @return the maximum duration that this item may be set to
366 nframes_t
367 TimeAxisViewItem::get_max_duration() const
369 return (max_item_duration) ;
373 * Sets the minimu duration that this item may be set to
375 * @param the minimum duration that this item may be set to
376 * @param src the identity of the object that initiated the change
378 void
379 TimeAxisViewItem::set_min_duration(nframes_t dur, void* src)
381 min_item_duration = dur ;
382 MinDurationChanged(max_item_duration, src) ; /* EMIT_SIGNAL */
386 * Returns the minimum duration that this item mey be set to
388 * @return the nimum duration that this item mey be set to
390 nframes_t
391 TimeAxisViewItem::get_min_duration() const
393 return(min_item_duration) ;
397 * Sets whether the position of this Item is locked to its current position
398 * Locked items cannot be moved until the item is unlocked again.
400 * @param yn set to true to lock this item to its current position
401 * @param src the identity of the object that initiated the change
403 void
404 TimeAxisViewItem::set_position_locked(bool yn, void* src)
406 position_locked = yn ;
407 set_trim_handle_colors() ;
408 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
412 * Returns whether this item is locked to its current position
414 * @return true if this item is locked to its current posotion
415 * false otherwise
417 bool
418 TimeAxisViewItem::get_position_locked() const
420 return (position_locked);
424 * Sets whether the Maximum Duration constraint is active and should be enforced
426 * @param active set true to enforce the max duration constraint
427 * @param src the identity of the object that initiated the change
429 void
430 TimeAxisViewItem::set_max_duration_active(bool active, void* src)
432 max_duration_active = active ;
436 * Returns whether the Maximum Duration constraint is active and should be enforced
438 * @return true if the maximum duration constraint is active, false otherwise
440 bool
441 TimeAxisViewItem::get_max_duration_active() const
443 return(max_duration_active) ;
447 * Sets whether the Minimum Duration constraint is active and should be enforced
449 * @param active set true to enforce the min duration constraint
450 * @param src the identity of the object that initiated the change
452 void
453 TimeAxisViewItem::set_min_duration_active(bool active, void* src)
455 min_duration_active = active ;
459 * Returns whether the Maximum Duration constraint is active and should be enforced
461 * @return true if the maximum duration constraint is active, false otherwise
463 bool
464 TimeAxisViewItem::get_min_duration_active() const
466 return(min_duration_active) ;
469 //---------------------------------------------------------------------------------------//
470 // Name/Id Accessors/Mutators
473 * Set the name/Id of this item.
475 * @param new_name the new name of this item
476 * @param src the identity of the object that initiated the change
478 void
479 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
481 if (new_name != item_name) {
482 std::string temp_name = item_name ;
483 item_name = new_name ;
484 NameChanged (item_name, temp_name, src) ; /* EMIT_SIGNAL */
489 * Returns the name/id of this item
491 * @return the name/id of this item
493 std::string
494 TimeAxisViewItem::get_item_name() const
496 return(item_name) ;
499 //---------------------------------------------------------------------------------------//
500 // Selection Methods
503 * Set to true to indicate that this item is currently selected
505 * @param yn true if this item is currently selected
506 * @param src the identity of the object that initiated the change
508 void
509 TimeAxisViewItem::set_selected(bool yn)
511 if (_selected != yn) {
512 Selectable::set_selected (yn);
513 set_frame_color ();
517 void
518 TimeAxisViewItem::set_should_show_selection (bool yn)
520 if (should_show_selection != yn) {
521 should_show_selection = yn;
522 set_frame_color ();
526 //---------------------------------------------------------------------------------------//
527 // Parent Componenet Methods
530 * Returns the TimeAxisView that this item is upon
532 * @return the timeAxisView that this item is placed upon
534 TimeAxisView&
535 TimeAxisViewItem::get_time_axis_view()
537 return trackview;
539 //---------------------------------------------------------------------------------------//
540 // ui methods & data
543 * Sets the displayed item text
544 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item
546 * @param new_name the new name text to display
548 void
549 TimeAxisViewItem::set_name_text(const ustring& new_name)
551 if (!name_pixbuf) {
552 return;
555 last_item_width = trackview.editor.frame_to_pixel(item_duration);
556 name_pixbuf_width = pixel_width (new_name, *NAME_FONT) + 2;
557 name_pixbuf->property_pixbuf() = pixbuf_from_ustring(new_name, NAME_FONT, name_pixbuf_width, NAME_HEIGHT);
561 * Set the height of this item
563 * @param h the new height
565 void
566 TimeAxisViewItem::set_height (double height)
568 _height = height;
570 if (name_highlight) {
571 if (height < NAME_HIGHLIGHT_THRESH) {
572 name_highlight->hide();
573 } else {
574 name_highlight->show();
577 if (height > NAME_HIGHLIGHT_SIZE) {
578 name_highlight->property_y1() = (double) height+1 - NAME_HIGHLIGHT_SIZE;
579 name_highlight->property_y2() = (double) height;
580 } else {
581 /* it gets hidden now anyway */
582 //name_highlight->property_y1() = (double) 1.0;
583 //name_highlight->property_y2() = (double) height;
587 if (name_pixbuf) {
588 if (height < NAME_HIGHLIGHT_THRESH) {
589 name_pixbuf->hide();
590 } else {
591 name_pixbuf->property_y() = height+1 - NAME_Y_OFFSET;
592 name_pixbuf->show();
596 if (frame) {
597 frame->property_y2() = height+1;
600 vestigial_frame->property_y2() = height+1;
606 void
607 TimeAxisViewItem::set_color(Gdk::Color& base_color)
609 compute_colors (base_color);
610 set_colors ();
616 ArdourCanvas::Item*
617 TimeAxisViewItem::get_canvas_frame()
619 return(frame) ;
625 ArdourCanvas::Group*
626 TimeAxisViewItem::get_canvas_group()
628 return (group) ;
634 ArdourCanvas::Item*
635 TimeAxisViewItem::get_name_highlight()
637 return (name_highlight) ;
643 ArdourCanvas::Pixbuf*
644 TimeAxisViewItem::get_name_pixbuf()
646 return (name_pixbuf) ;
650 * Calculates some contrasting color for displaying various parts of this item, based upon the base color
652 * @param color the base color of the item
654 void
655 TimeAxisViewItem::compute_colors(Gdk::Color& base_color)
657 unsigned char radius ;
658 char minor_shift ;
660 unsigned char r,g,b ;
662 /* FILL: this is simple */
663 r = base_color.get_red()/256 ;
664 g = base_color.get_green()/256 ;
665 b = base_color.get_blue()/256 ;
666 fill_color = RGBA_TO_UINT(r,g,b,255) ;
668 /* for minor colors:
669 if the overall saturation is strong, make the minor colors light.
670 if its weak, make them dark.
672 we do this by moving an equal distance to the other side of the
673 central circle in the color wheel from where we started.
676 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f)) ;
677 minor_shift = 125 - radius ;
679 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
681 r = base_color.get_red()/256;
682 g = base_color.get_green()/256;
683 b = base_color.get_blue()/256;
685 if (r > b)
687 if (r > g)
689 /* red sector => green */
690 swap (r,g);
692 else
694 /* green sector => blue */
695 swap (g,b);
698 else
700 if (b > g)
702 /* blue sector => red */
703 swap (b,r);
705 else
707 /* green sector => blue */
708 swap (g,b);
712 r += minor_shift;
713 b += minor_shift;
714 g += minor_shift;
716 label_color = RGBA_TO_UINT(r,g,b,255);
717 r = (base_color.get_red()/256) + 127 ;
718 g = (base_color.get_green()/256) + 127 ;
719 b = (base_color.get_blue()/256) + 127 ;
721 label_color = RGBA_TO_UINT(r,g,b,255);
723 /* XXX can we do better than this ? */
724 /* We're trying ;) */
725 /* NUKECOLORS */
727 //frame_color_r = 192;
728 //frame_color_g = 192;
729 //frame_color_b = 194;
731 //selected_frame_color_r = 182;
732 //selected_frame_color_g = 145;
733 //selected_frame_color_b = 168;
735 //handle_color_r = 25 ;
736 //handle_color_g = 0 ;
737 //handle_color_b = 255 ;
738 //lock_handle_color_r = 235 ;
739 //lock_handle_color_g = 16;
740 //lock_handle_color_b = 16;
744 * Convenience method to set the various canvas item colors
746 void
747 TimeAxisViewItem::set_colors()
749 set_frame_color() ;
751 if (name_highlight) {
752 name_highlight->property_fill_color_rgba() = fill_color;
753 name_highlight->property_outline_color_rgba() = fill_color;
755 set_trim_handle_colors() ;
759 * Sets the frame color depending on whether this item is selected
761 void
762 TimeAxisViewItem::set_frame_color()
764 if (frame) {
765 uint32_t r,g,b,a;
767 if (_selected && should_show_selection) {
768 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get(), &r, &g, &b, &a);
769 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
770 } else {
771 if (_recregion) {
772 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_RecordingRect.get(), &r, &g, &b, &a);
773 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, a);
774 } else {
775 UINT_TO_RGBA(ARDOUR_UI::config()->canvasvar_FrameBase.get(), &r, &g, &b, &a);
776 frame->property_fill_color_rgba() = RGBA_TO_UINT(r, g, b, fill_opacity ? fill_opacity : a);
783 * Sets the colors of the start and end trim handle depending on object state
786 void
787 TimeAxisViewItem::set_trim_handle_colors()
789 if (frame_handle_start) {
790 if (position_locked) {
791 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
792 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandleLocked.get();
793 } else {
794 frame_handle_start->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
795 frame_handle_end->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_TrimHandle.get();
800 double
801 TimeAxisViewItem::get_samples_per_unit()
803 return(samples_per_unit) ;
806 void
807 TimeAxisViewItem::set_samples_per_unit (double spu)
809 samples_per_unit = spu ;
810 set_position (this->get_position(), this);
811 reset_width_dependent_items ((double)get_duration() / samples_per_unit);
814 void
815 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
817 if (pixel_width < 2.0) {
819 if (show_vestigial) {
820 vestigial_frame->show();
823 if (name_highlight) {
824 name_highlight->hide();
827 if (name_pixbuf) {
828 name_pixbuf->hide();
831 if (frame) {
832 frame->hide();
835 if (frame_handle_start) {
836 frame_handle_start->hide();
837 frame_handle_end->hide();
840 } else {
841 vestigial_frame->hide();
843 if (name_highlight) {
845 if (_height < NAME_HIGHLIGHT_THRESH) {
846 name_highlight->hide();
847 } else {
848 name_highlight->show();
851 if (visibility & FullWidthNameHighlight) {
852 name_highlight->property_x2() = pixel_width;
853 } else {
854 name_highlight->property_x2() = pixel_width - 1.0;
859 if (name_pixbuf) {
860 if (_height < NAME_HIGHLIGHT_THRESH) {
861 name_pixbuf->hide();
862 } else {
863 reset_name_width (pixel_width);
867 if (frame) {
868 frame->show();
869 frame->property_x2() = pixel_width;
872 if (frame_handle_start) {
873 if (pixel_width < (2*TimeAxisViewItem::GRAB_HANDLE_LENGTH)) {
874 frame_handle_start->hide();
875 frame_handle_end->hide();
876 } else {
877 frame_handle_start->show();
878 frame_handle_end->property_x1() = pixel_width - (TimeAxisViewItem::GRAB_HANDLE_LENGTH);
879 frame_handle_end->property_x2() = pixel_width;
880 frame_handle_end->show();
886 void
887 TimeAxisViewItem::reset_name_width (double pix_width)
889 uint32_t it_width;
890 int pb_width;
891 bool pixbuf_holds_full_name;
893 if (!name_pixbuf) {
894 return;
897 it_width = trackview.editor.frame_to_pixel(item_duration);
898 pb_width = name_pixbuf_width;
900 pixbuf_holds_full_name = last_item_width > pb_width + NAME_X_OFFSET;
901 last_item_width = it_width;
903 if (pixbuf_holds_full_name && (it_width >= pb_width + NAME_X_OFFSET)) {
905 we've previously had the full name length showing
906 and its still showing.
908 return;
911 if (pb_width > it_width - NAME_X_OFFSET) {
912 pb_width = it_width - NAME_X_OFFSET;
915 if (pb_width <= 0 || it_width <= NAME_X_OFFSET) {
916 name_pixbuf->hide();
917 return;
918 } else {
919 name_pixbuf->show();
922 name_pixbuf->property_pixbuf() = pixbuf_from_ustring(item_name, NAME_FONT, pb_width, NAME_HEIGHT);
926 //---------------------------------------------------------------------------------------//
927 // Handle time axis removal
930 * Handles the Removal of this time axis item
931 * This _needs_ to be called to alert others of the removal properly, ie where the source
932 * of the removal came from.
934 * XXX Although im not too happy about this method of doing things, I cant think of a cleaner method
935 * just now to capture the source of the removal
937 * @param src the identity of the object that initiated the change
939 void
940 TimeAxisViewItem::remove_this_item(void* src)
943 defer to idle loop, otherwise we'll delete this object
944 while we're still inside this function ...
946 Glib::signal_idle().connect(bind (sigc::ptr_fun (&TimeAxisViewItem::idle_remove_this_item), this, src));
950 * Callback used to remove this time axis item during the gtk idle loop
951 * This is used to avoid deleting the obejct while inside the remove_this_item
952 * method
954 * @param item the TimeAxisViewItem to remove
955 * @param src the identity of the object that initiated the change
957 gint
958 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
960 item->ItemRemoved (item->get_item_name(), src) ; /* EMIT_SIGNAL */
961 delete item;
962 item = 0;
963 return false;