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/drag_handle.h"
35 #include "canvas/text.h"
36 #include "canvas/utils.h"
38 #include "ardour/profile.h"
40 #include "ardour_ui.h"
42 * ardour_ui.h was moved up in the include list
43 * due to a conflicting definition of 'Rect' between
44 * Apple's MacTypes.h file and GTK
47 #include "public_editor.h"
48 #include "time_axis_view_item.h"
49 #include "time_axis_view.h"
51 #include "rgb_macros.h"
56 using namespace Editing;
59 using namespace ARDOUR;
60 using namespace Gtkmm2ext;
62 Pango::FontDescription TimeAxisViewItem::NAME_FONT;
63 const double TimeAxisViewItem::NAME_X_OFFSET = 15.0;
64 const double TimeAxisViewItem::GRAB_HANDLE_TOP = 0.0;
65 const double TimeAxisViewItem::GRAB_HANDLE_WIDTH = 10.0;
66 const double TimeAxisViewItem::RIGHT_EDGE_SHIFT = 1.0;
68 int TimeAxisViewItem::NAME_HEIGHT;
69 double TimeAxisViewItem::NAME_Y_OFFSET;
70 double TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
71 double TimeAxisViewItem::NAME_HIGHLIGHT_THRESH;
74 TimeAxisViewItem::set_constant_heights ()
76 NAME_FONT = get_font_for_style (X_("TimeAxisViewItemName"));
82 Glib::RefPtr<Pango::Layout> layout = foo.create_pango_layout (X_("Hg")); /* ascender + descender */
86 layout->set_font_description (NAME_FONT);
87 get_pixel_size (layout, width, height);
89 layout = foo.create_pango_layout (X_("H")); /* just the ascender */
93 /* Config->get_show_name_highlight) == true:
94 Y_OFFSET is measured from bottom of the time axis view item.
95 Config->get_show_name_highlight) == false:
96 Y_OFFSET is measured from the top of the time axis view item.
99 if (Config->get_show_name_highlight()) {
100 NAME_Y_OFFSET = height + 1;
101 NAME_HIGHLIGHT_SIZE = height + 2;
104 NAME_HIGHLIGHT_SIZE = 0;
106 NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 3;
110 * Construct a new TimeAxisViewItem.
112 * @param it_name the unique name of this item
113 * @param parent the parent canvas group
114 * @param tv the TimeAxisView we are going to be added to
115 * @param spu samples per unit
117 * @param start the start point of this item
118 * @param duration the duration of this item
119 * @param recording true if this is a recording region view
120 * @param automation true if this is an automation region view
122 TimeAxisViewItem::TimeAxisViewItem(
123 const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color,
124 framepos_t start, framecnt_t duration, bool recording, bool automation, Visibility vis
127 , frame_position (-1)
128 , item_name (it_name)
130 , _recregion (recording)
131 , _automation (automation)
135 init (&parent, spu, base_color, start, duration, vis, true, true);
138 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
141 , PBD::ScopedConnectionList()
142 , trackview (other.trackview)
143 , frame_position (-1)
144 , item_name (other.item_name)
146 , _recregion (other._recregion)
147 , _automation (other._automation)
148 , _dragging (other._dragging)
155 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
156 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
158 /* share the other's parent, but still create a new group */
160 ArdourCanvas::Group* parent = other.group->parent();
162 _selected = other._selected;
164 init (parent, other.samples_per_pixel, c, other.frame_position,
165 other.item_duration, other.visibility, other.wide_enough_for_name, other.high_enough_for_name);
169 TimeAxisViewItem::init (ArdourCanvas::Group* parent, double fpp, Gdk::Color const & base_color,
170 framepos_t start, framepos_t duration, Visibility vis,
171 bool wide, bool high)
173 group = new ArdourCanvas::Group (parent);
174 CANVAS_DEBUG_NAME (group, string_compose ("TAVI group for %1", get_item_name()));
175 group->Event.connect (sigc::mem_fun (*this, &TimeAxisViewItem::canvas_group_event));
177 samples_per_pixel = fpp;
178 frame_position = start;
179 item_duration = duration;
180 name_connected = false;
182 position_locked = false;
183 max_item_duration = ARDOUR::max_framepos;
184 min_item_duration = 0;
185 show_vestigial = true;
190 wide_enough_for_name = wide;
191 high_enough_for_name = high;
195 warning << "Time Axis Item Duration == 0" << endl;
198 vestigial_frame = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, 1.0, 2.0, trackview.current_height()));
199 CANVAS_DEBUG_NAME (vestigial_frame, string_compose ("vestigial frame for %1", get_item_name()));
200 vestigial_frame->hide ();
201 vestigial_frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
202 vestigial_frame->set_fill_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
204 if (visibility & ShowFrame) {
205 frame = new ArdourCanvas::Rectangle (group,
206 ArdourCanvas::Rect (0.0, 0.0,
207 trackview.editor().sample_to_pixel(duration) + RIGHT_EDGE_SHIFT,
208 trackview.current_height() - 1.0));
210 CANVAS_DEBUG_NAME (frame, string_compose ("frame for %1", get_item_name()));
212 if (Config->get_show_name_highlight()) {
213 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::LEFT|ArdourCanvas::Rectangle::RIGHT));
215 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::LEFT|ArdourCanvas::Rectangle::RIGHT|ArdourCanvas::Rectangle::BOTTOM));
219 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RecordingRect());
221 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame());
229 if (Config->get_show_name_highlight() && (visibility & ShowNameHighlight)) {
234 if (visibility & FullWidthNameHighlight) {
236 width = trackview.editor().sample_to_pixel(item_duration) + RIGHT_EDGE_SHIFT;
239 width = trackview.editor().sample_to_pixel(item_duration) - 2.0 + RIGHT_EDGE_SHIFT;
242 name_highlight = new ArdourCanvas::Rectangle (group,
243 ArdourCanvas::Rect (start,
244 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
245 width - 2.0 + RIGHT_EDGE_SHIFT,
246 trackview.current_height() - 1.0));
247 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
248 name_highlight->set_data ("timeaxisviewitem", this);
249 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
250 name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
256 if (visibility & ShowNameText) {
257 name_text = new ArdourCanvas::Text (group);
258 CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
259 if (Config->get_show_name_highlight()) {
260 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
262 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, NAME_Y_OFFSET));
264 name_text->set_font_description (NAME_FONT);
269 /* create our grab handles used for trimming/duration etc */
270 if (!_recregion && !_automation) {
271 double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
272 double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
274 frame_handle_start = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), true);
275 CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
276 frame_handle_start->set_outline (false);
277 frame_handle_start->set_fill (false);
278 frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
280 frame_handle_end = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), false);
281 CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
282 frame_handle_end->set_outline (false);
283 frame_handle_end->set_fill (false);
284 frame_handle_end->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_end));
286 frame_handle_start = frame_handle_end = 0;
289 set_color (base_color);
291 set_duration (item_duration, this);
292 set_position (start, this);
294 Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&TimeAxisViewItem::parameter_changed, this, _1), gui_context ());
295 ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &TimeAxisViewItem::parameter_changed));
298 TimeAxisViewItem::~TimeAxisViewItem()
304 TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
310 TimeAxisViewItem::hide_rect ()
312 rect_visible = false;
315 if (name_highlight) {
316 name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0));
317 name_highlight->set_fill_color (UINT_RGBA_CHANGE_A (fill_color, 64));
322 TimeAxisViewItem::show_rect ()
327 if (name_highlight) {
328 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
329 name_highlight->set_fill_color (fill_color);
334 * Set the position of this item on the timeline.
336 * @param pos the new position
337 * @param src the identity of the object that initiated the change
338 * @return true on success
342 TimeAxisViewItem::set_position(framepos_t pos, void* src, double* delta)
344 if (position_locked) {
348 frame_position = pos;
350 double new_unit_pos = trackview.editor().sample_to_pixel (pos);
353 (*delta) = new_unit_pos - group->position().x;
358 if (new_unit_pos == group->position().x) {
363 group->set_x_position (new_unit_pos);
365 PositionChanged (frame_position, src); /* EMIT_SIGNAL */
370 /** @return position of this item on the timeline */
372 TimeAxisViewItem::get_position() const
374 return frame_position;
378 * Set the duration of this item.
380 * @param dur the new duration of this item
381 * @param src the identity of the object that initiated the change
382 * @return true on success
386 TimeAxisViewItem::set_duration (framecnt_t dur, void* src)
388 if ((dur > max_item_duration) || (dur < min_item_duration)) {
389 warning << string_compose (
390 P_("new duration %1 frame is out of bounds for %2", "new duration of %1 frames is out of bounds for %2", dur),
391 get_item_name(), dur)
402 reset_width_dependent_items (trackview.editor().sample_to_pixel (dur));
404 DurationChanged (dur, src); /* EMIT_SIGNAL */
408 /** @return duration of this item */
410 TimeAxisViewItem::get_duration() const
412 return item_duration;
416 * Set the maximum duration that this item can have.
418 * @param dur the new maximum duration
419 * @param src the identity of the object that initiated the change
422 TimeAxisViewItem::set_max_duration(framecnt_t dur, void* src)
424 max_item_duration = dur;
425 MaxDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
428 /** @return the maximum duration that this item may have */
430 TimeAxisViewItem::get_max_duration() const
432 return max_item_duration;
436 * Set the minimum duration that this item may have.
438 * @param the minimum duration that this item may be set to
439 * @param src the identity of the object that initiated the change
442 TimeAxisViewItem::set_min_duration(framecnt_t dur, void* src)
444 min_item_duration = dur;
445 MinDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
448 /** @return the minimum duration that this item mey have */
450 TimeAxisViewItem::get_min_duration() const
452 return min_item_duration;
456 * Set whether this item is locked to its current position.
457 * Locked items cannot be moved until the item is unlocked again.
459 * @param yn true to lock this item to its current position
460 * @param src the identity of the object that initiated the change
463 TimeAxisViewItem::set_position_locked(bool yn, void* src)
465 position_locked = yn;
466 set_trim_handle_colors();
467 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
470 /** @return true if this item is locked to its current position */
472 TimeAxisViewItem::get_position_locked() const
474 return position_locked;
478 * Set whether the maximum duration constraint is active.
480 * @param active set true to enforce the max duration constraint
481 * @param src the identity of the object that initiated the change
484 TimeAxisViewItem::set_max_duration_active (bool active, void* /*src*/)
486 max_duration_active = active;
489 /** @return true if the maximum duration constraint is active */
491 TimeAxisViewItem::get_max_duration_active() const
493 return max_duration_active;
497 * Set whether the minimum duration constraint is active.
499 * @param active set true to enforce the min duration constraint
500 * @param src the identity of the object that initiated the change
504 TimeAxisViewItem::set_min_duration_active (bool active, void* /*src*/)
506 min_duration_active = active;
509 /** @return true if the maximum duration constraint is active */
511 TimeAxisViewItem::get_min_duration_active() const
513 return min_duration_active;
517 * Set the name of this item.
519 * @param new_name the new name of this item
520 * @param src the identity of the object that initiated the change
524 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
526 if (new_name != item_name) {
527 std::string temp_name = item_name;
528 item_name = new_name;
529 NameChanged (item_name, temp_name, src); /* EMIT_SIGNAL */
533 /** @return the name of this item */
535 TimeAxisViewItem::get_item_name() const
541 * Set selection status.
543 * @param yn true if this item is currently selected
546 TimeAxisViewItem::set_selected(bool yn)
548 if (_selected != yn) {
549 Selectable::set_selected (yn);
554 /** @return the TimeAxisView that this item is on */
556 TimeAxisViewItem::get_time_axis_view () const
562 * Set the displayed item text.
563 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item.
565 * @param new_name the new name text to display
569 TimeAxisViewItem::set_name_text(const string& new_name)
575 name_text_width = pixel_width (new_name, NAME_FONT) + 2;
576 name_text->set (new_name);
581 * Set the height of this item.
583 * @param h new height
586 TimeAxisViewItem::set_height (double height)
590 manage_name_highlight ();
592 if (visibility & ShowNameText) {
593 if (Config->get_show_name_highlight()) {
594 name_text->set_y_position (height - NAME_Y_OFFSET);
596 name_text->set_y_position (NAME_Y_OFFSET);
601 frame->set_y1 (height);
602 if (frame_handle_start) {
603 frame_handle_start->set_y1 (height);
604 frame_handle_end->set_y1 (height);
608 vestigial_frame->set_y1 (height - 1.0);
614 TimeAxisViewItem::manage_name_highlight ()
616 if (!name_highlight) {
620 if (_height < NAME_HIGHLIGHT_THRESH) {
621 high_enough_for_name = false;
623 high_enough_for_name = true;
627 wide_enough_for_name = false;
629 wide_enough_for_name = true;
632 if (name_highlight && wide_enough_for_name && high_enough_for_name) {
634 name_highlight->show();
635 name_highlight->set (ArdourCanvas::Rect (0.0, (double) _height - NAME_HIGHLIGHT_SIZE, _width+RIGHT_EDGE_SHIFT, (double) _height - 1.0));
638 name_highlight->hide();
645 TimeAxisViewItem::set_color (Gdk::Color const & base_color)
647 compute_colors (base_color);
652 TimeAxisViewItem::get_canvas_frame()
658 TimeAxisViewItem::get_canvas_group()
664 TimeAxisViewItem::get_name_highlight()
666 return name_highlight;
670 * Calculate some contrasting color for displaying various parts of this item, based upon the base color.
672 * @param color the base color of the item
675 TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
677 unsigned char radius;
682 /* FILL: this is simple */
683 r = base_color.get_red()/256;
684 g = base_color.get_green()/256;
685 b = base_color.get_blue()/256;
686 fill_color = RGBA_TO_UINT(r,g,b,160);
689 if the overall saturation is strong, make the minor colors light.
690 if its weak, make them dark.
692 we do this by moving an equal distance to the other side of the
693 central circle in the color wheel from where we started.
696 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f));
697 minor_shift = 125 - radius;
699 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
701 r = base_color.get_red()/256;
702 g = base_color.get_green()/256;
703 b = base_color.get_blue()/256;
709 /* red sector => green */
714 /* green sector => blue */
722 /* blue sector => red */
727 /* green sector => blue */
736 label_color = RGBA_TO_UINT(r,g,b,255);
737 r = (base_color.get_red()/256) + 127;
738 g = (base_color.get_green()/256) + 127;
739 b = (base_color.get_blue()/256) + 127;
741 label_color = RGBA_TO_UINT(r,g,b,255);
743 /* XXX can we do better than this ? */
747 //frame_color_r = 192;
748 //frame_color_g = 192;
749 //frame_color_b = 194;
751 //selected_frame_color_r = 182;
752 //selected_frame_color_g = 145;
753 //selected_frame_color_b = 168;
755 //handle_color_r = 25;
756 //handle_color_g = 0;
757 //handle_color_b = 255;
758 //lock_handle_color_r = 235;
759 //lock_handle_color_g = 16;
760 //lock_handle_color_b = 16;
764 * Convenience method to set the various canvas item colors
767 TimeAxisViewItem::set_colors()
771 if (name_highlight) {
772 name_highlight->set_fill_color (fill_color);
775 set_name_text_color ();
776 set_trim_handle_colors();
780 TimeAxisViewItem::set_name_text_color ()
788 const double black_r = 0.0;
789 const double black_g = 0.0;
790 const double black_b = 0.0;
792 const double white_r = 1.0;
793 const double white_g = 1.0;
794 const double white_b = 1.0;
798 if (Config->get_show_name_highlight()) {
799 /* name text will always be on top of name highlight, which
800 will always use our fill color.
804 /* name text will be on top of the item, whose color
805 may vary depending on various conditions.
807 f = get_fill_color ();
810 ArdourCanvas::color_to_rgba (f, r, g, b, a);
812 /* Use W3C contrast guideline calculation */
814 double white_contrast = (max (r, white_r) - min (r, white_r)) +
815 (max (g, white_g) - min (g, white_g)) +
816 (max (b, white_b) - min (b, white_b));
818 double black_contrast = (max (r, black_r) - min (r, black_r)) +
819 (max (g, black_g) - min (g, black_g)) +
820 (max (b, black_b) - min (b, black_b));
822 if (white_contrast > black_contrast) {
824 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
827 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
832 TimeAxisViewItem::get_fill_color () const
838 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
843 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
846 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
847 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
858 * Sets the frame color depending on whether this item is selected
861 TimeAxisViewItem::set_frame_color()
869 f = get_fill_color ();
872 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
876 f = UINT_RGBA_CHANGE_A (f, 0);
879 frame->set_fill_color (f);
880 set_frame_gradient ();
884 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
886 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
890 f = UINT_RGBA_CHANGE_A (f, 64);
893 frame->set_outline_color (f);
898 TimeAxisViewItem::set_frame_gradient ()
900 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
901 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
905 ArdourCanvas::Fill::StopList stops;
908 ArdourCanvas::Color f (get_fill_color());
910 /* need to get alpha value */
911 ArdourCanvas::color_to_rgba (f, r, g, b, a);
913 stops.push_back (std::make_pair (0.0, f));
915 /* now a darker version */
917 ArdourCanvas::color_to_hsv (f, h, s, v);
919 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
921 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
922 stops.push_back (std::make_pair (1.0, darker));
924 frame->set_gradient (stops, true);
928 * Set the colors of the start and end trim handle depending on object state
931 TimeAxisViewItem::set_trim_handle_colors()
934 /* Leave them transparent for now */
935 if (frame_handle_start) {
936 frame_handle_start->set_fill_color (0x00000000);
937 frame_handle_end->set_fill_color (0x00000000);
940 if (frame_handle_start) {
941 if (position_locked) {
942 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
943 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
945 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
946 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
953 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
956 case GDK_LEAVE_NOTIFY:
957 /* always hide the handle whenever we leave, no matter what mode */
958 item->set_fill (false);
960 case GDK_ENTER_NOTIFY:
961 if (trackview.editor().effective_mouse_mode() == Editing::MouseObject &&
962 !trackview.editor().internal_editing()) {
963 /* never set this to be visible in internal
964 edit mode. Note, however, that we do need to
965 undo visibility (LEAVE_NOTIFY case above) no
966 matter what the mode is.
968 item->set_fill (true);
977 /** @return the frames per pixel */
979 TimeAxisViewItem::get_samples_per_pixel () const
981 return samples_per_pixel;
984 /** Set the frames per pixel of this item.
985 * This item is used to determine the relative visual size and position of this item
986 * based upon its duration and start value.
988 * @param fpp the new frames per pixel
991 TimeAxisViewItem::set_samples_per_pixel (double fpp)
993 samples_per_pixel = fpp;
994 set_position (this->get_position(), this);
995 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
999 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
1001 _width = pixel_width;
1003 manage_name_highlight ();
1005 if (pixel_width < 2.0) {
1007 if (show_vestigial) {
1008 vestigial_frame->show();
1015 if (frame_handle_start) {
1016 frame_handle_start->hide();
1017 frame_handle_end->hide();
1021 vestigial_frame->hide();
1025 frame->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1028 if (frame_handle_start) {
1029 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
1031 * there's less than GRAB_HANDLE_WIDTH of the region between
1032 * the right-hand end of frame_handle_start and the left-hand
1033 * end of frame_handle_end, so disable the handles
1036 frame_handle_start->hide();
1037 frame_handle_end->hide();
1039 frame_handle_start->show();
1040 frame_handle_end->set_x0 (pixel_width + RIGHT_EDGE_SHIFT - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1041 frame_handle_end->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1042 frame_handle_end->show();
1049 TimeAxisViewItem::manage_name_text ()
1051 int visible_name_width;
1057 if (!wide_enough_for_name || !high_enough_for_name) {
1062 if (name_text->text().empty()) {
1066 visible_name_width = name_text_width;
1068 if (visible_name_width > _width - NAME_X_OFFSET) {
1069 visible_name_width = _width - NAME_X_OFFSET;
1072 if (visible_name_width < 1) {
1075 name_text->clamp_width (visible_name_width);
1081 * Callback used to remove this time axis item during the gtk idle loop.
1082 * This is used to avoid deleting the obejct while inside the remove_this_item
1085 * @param item the TimeAxisViewItem to remove.
1086 * @param src the identity of the object that initiated the change.
1089 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1091 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1098 TimeAxisViewItem::set_y (double y)
1100 group->set_y_position (y);
1104 TimeAxisViewItem::parameter_changed (string p)
1106 if (p == "color-regions-using-track-color") {
1108 } else if (p == "timeline-item-gradient-depth") {
1109 set_frame_gradient ();