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.
22 #include "pbd/error.h"
23 #include "pbd/stacktrace.h"
25 #include "ardour/types.h"
26 #include "ardour/ardour.h"
28 #include "gtkmm2ext/utils.h"
29 #include "gtkmm2ext/gui_thread.h"
31 #include "canvas/group.h"
32 #include "canvas/rectangle.h"
33 #include "canvas/debug.h"
34 #include "canvas/text.h"
35 #include "canvas/utils.h"
37 #include "ardour_ui.h"
39 * ardour_ui.h was moved up in the include list
40 * due to a conflicting definition of 'Rect' between
41 * Apple's MacTypes.h file and GTK
44 #include "public_editor.h"
45 #include "time_axis_view_item.h"
46 #include "time_axis_view.h"
48 #include "rgb_macros.h"
53 using namespace Editing;
56 using namespace ARDOUR;
57 using namespace Gtkmm2ext;
59 Pango::FontDescription TimeAxisViewItem::NAME_FONT;
60 const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
61 const double TimeAxisViewItem::GRAB_HANDLE_TOP = 6;
62 const double TimeAxisViewItem::GRAB_HANDLE_WIDTH = 5;
64 int TimeAxisViewItem::NAME_HEIGHT;
65 double TimeAxisViewItem::NAME_Y_OFFSET;
66 double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
67 double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
70 TimeAxisViewItem::set_constant_heights ()
72 NAME_FONT = get_font_for_style (X_("TimeAxisViewItemName"));
78 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
82 layout->set_font_description (NAME_FONT);
83 Gtkmm2ext::get_ink_pixel_size (layout, width, height);
86 NAME_Y_OFFSET = height + 5; // XXX this offset is magic
87 NAME_HIGHLIGHT_SIZE = height + 2;
88 NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 3;
92 * Construct a new TimeAxisViewItem.
94 * @param it_name the unique name of this item
95 * @param parent the parent canvas group
96 * @param tv the TimeAxisView we are going to be added to
97 * @param spu samples per unit
99 * @param start the start point of this item
100 * @param duration the duration of this item
101 * @param recording true if this is a recording region view
102 * @param automation true if this is an automation region view
104 TimeAxisViewItem::TimeAxisViewItem(
105 const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color,
106 framepos_t start, framecnt_t duration, bool recording, bool automation, Visibility vis
109 , item_name (it_name)
111 , _recregion (recording)
112 , _automation (automation)
116 init (&parent, spu, base_color, start, duration, vis, true, true);
119 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
122 , PBD::ScopedConnectionList()
123 , trackview (other.trackview)
124 , item_name (other.item_name)
125 , _recregion (other._recregion)
126 , _automation (other._automation)
127 , _dragging (other._dragging)
133 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
134 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
136 /* share the other's parent, but still create a new group */
138 ArdourCanvas::Group* parent = other.group->parent();
140 _selected = other._selected;
142 init (parent, other.samples_per_pixel, c, other.frame_position,
143 other.item_duration, other.visibility, other.wide_enough_for_name, other.high_enough_for_name);
147 TimeAxisViewItem::init (ArdourCanvas::Group* parent, double fpp, Gdk::Color const & base_color,
148 framepos_t start, framepos_t duration, Visibility vis,
149 bool wide, bool high)
151 group = new ArdourCanvas::Group (parent);
152 CANVAS_DEBUG_NAME (group, string_compose ("TAVI group for %1", get_item_name()));
153 group->Event.connect (sigc::mem_fun (*this, &TimeAxisViewItem::canvas_group_event));
155 samples_per_pixel = fpp;
156 frame_position = start;
157 item_duration = duration;
158 name_connected = false;
160 position_locked = false;
161 max_item_duration = ARDOUR::max_framepos;
162 min_item_duration = 0;
163 show_vestigial = true;
168 wide_enough_for_name = wide;
169 high_enough_for_name = high;
173 warning << "Time Axis Item Duration == 0" << endl;
176 vestigial_frame = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, 1.0, 2.0, trackview.current_height()));
177 CANVAS_DEBUG_NAME (vestigial_frame, string_compose ("vestigial frame for %1", get_item_name()));
178 vestigial_frame->hide ();
179 vestigial_frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
180 vestigial_frame->set_fill_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
182 if (visibility & ShowFrame) {
183 frame = new ArdourCanvas::Rectangle (group,
184 ArdourCanvas::Rect (0.0, 1.0,
185 trackview.editor().sample_to_pixel(duration),
186 trackview.current_height()));
187 CANVAS_DEBUG_NAME (frame, string_compose ("frame for %1", get_item_name()));
190 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RecordingRect());
192 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame());
200 if (visibility & ShowNameHighlight) {
202 if (visibility & FullWidthNameHighlight) {
203 name_highlight = new ArdourCanvas::Rectangle (group,
204 ArdourCanvas::Rect (0.0, trackview.editor().sample_to_pixel(item_duration),
205 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
206 trackview.current_height()));
207 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
209 name_highlight = new ArdourCanvas::Rectangle (group,
210 ArdourCanvas::Rect (1.0, trackview.editor().sample_to_pixel(item_duration) - 1,
211 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
212 trackview.current_height()));
213 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
216 name_highlight->set_data ("timeaxisviewitem", this);
217 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
218 /* we should really use a canvas color property here */
219 name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
225 if (visibility & ShowNameText) {
226 name_text = new ArdourCanvas::Text (group);
227 CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
228 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
229 name_text->set_font_description (NAME_FONT);
235 /* create our grab handles used for trimming/duration etc */
236 if (!_recregion && !_automation) {
237 double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
238 double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
240 frame_handle_start = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
241 CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
242 frame_handle_start->set_outline (false);
243 frame_handle_start->set_fill (false);
244 frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
246 frame_handle_end = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
247 CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
248 frame_handle_end->set_outline (false);
249 frame_handle_end->set_fill (false);
250 frame_handle_end->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_end));
252 frame_handle_start = frame_handle_end = 0;
255 set_color (base_color);
257 set_duration (item_duration, this);
258 set_position (start, this);
260 Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&TimeAxisViewItem::parameter_changed, this, _1), gui_context ());
261 ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &TimeAxisViewItem::parameter_changed));
264 TimeAxisViewItem::~TimeAxisViewItem()
270 TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
276 TimeAxisViewItem::hide_rect ()
278 rect_visible = false;
281 if (name_highlight) {
282 name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0));
283 name_highlight->set_fill_color (UINT_RGBA_CHANGE_A (fill_color, 64));
288 TimeAxisViewItem::show_rect ()
293 if (name_highlight) {
294 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
295 name_highlight->set_fill_color (fill_color);
300 * Set the position of this item on the timeline.
302 * @param pos the new position
303 * @param src the identity of the object that initiated the change
304 * @return true on success
308 TimeAxisViewItem::set_position(framepos_t pos, void* src, double* delta)
310 if (position_locked) {
314 frame_position = pos;
316 /* This sucks. The GnomeCanvas version I am using
317 doesn't correctly implement gnome_canvas_group_set_arg(),
318 so that simply setting the "x" arg of the group
319 fails to move the group. Instead, we have to
320 use gnome_canvas_item_move(), which does the right
321 thing. I see that in GNOME CVS, the current (Sept 2001)
322 version of GNOME Canvas rectifies this issue cleanly.
326 double new_unit_pos = pos / samples_per_pixel;
328 old_unit_pos = group->position().x;
330 if (new_unit_pos != old_unit_pos) {
331 group->set_x_position (new_unit_pos);
335 (*delta) = new_unit_pos - old_unit_pos;
338 PositionChanged (frame_position, src); /* EMIT_SIGNAL */
343 /** @return position of this item on the timeline */
345 TimeAxisViewItem::get_position() const
347 return frame_position;
351 * Set the duration of this item.
353 * @param dur the new duration of this item
354 * @param src the identity of the object that initiated the change
355 * @return true on success
359 TimeAxisViewItem::set_duration (framecnt_t dur, void* src)
361 if ((dur > max_item_duration) || (dur < min_item_duration)) {
362 warning << string_compose (
363 P_("new duration %1 frame is out of bounds for %2", "new duration of %1 frames is out of bounds for %2", dur),
364 get_item_name(), dur)
375 reset_width_dependent_items (trackview.editor().sample_to_pixel (dur));
377 DurationChanged (dur, src); /* EMIT_SIGNAL */
381 /** @return duration of this item */
383 TimeAxisViewItem::get_duration() const
385 return item_duration;
389 * Set the maximum duration that this item can have.
391 * @param dur the new maximum duration
392 * @param src the identity of the object that initiated the change
395 TimeAxisViewItem::set_max_duration(framecnt_t dur, void* src)
397 max_item_duration = dur;
398 MaxDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
401 /** @return the maximum duration that this item may have */
403 TimeAxisViewItem::get_max_duration() const
405 return max_item_duration;
409 * Set the minimum duration that this item may have.
411 * @param the minimum duration that this item may be set to
412 * @param src the identity of the object that initiated the change
415 TimeAxisViewItem::set_min_duration(framecnt_t dur, void* src)
417 min_item_duration = dur;
418 MinDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
421 /** @return the minimum duration that this item mey have */
423 TimeAxisViewItem::get_min_duration() const
425 return min_item_duration;
429 * Set whether this item is locked to its current position.
430 * Locked items cannot be moved until the item is unlocked again.
432 * @param yn true to lock this item to its current position
433 * @param src the identity of the object that initiated the change
436 TimeAxisViewItem::set_position_locked(bool yn, void* src)
438 position_locked = yn;
439 set_trim_handle_colors();
440 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
443 /** @return true if this item is locked to its current position */
445 TimeAxisViewItem::get_position_locked() const
447 return position_locked;
451 * Set whether the maximum duration constraint is active.
453 * @param active set true to enforce the max duration constraint
454 * @param src the identity of the object that initiated the change
457 TimeAxisViewItem::set_max_duration_active (bool active, void* /*src*/)
459 max_duration_active = active;
462 /** @return true if the maximum duration constraint is active */
464 TimeAxisViewItem::get_max_duration_active() const
466 return max_duration_active;
470 * Set whether the minimum duration constraint is active.
472 * @param active set true to enforce the min duration constraint
473 * @param src the identity of the object that initiated the change
477 TimeAxisViewItem::set_min_duration_active (bool active, void* /*src*/)
479 min_duration_active = active;
482 /** @return true if the maximum duration constraint is active */
484 TimeAxisViewItem::get_min_duration_active() const
486 return min_duration_active;
490 * Set the name of this item.
492 * @param new_name the new name of this item
493 * @param src the identity of the object that initiated the change
497 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
499 if (new_name != item_name) {
500 std::string temp_name = item_name;
501 item_name = new_name;
502 NameChanged (item_name, temp_name, src); /* EMIT_SIGNAL */
506 /** @return the name of this item */
508 TimeAxisViewItem::get_item_name() const
514 * Set selection status.
516 * @param yn true if this item is currently selected
519 TimeAxisViewItem::set_selected(bool yn)
521 if (_selected != yn) {
522 Selectable::set_selected (yn);
527 /** @return the TimeAxisView that this item is on */
529 TimeAxisViewItem::get_time_axis_view () const
535 * Set the displayed item text.
536 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item.
538 * @param new_name the new name text to display
542 TimeAxisViewItem::set_name_text(const string& new_name)
548 last_item_width = trackview.editor().sample_to_pixel(item_duration);
549 name_text_width = pixel_width (new_name, NAME_FONT) + 2;
550 name_text->set (new_name);
555 * Set the height of this item.
557 * @param h new height
560 TimeAxisViewItem::set_height (double height)
564 if (name_highlight) {
565 if (height < NAME_HIGHLIGHT_THRESH) {
566 name_highlight->hide ();
567 high_enough_for_name = false;
570 name_highlight->show();
571 high_enough_for_name = true;
574 if (height > NAME_HIGHLIGHT_SIZE) {
575 name_highlight->set_y0 ((double) height - 1 - NAME_HIGHLIGHT_SIZE);
576 name_highlight->set_y1 ((double) height - 1);
579 /* it gets hidden now anyway */
580 name_highlight->set_y0 (1);
581 name_highlight->set_y1 (height);
585 if (visibility & ShowNameText) {
586 name_text->set_y_position (height + 1 - NAME_Y_OFFSET);
590 frame->set_y1 (height - 1);
591 if (frame_handle_start) {
592 frame_handle_start->set_y1 (height - 1);
593 frame_handle_end->set_y1 (height - 1);
597 vestigial_frame->set_y1 (height - 1);
599 update_name_text_visibility ();
604 TimeAxisViewItem::set_color (Gdk::Color const & base_color)
606 compute_colors (base_color);
611 TimeAxisViewItem::get_canvas_frame()
617 TimeAxisViewItem::get_canvas_group()
623 TimeAxisViewItem::get_name_highlight()
625 return name_highlight;
629 * Calculate some contrasting color for displaying various parts of this item, based upon the base color.
631 * @param color the base color of the item
634 TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
636 unsigned char radius;
641 /* FILL: this is simple */
642 r = base_color.get_red()/256;
643 g = base_color.get_green()/256;
644 b = base_color.get_blue()/256;
645 fill_color = RGBA_TO_UINT(r,g,b,160);
648 if the overall saturation is strong, make the minor colors light.
649 if its weak, make them dark.
651 we do this by moving an equal distance to the other side of the
652 central circle in the color wheel from where we started.
655 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f));
656 minor_shift = 125 - radius;
658 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
660 r = base_color.get_red()/256;
661 g = base_color.get_green()/256;
662 b = base_color.get_blue()/256;
668 /* red sector => green */
673 /* green sector => blue */
681 /* blue sector => red */
686 /* green sector => blue */
695 label_color = RGBA_TO_UINT(r,g,b,255);
696 r = (base_color.get_red()/256) + 127;
697 g = (base_color.get_green()/256) + 127;
698 b = (base_color.get_blue()/256) + 127;
700 label_color = RGBA_TO_UINT(r,g,b,255);
702 /* XXX can we do better than this ? */
706 //frame_color_r = 192;
707 //frame_color_g = 192;
708 //frame_color_b = 194;
710 //selected_frame_color_r = 182;
711 //selected_frame_color_g = 145;
712 //selected_frame_color_b = 168;
714 //handle_color_r = 25;
715 //handle_color_g = 0;
716 //handle_color_b = 255;
717 //lock_handle_color_r = 235;
718 //lock_handle_color_g = 16;
719 //lock_handle_color_b = 16;
723 * Convenience method to set the various canvas item colors
726 TimeAxisViewItem::set_colors()
730 if (name_highlight) {
731 name_highlight->set_fill_color (fill_color);
737 const double black_r = 0.0;
738 const double black_g = 0.0;
739 const double black_b = 0.0;
741 const double white_r = 1.0;
742 const double white_g = 1.0;
743 const double white_b = 1.0;
745 ArdourCanvas::color_to_rgba (fill_color, r, g, b, a);
747 /* Use W3C contrast guideline calculation */
749 double white_contrast = (max (r, white_r) - min (r, white_r)) +
750 (max (g, white_g) - min (g, white_g)) +
751 (max (b, white_b) - min (b, white_b));
753 double black_contrast = (max (r, black_r) - min (r, black_r)) +
754 (max (g, black_g) - min (g, black_g)) +
755 (max (b, black_b) - min (b, black_b));
757 if (white_contrast > black_contrast) {
759 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
762 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
768 ArdourCanvas::color_to_hsv (fill_color, h, s, v);
771 /* fill is black, set text to white */
772 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
773 } else if (v == 1.0) {
774 /* fill is white, set text to black */
775 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
778 h = fabs (fmod ((h - 180), 360.0)); /* complementary color */
779 s = 1.0; /* fully saturate */
780 v = 0.9; /* increase lightness/brightness/value */
782 name_text->set_color (ArdourCanvas::hsv_to_color (h, s, v, 1.0));
788 set_trim_handle_colors();
792 TimeAxisViewItem::get_fill_color () const
798 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
803 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
806 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
807 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
818 * Sets the frame color depending on whether this item is selected
821 TimeAxisViewItem::set_frame_color()
829 f = get_fill_color ();
832 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
836 f = UINT_RGBA_CHANGE_A (f, 0);
839 frame->set_fill_color (f);
840 set_frame_gradient ();
844 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
846 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
850 f = UINT_RGBA_CHANGE_A (f, 64);
853 frame->set_outline_color (f);
858 TimeAxisViewItem::set_frame_gradient ()
860 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
861 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
865 ArdourCanvas::Fill::StopList stops;
868 ArdourCanvas::Color f (get_fill_color());
870 /* need to get alpha value */
871 ArdourCanvas::color_to_rgba (f, r, g, b, a);
873 stops.push_back (std::make_pair (0.0, f));
875 /* now a darker version */
877 ArdourCanvas::color_to_hsv (f, h, s, v);
879 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
881 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
882 stops.push_back (std::make_pair (1.0, darker));
884 frame->set_gradient (stops, true);
888 * Set the colors of the start and end trim handle depending on object state
891 TimeAxisViewItem::set_trim_handle_colors()
893 if (frame_handle_start) {
894 if (position_locked) {
895 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
896 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
898 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
899 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
905 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
908 case GDK_LEAVE_NOTIFY:
909 item->set_fill (false);
911 case GDK_ENTER_NOTIFY:
912 item->set_fill (true);
920 /** @return the frames per pixel */
922 TimeAxisViewItem::get_samples_per_pixel () const
924 return samples_per_pixel;
927 /** Set the frames per pixel of this item.
928 * This item is used to determine the relative visual size and position of this item
929 * based upon its duration and start value.
931 * @param fpp the new frames per pixel
934 TimeAxisViewItem::set_samples_per_pixel (double fpp)
936 samples_per_pixel = fpp;
937 set_position (this->get_position(), this);
938 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
942 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
944 if (pixel_width < 2.0) {
946 if (show_vestigial) {
947 vestigial_frame->show();
950 if (name_highlight) {
951 name_highlight->hide();
958 if (frame_handle_start) {
959 frame_handle_start->hide();
960 frame_handle_end->hide();
963 wide_enough_for_name = false;
966 vestigial_frame->hide();
968 if (name_highlight) {
970 if (_height < NAME_HIGHLIGHT_THRESH) {
971 name_highlight->hide();
972 high_enough_for_name = false;
974 name_highlight->show();
975 if (!get_item_name().empty()) {
976 reset_name_width (pixel_width);
978 high_enough_for_name = true;
981 name_highlight->set_x1 (pixel_width);
986 frame->set_x1 (pixel_width);
989 if (frame_handle_start) {
990 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
992 * there's less than GRAB_HANDLE_WIDTH of the region between
993 * the right-hand end of frame_handle_start and the left-hand
994 * end of frame_handle_end, so disable the handles
997 frame_handle_start->hide();
998 frame_handle_end->hide();
1000 frame_handle_start->show();
1001 frame_handle_end->set_x0 (pixel_width - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1002 frame_handle_end->set_x1 (pixel_width);
1003 frame_handle_end->show();
1007 wide_enough_for_name = true;
1010 update_name_text_visibility ();
1014 TimeAxisViewItem::reset_name_width (double /*pixel_width*/)
1018 bool showing_full_name;
1024 it_width = trackview.editor().sample_to_pixel(item_duration);
1025 pb_width = name_text_width;
1027 showing_full_name = last_item_width > pb_width + NAME_X_OFFSET;
1028 last_item_width = it_width;
1030 if (showing_full_name && (it_width >= pb_width + NAME_X_OFFSET)) {
1032 we've previously had the full name length showing
1033 and its still showing.
1038 if (pb_width > it_width - NAME_X_OFFSET) {
1039 pb_width = it_width - NAME_X_OFFSET;
1042 if (it_width <= NAME_X_OFFSET) {
1043 wide_enough_for_name = false;
1045 wide_enough_for_name = true;
1048 update_name_text_visibility ();
1054 name_text->set (item_name);
1055 name_text->clamp_width (pb_width);
1059 * Callback used to remove this time axis item during the gtk idle loop.
1060 * This is used to avoid deleting the obejct while inside the remove_this_item
1063 * @param item the TimeAxisViewItem to remove.
1064 * @param src the identity of the object that initiated the change.
1067 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1069 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1076 TimeAxisViewItem::set_y (double y)
1078 group->set_y_position (y);
1082 TimeAxisViewItem::update_name_text_visibility ()
1088 if (wide_enough_for_name && high_enough_for_name) {
1096 TimeAxisViewItem::parameter_changed (string p)
1098 if (p == "color-regions-using-track-color") {
1100 } else if (p == "timeline-item-gradient-depth") {
1101 set_frame_gradient ();