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);
778 const double black_r = 0.0;
779 const double black_g = 0.0;
780 const double black_b = 0.0;
782 const double white_r = 1.0;
783 const double white_g = 1.0;
784 const double white_b = 1.0;
786 ArdourCanvas::color_to_rgba (fill_color, r, g, b, a);
788 /* Use W3C contrast guideline calculation */
790 double white_contrast = (max (r, white_r) - min (r, white_r)) +
791 (max (g, white_g) - min (g, white_g)) +
792 (max (b, white_b) - min (b, white_b));
794 double black_contrast = (max (r, black_r) - min (r, black_r)) +
795 (max (g, black_g) - min (g, black_g)) +
796 (max (b, black_b) - min (b, black_b));
798 if (white_contrast > black_contrast) {
800 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
803 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
809 ArdourCanvas::color_to_hsv (fill_color, h, s, v);
812 /* fill is black, set text to white */
813 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
814 } else if (v == 1.0) {
815 /* fill is white, set text to black */
816 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
819 h = fabs (fmod ((h - 180), 360.0)); /* complementary color */
820 s = 1.0; /* fully saturate */
821 v = 0.9; /* increase lightness/brightness/value */
823 name_text->set_color (ArdourCanvas::hsv_to_color (h, s, v, 1.0));
829 set_trim_handle_colors();
833 TimeAxisViewItem::get_fill_color () const
839 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
844 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
847 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
848 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
859 * Sets the frame color depending on whether this item is selected
862 TimeAxisViewItem::set_frame_color()
870 f = get_fill_color ();
873 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
877 f = UINT_RGBA_CHANGE_A (f, 0);
880 frame->set_fill_color (f);
881 set_frame_gradient ();
885 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
887 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
891 f = UINT_RGBA_CHANGE_A (f, 64);
894 frame->set_outline_color (f);
899 TimeAxisViewItem::set_frame_gradient ()
901 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
902 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
906 ArdourCanvas::Fill::StopList stops;
909 ArdourCanvas::Color f (get_fill_color());
911 /* need to get alpha value */
912 ArdourCanvas::color_to_rgba (f, r, g, b, a);
914 stops.push_back (std::make_pair (0.0, f));
916 /* now a darker version */
918 ArdourCanvas::color_to_hsv (f, h, s, v);
920 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
922 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
923 stops.push_back (std::make_pair (1.0, darker));
925 frame->set_gradient (stops, true);
929 * Set the colors of the start and end trim handle depending on object state
932 TimeAxisViewItem::set_trim_handle_colors()
935 /* Leave them transparent for now */
936 if (frame_handle_start) {
937 frame_handle_start->set_fill_color (0x00000000);
938 frame_handle_end->set_fill_color (0x00000000);
941 if (frame_handle_start) {
942 if (position_locked) {
943 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
944 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
946 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
947 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
954 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
957 case GDK_LEAVE_NOTIFY:
958 /* always hide the handle whenever we leave, no matter what mode */
959 item->set_fill (false);
961 case GDK_ENTER_NOTIFY:
962 if (trackview.editor().effective_mouse_mode() == Editing::MouseObject &&
963 !trackview.editor().internal_editing()) {
964 /* never set this to be visible in internal
965 edit mode. Note, however, that we do need to
966 undo visibility (LEAVE_NOTIFY case above) no
967 matter what the mode is.
969 item->set_fill (true);
978 /** @return the frames per pixel */
980 TimeAxisViewItem::get_samples_per_pixel () const
982 return samples_per_pixel;
985 /** Set the frames per pixel of this item.
986 * This item is used to determine the relative visual size and position of this item
987 * based upon its duration and start value.
989 * @param fpp the new frames per pixel
992 TimeAxisViewItem::set_samples_per_pixel (double fpp)
994 samples_per_pixel = fpp;
995 set_position (this->get_position(), this);
996 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
1000 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
1002 _width = pixel_width;
1004 manage_name_highlight ();
1006 if (pixel_width < 2.0) {
1008 if (show_vestigial) {
1009 vestigial_frame->show();
1016 if (frame_handle_start) {
1017 frame_handle_start->hide();
1018 frame_handle_end->hide();
1022 vestigial_frame->hide();
1026 frame->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1029 if (frame_handle_start) {
1030 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
1032 * there's less than GRAB_HANDLE_WIDTH of the region between
1033 * the right-hand end of frame_handle_start and the left-hand
1034 * end of frame_handle_end, so disable the handles
1037 frame_handle_start->hide();
1038 frame_handle_end->hide();
1040 frame_handle_start->show();
1041 frame_handle_end->set_x0 (pixel_width + RIGHT_EDGE_SHIFT - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1042 frame_handle_end->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1043 frame_handle_end->show();
1050 TimeAxisViewItem::manage_name_text ()
1052 int visible_name_width;
1058 if (!wide_enough_for_name || !high_enough_for_name) {
1063 if (name_text->text().empty()) {
1067 visible_name_width = name_text_width;
1069 if (visible_name_width > _width - NAME_X_OFFSET) {
1070 visible_name_width = _width - NAME_X_OFFSET;
1073 if (visible_name_width < 1) {
1076 name_text->clamp_width (visible_name_width);
1082 * Callback used to remove this time axis item during the gtk idle loop.
1083 * This is used to avoid deleting the obejct while inside the remove_this_item
1086 * @param item the TimeAxisViewItem to remove.
1087 * @param src the identity of the object that initiated the change.
1090 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1092 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1099 TimeAxisViewItem::set_y (double y)
1101 group->set_y_position (y);
1105 TimeAxisViewItem::parameter_changed (string p)
1107 if (p == "color-regions-using-track-color") {
1109 } else if (p == "timeline-item-gradient-depth") {
1110 set_frame_gradient ();