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
110 , _recregion (recording)
111 , _automation (automation)
114 init (it_name, &parent, spu, base_color, start, duration, vis, true, true);
117 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
120 , PBD::ScopedConnectionList()
121 , trackview (other.trackview)
122 , _recregion (other._recregion)
123 , _automation (other._automation)
124 , _dragging (other._dragging)
130 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
131 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
133 /* share the other's parent, but still create a new group */
135 ArdourCanvas::Group* parent = other.group->parent();
137 _selected = other._selected;
139 init (other.item_name, parent, other.samples_per_pixel, c, other.frame_position,
140 other.item_duration, other.visibility, other.wide_enough_for_name, other.high_enough_for_name);
144 TimeAxisViewItem::init (const string& it_name, ArdourCanvas::Group* parent, double fpp, Gdk::Color const & base_color,
145 framepos_t start, framepos_t duration, Visibility vis,
146 bool wide, bool high)
148 group = new ArdourCanvas::Group (parent);
149 CANVAS_DEBUG_NAME (group, string_compose ("TAVI group for %1", get_item_name()));
150 group->Event.connect (sigc::mem_fun (*this, &TimeAxisViewItem::canvas_group_event));
153 samples_per_pixel = fpp;
154 frame_position = start;
155 item_duration = duration;
156 name_connected = false;
158 position_locked = false;
159 max_item_duration = ARDOUR::max_framepos;
160 min_item_duration = 0;
161 show_vestigial = true;
166 wide_enough_for_name = wide;
167 high_enough_for_name = high;
171 warning << "Time Axis Item Duration == 0" << endl;
174 vestigial_frame = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, 1.0, 2.0, trackview.current_height()));
175 CANVAS_DEBUG_NAME (vestigial_frame, string_compose ("vestigial frame for %1", get_item_name()));
176 vestigial_frame->hide ();
177 vestigial_frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
178 vestigial_frame->set_fill_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
180 if (visibility & ShowFrame) {
181 frame = new ArdourCanvas::Rectangle (group,
182 ArdourCanvas::Rect (0.0, 1.0,
183 trackview.editor().sample_to_pixel(duration),
184 trackview.current_height()));
185 CANVAS_DEBUG_NAME (frame, string_compose ("frame for %1", get_item_name()));
188 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RecordingRect());
190 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame());
198 if (visibility & ShowNameHighlight) {
200 if (visibility & FullWidthNameHighlight) {
201 name_highlight = new ArdourCanvas::Rectangle (group,
202 ArdourCanvas::Rect (0.0, trackview.editor().sample_to_pixel(item_duration),
203 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
204 trackview.current_height()));
205 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
207 name_highlight = new ArdourCanvas::Rectangle (group,
208 ArdourCanvas::Rect (1.0, trackview.editor().sample_to_pixel(item_duration) - 1,
209 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
210 trackview.current_height()));
211 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
214 name_highlight->set_data ("timeaxisviewitem", this);
215 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
216 /* we should really use a canvas color property here */
217 name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
223 if (visibility & ShowNameText) {
224 name_text = new ArdourCanvas::Text (group);
225 CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
226 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
227 name_text->set_font_description (NAME_FONT);
233 /* create our grab handles used for trimming/duration etc */
234 if (!_recregion && !_automation) {
235 double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
236 double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
238 frame_handle_start = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
239 CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
240 frame_handle_start->set_outline (false);
241 frame_handle_start->set_fill (false);
242 frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
244 frame_handle_end = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()));
245 CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
246 frame_handle_end->set_outline (false);
247 frame_handle_end->set_fill (false);
248 frame_handle_end->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_end));
250 frame_handle_start = frame_handle_end = 0;
253 set_color (base_color);
255 set_duration (item_duration, this);
256 set_position (start, this);
258 Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&TimeAxisViewItem::parameter_changed, this, _1), gui_context ());
259 ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &TimeAxisViewItem::parameter_changed));
262 TimeAxisViewItem::~TimeAxisViewItem()
268 TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
274 TimeAxisViewItem::hide_rect ()
276 rect_visible = false;
279 if (name_highlight) {
280 name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0));
281 name_highlight->set_fill_color (UINT_RGBA_CHANGE_A (fill_color, 64));
286 TimeAxisViewItem::show_rect ()
291 if (name_highlight) {
292 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
293 name_highlight->set_fill_color (fill_color);
298 * Set the position of this item on the timeline.
300 * @param pos the new position
301 * @param src the identity of the object that initiated the change
302 * @return true on success
306 TimeAxisViewItem::set_position(framepos_t pos, void* src, double* delta)
308 if (position_locked) {
312 frame_position = pos;
314 /* This sucks. The GnomeCanvas version I am using
315 doesn't correctly implement gnome_canvas_group_set_arg(),
316 so that simply setting the "x" arg of the group
317 fails to move the group. Instead, we have to
318 use gnome_canvas_item_move(), which does the right
319 thing. I see that in GNOME CVS, the current (Sept 2001)
320 version of GNOME Canvas rectifies this issue cleanly.
324 double new_unit_pos = pos / samples_per_pixel;
326 old_unit_pos = group->position().x;
328 if (new_unit_pos != old_unit_pos) {
329 group->set_x_position (new_unit_pos);
333 (*delta) = new_unit_pos - old_unit_pos;
336 PositionChanged (frame_position, src); /* EMIT_SIGNAL */
341 /** @return position of this item on the timeline */
343 TimeAxisViewItem::get_position() const
345 return frame_position;
349 * Set the duration of this item.
351 * @param dur the new duration of this item
352 * @param src the identity of the object that initiated the change
353 * @return true on success
357 TimeAxisViewItem::set_duration (framecnt_t dur, void* src)
359 if ((dur > max_item_duration) || (dur < min_item_duration)) {
360 warning << string_compose (
361 P_("new duration %1 frame is out of bounds for %2", "new duration of %1 frames is out of bounds for %2", dur),
362 get_item_name(), dur)
373 reset_width_dependent_items (trackview.editor().sample_to_pixel (dur));
375 DurationChanged (dur, src); /* EMIT_SIGNAL */
379 /** @return duration of this item */
381 TimeAxisViewItem::get_duration() const
383 return item_duration;
387 * Set the maximum duration that this item can have.
389 * @param dur the new maximum duration
390 * @param src the identity of the object that initiated the change
393 TimeAxisViewItem::set_max_duration(framecnt_t dur, void* src)
395 max_item_duration = dur;
396 MaxDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
399 /** @return the maximum duration that this item may have */
401 TimeAxisViewItem::get_max_duration() const
403 return max_item_duration;
407 * Set the minimum duration that this item may have.
409 * @param the minimum duration that this item may be set to
410 * @param src the identity of the object that initiated the change
413 TimeAxisViewItem::set_min_duration(framecnt_t dur, void* src)
415 min_item_duration = dur;
416 MinDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
419 /** @return the minimum duration that this item mey have */
421 TimeAxisViewItem::get_min_duration() const
423 return min_item_duration;
427 * Set whether this item is locked to its current position.
428 * Locked items cannot be moved until the item is unlocked again.
430 * @param yn true to lock this item to its current position
431 * @param src the identity of the object that initiated the change
434 TimeAxisViewItem::set_position_locked(bool yn, void* src)
436 position_locked = yn;
437 set_trim_handle_colors();
438 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
441 /** @return true if this item is locked to its current position */
443 TimeAxisViewItem::get_position_locked() const
445 return position_locked;
449 * Set whether the maximum duration constraint is active.
451 * @param active set true to enforce the max duration constraint
452 * @param src the identity of the object that initiated the change
455 TimeAxisViewItem::set_max_duration_active (bool active, void* /*src*/)
457 max_duration_active = active;
460 /** @return true if the maximum duration constraint is active */
462 TimeAxisViewItem::get_max_duration_active() const
464 return max_duration_active;
468 * Set whether the minimum duration constraint is active.
470 * @param active set true to enforce the min duration constraint
471 * @param src the identity of the object that initiated the change
475 TimeAxisViewItem::set_min_duration_active (bool active, void* /*src*/)
477 min_duration_active = active;
480 /** @return true if the maximum duration constraint is active */
482 TimeAxisViewItem::get_min_duration_active() const
484 return min_duration_active;
488 * Set the name of this item.
490 * @param new_name the new name of this item
491 * @param src the identity of the object that initiated the change
495 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
497 if (new_name != item_name) {
498 std::string temp_name = item_name;
499 item_name = new_name;
500 NameChanged (item_name, temp_name, src); /* EMIT_SIGNAL */
504 /** @return the name of this item */
506 TimeAxisViewItem::get_item_name() const
512 * Set selection status.
514 * @param yn true if this item is currently selected
517 TimeAxisViewItem::set_selected(bool yn)
519 if (_selected != yn) {
520 Selectable::set_selected (yn);
525 /** @return the TimeAxisView that this item is on */
527 TimeAxisViewItem::get_time_axis_view () const
533 * Set the displayed item text.
534 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item.
536 * @param new_name the new name text to display
540 TimeAxisViewItem::set_name_text(const string& new_name)
546 last_item_width = trackview.editor().sample_to_pixel(item_duration);
547 name_text_width = pixel_width (new_name, NAME_FONT) + 2;
548 name_text->set (new_name);
553 * Set the height of this item.
555 * @param h new height
558 TimeAxisViewItem::set_height (double height)
562 if (name_highlight) {
563 if (height < NAME_HIGHLIGHT_THRESH) {
564 name_highlight->hide ();
565 high_enough_for_name = false;
568 name_highlight->show();
569 high_enough_for_name = true;
572 if (height > NAME_HIGHLIGHT_SIZE) {
573 name_highlight->set_y0 ((double) height - 1 - NAME_HIGHLIGHT_SIZE);
574 name_highlight->set_y1 ((double) height - 1);
577 /* it gets hidden now anyway */
578 name_highlight->set_y0 (1);
579 name_highlight->set_y1 (height);
583 if (visibility & ShowNameText) {
584 name_text->set_y_position (height + 1 - NAME_Y_OFFSET);
588 frame->set_y1 (height - 1);
589 if (frame_handle_start) {
590 frame_handle_start->set_y1 (height - 1);
591 frame_handle_end->set_y1 (height - 1);
595 vestigial_frame->set_y1 (height - 1);
597 update_name_text_visibility ();
602 TimeAxisViewItem::set_color (Gdk::Color const & base_color)
604 compute_colors (base_color);
609 TimeAxisViewItem::get_canvas_frame()
615 TimeAxisViewItem::get_canvas_group()
621 TimeAxisViewItem::get_name_highlight()
623 return name_highlight;
627 * Calculate some contrasting color for displaying various parts of this item, based upon the base color.
629 * @param color the base color of the item
632 TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
634 unsigned char radius;
639 /* FILL: this is simple */
640 r = base_color.get_red()/256;
641 g = base_color.get_green()/256;
642 b = base_color.get_blue()/256;
643 fill_color = RGBA_TO_UINT(r,g,b,160);
646 if the overall saturation is strong, make the minor colors light.
647 if its weak, make them dark.
649 we do this by moving an equal distance to the other side of the
650 central circle in the color wheel from where we started.
653 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f));
654 minor_shift = 125 - radius;
656 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
658 r = base_color.get_red()/256;
659 g = base_color.get_green()/256;
660 b = base_color.get_blue()/256;
666 /* red sector => green */
671 /* green sector => blue */
679 /* blue sector => red */
684 /* green sector => blue */
693 label_color = RGBA_TO_UINT(r,g,b,255);
694 r = (base_color.get_red()/256) + 127;
695 g = (base_color.get_green()/256) + 127;
696 b = (base_color.get_blue()/256) + 127;
698 label_color = RGBA_TO_UINT(r,g,b,255);
700 /* XXX can we do better than this ? */
704 //frame_color_r = 192;
705 //frame_color_g = 192;
706 //frame_color_b = 194;
708 //selected_frame_color_r = 182;
709 //selected_frame_color_g = 145;
710 //selected_frame_color_b = 168;
712 //handle_color_r = 25;
713 //handle_color_g = 0;
714 //handle_color_b = 255;
715 //lock_handle_color_r = 235;
716 //lock_handle_color_g = 16;
717 //lock_handle_color_b = 16;
721 * Convenience method to set the various canvas item colors
724 TimeAxisViewItem::set_colors()
728 if (name_highlight) {
729 name_highlight->set_fill_color (fill_color);
735 const double black_r = 0.0;
736 const double black_g = 0.0;
737 const double black_b = 0.0;
739 const double white_r = 1.0;
740 const double white_g = 1.0;
741 const double white_b = 1.0;
743 ArdourCanvas::color_to_rgba (fill_color, r, g, b, a);
745 /* Use W3C contrast guideline calculation */
747 double white_contrast = (max (r, white_r) - min (r, white_r)) +
748 (max (g, white_g) - min (g, white_g)) +
749 (max (b, white_b) - min (b, white_b));
751 double black_contrast = (max (r, black_r) - min (r, black_r)) +
752 (max (g, black_g) - min (g, black_g)) +
753 (max (b, black_b) - min (b, black_b));
755 if (white_contrast > black_contrast) {
757 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
760 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
766 ArdourCanvas::color_to_hsv (fill_color, h, s, v);
769 /* fill is black, set text to white */
770 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
771 } else if (v == 1.0) {
772 /* fill is white, set text to black */
773 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
776 h = fabs (fmod ((h - 180), 360.0)); /* complementary color */
777 s = 1.0; /* fully saturate */
778 v = 0.9; /* increase lightness/brightness/value */
780 name_text->set_color (ArdourCanvas::hsv_to_color (h, s, v, 1.0));
786 set_trim_handle_colors();
790 TimeAxisViewItem::get_fill_color () const
796 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
801 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
804 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
805 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
816 * Sets the frame color depending on whether this item is selected
819 TimeAxisViewItem::set_frame_color()
827 f = get_fill_color ();
830 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
834 f = UINT_RGBA_CHANGE_A (f, 0);
837 frame->set_fill_color (f);
838 set_frame_gradient ();
842 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
844 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
848 f = UINT_RGBA_CHANGE_A (f, 64);
851 frame->set_outline_color (f);
856 TimeAxisViewItem::set_frame_gradient ()
858 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
859 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
863 ArdourCanvas::Fill::StopList stops;
866 ArdourCanvas::Color f (get_fill_color());
868 /* need to get alpha value */
869 ArdourCanvas::color_to_rgba (f, r, g, b, a);
871 stops.push_back (std::make_pair (0.0, f));
873 /* now a darker version */
875 ArdourCanvas::color_to_hsv (f, h, s, v);
877 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
879 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
880 stops.push_back (std::make_pair (1.0, darker));
882 frame->set_gradient (stops, true);
886 * Set the colors of the start and end trim handle depending on object state
889 TimeAxisViewItem::set_trim_handle_colors()
891 if (frame_handle_start) {
892 if (position_locked) {
893 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
894 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
896 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
897 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
903 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
906 case GDK_LEAVE_NOTIFY:
907 item->set_fill (false);
909 case GDK_ENTER_NOTIFY:
910 item->set_fill (true);
918 /** @return the frames per pixel */
920 TimeAxisViewItem::get_samples_per_pixel () const
922 return samples_per_pixel;
925 /** Set the frames per pixel of this item.
926 * This item is used to determine the relative visual size and position of this item
927 * based upon its duration and start value.
929 * @param fpp the new frames per pixel
932 TimeAxisViewItem::set_samples_per_pixel (double fpp)
934 samples_per_pixel = fpp;
935 set_position (this->get_position(), this);
936 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
940 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
942 if (pixel_width < 2.0) {
944 if (show_vestigial) {
945 vestigial_frame->show();
948 if (name_highlight) {
949 name_highlight->hide();
956 if (frame_handle_start) {
957 frame_handle_start->hide();
958 frame_handle_end->hide();
961 wide_enough_for_name = false;
964 vestigial_frame->hide();
966 if (name_highlight) {
968 if (_height < NAME_HIGHLIGHT_THRESH) {
969 name_highlight->hide();
970 high_enough_for_name = false;
972 name_highlight->show();
973 if (!get_item_name().empty()) {
974 reset_name_width (pixel_width);
976 high_enough_for_name = true;
979 name_highlight->set_x1 (pixel_width);
984 frame->set_x1 (pixel_width);
987 if (frame_handle_start) {
988 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
990 * there's less than GRAB_HANDLE_WIDTH of the region between
991 * the right-hand end of frame_handle_start and the left-hand
992 * end of frame_handle_end, so disable the handles
995 frame_handle_start->hide();
996 frame_handle_end->hide();
998 frame_handle_start->show();
999 frame_handle_end->set_x0 (pixel_width - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1000 frame_handle_end->set_x1 (pixel_width);
1001 frame_handle_end->show();
1005 wide_enough_for_name = true;
1008 update_name_text_visibility ();
1012 TimeAxisViewItem::reset_name_width (double /*pixel_width*/)
1016 bool showing_full_name;
1022 it_width = trackview.editor().sample_to_pixel(item_duration);
1023 pb_width = name_text_width;
1025 showing_full_name = last_item_width > pb_width + NAME_X_OFFSET;
1026 last_item_width = it_width;
1028 if (showing_full_name && (it_width >= pb_width + NAME_X_OFFSET)) {
1030 we've previously had the full name length showing
1031 and its still showing.
1036 if (pb_width > it_width - NAME_X_OFFSET) {
1037 pb_width = it_width - NAME_X_OFFSET;
1040 if (it_width <= NAME_X_OFFSET) {
1041 wide_enough_for_name = false;
1043 wide_enough_for_name = true;
1046 update_name_text_visibility ();
1052 name_text->set (item_name);
1053 name_text->clamp_width (pb_width);
1057 * Callback used to remove this time axis item during the gtk idle loop.
1058 * This is used to avoid deleting the obejct while inside the remove_this_item
1061 * @param item the TimeAxisViewItem to remove.
1062 * @param src the identity of the object that initiated the change.
1065 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1067 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1074 TimeAxisViewItem::set_y (double y)
1076 group->set_y_position (y);
1080 TimeAxisViewItem::update_name_text_visibility ()
1086 if (wide_enough_for_name && high_enough_for_name) {
1094 TimeAxisViewItem::parameter_changed (string p)
1096 if (p == "color-regions-using-track-color") {
1098 } else if (p == "timeline-item-gradient-depth") {
1099 set_frame_gradient ();