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 */
92 /* Ardour: Y_OFFSET is measured from bottom of the time axis view item.
93 TRX: Y_OFFSET is measured from the top of the time axis view item.
95 if (Config->get_show_name_highlight()) {
97 NAME_HIGHLIGHT_SIZE = 0;
99 NAME_Y_OFFSET = height + 1;
100 NAME_HIGHLIGHT_SIZE = height + 2;
102 NAME_HIGHLIGHT_THRESH = NAME_HIGHLIGHT_SIZE * 3;
106 * Construct a new TimeAxisViewItem.
108 * @param it_name the unique name of this item
109 * @param parent the parent canvas group
110 * @param tv the TimeAxisView we are going to be added to
111 * @param spu samples per unit
113 * @param start the start point of this item
114 * @param duration the duration of this item
115 * @param recording true if this is a recording region view
116 * @param automation true if this is an automation region view
118 TimeAxisViewItem::TimeAxisViewItem(
119 const string & it_name, ArdourCanvas::Group& parent, TimeAxisView& tv, double spu, Gdk::Color const & base_color,
120 framepos_t start, framecnt_t duration, bool recording, bool automation, Visibility vis
123 , frame_position (-1)
124 , item_name (it_name)
126 , _recregion (recording)
127 , _automation (automation)
131 init (&parent, spu, base_color, start, duration, vis, true, true);
134 TimeAxisViewItem::TimeAxisViewItem (const TimeAxisViewItem& other)
137 , PBD::ScopedConnectionList()
138 , trackview (other.trackview)
139 , frame_position (-1)
140 , item_name (other.item_name)
142 , _recregion (other._recregion)
143 , _automation (other._automation)
144 , _dragging (other._dragging)
151 UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
152 c.set_rgb_p (r/255.0, g/255.0, b/255.0);
154 /* share the other's parent, but still create a new group */
156 ArdourCanvas::Group* parent = other.group->parent();
158 _selected = other._selected;
160 init (parent, other.samples_per_pixel, c, other.frame_position,
161 other.item_duration, other.visibility, other.wide_enough_for_name, other.high_enough_for_name);
165 TimeAxisViewItem::init (ArdourCanvas::Group* parent, double fpp, Gdk::Color const & base_color,
166 framepos_t start, framepos_t duration, Visibility vis,
167 bool wide, bool high)
169 group = new ArdourCanvas::Group (parent);
170 CANVAS_DEBUG_NAME (group, string_compose ("TAVI group for %1", get_item_name()));
171 group->Event.connect (sigc::mem_fun (*this, &TimeAxisViewItem::canvas_group_event));
173 samples_per_pixel = fpp;
174 frame_position = start;
175 item_duration = duration;
176 name_connected = false;
178 position_locked = false;
179 max_item_duration = ARDOUR::max_framepos;
180 min_item_duration = 0;
181 show_vestigial = true;
186 wide_enough_for_name = wide;
187 high_enough_for_name = high;
191 warning << "Time Axis Item Duration == 0" << endl;
194 vestigial_frame = new ArdourCanvas::Rectangle (group, ArdourCanvas::Rect (0.0, 1.0, 2.0, trackview.current_height()));
195 CANVAS_DEBUG_NAME (vestigial_frame, string_compose ("vestigial frame for %1", get_item_name()));
196 vestigial_frame->hide ();
197 vestigial_frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
198 vestigial_frame->set_fill_color (ARDOUR_UI::config()->get_canvasvar_VestigialFrame());
200 if (visibility & ShowFrame) {
201 frame = new ArdourCanvas::Rectangle (group,
202 ArdourCanvas::Rect (0.0, 0.0,
203 trackview.editor().sample_to_pixel(duration) + RIGHT_EDGE_SHIFT,
204 trackview.current_height() - 1.0));
206 CANVAS_DEBUG_NAME (frame, string_compose ("frame for %1", get_item_name()));
208 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::LEFT|ArdourCanvas::Rectangle::RIGHT));
211 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RecordingRect());
213 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame());
216 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::RIGHT|ArdourCanvas::Rectangle::LEFT));
223 if (Config->get_show_name_highlight() && (visibility & ShowNameHighlight)) {
228 if (visibility & FullWidthNameHighlight) {
230 width = trackview.editor().sample_to_pixel(item_duration) + RIGHT_EDGE_SHIFT;
233 width = trackview.editor().sample_to_pixel(item_duration) - 2.0 + RIGHT_EDGE_SHIFT;
236 name_highlight = new ArdourCanvas::Rectangle (group,
237 ArdourCanvas::Rect (start,
238 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
239 width - 2.0 + RIGHT_EDGE_SHIFT,
240 trackview.current_height() - 1.0));
241 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
242 name_highlight->set_data ("timeaxisviewitem", this);
243 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
244 name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
250 if (visibility & ShowNameText) {
251 name_text = new ArdourCanvas::Text (group);
252 CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
253 if (Config->get_show_name_highlight()) {
254 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, NAME_Y_OFFSET));
256 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
258 name_text->set_font_description (NAME_FONT);
263 /* create our grab handles used for trimming/duration etc */
264 if (!_recregion && !_automation) {
265 double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
266 double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
268 frame_handle_start = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), true);
269 CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
270 frame_handle_start->set_outline (false);
271 frame_handle_start->set_fill (false);
272 frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
274 frame_handle_end = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), false);
275 CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
276 frame_handle_end->set_outline (false);
277 frame_handle_end->set_fill (false);
278 frame_handle_end->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_end));
280 frame_handle_start = frame_handle_end = 0;
283 set_color (base_color);
285 set_duration (item_duration, this);
286 set_position (start, this);
288 Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&TimeAxisViewItem::parameter_changed, this, _1), gui_context ());
289 ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &TimeAxisViewItem::parameter_changed));
292 TimeAxisViewItem::~TimeAxisViewItem()
298 TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
304 TimeAxisViewItem::hide_rect ()
306 rect_visible = false;
309 if (name_highlight) {
310 name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0));
311 name_highlight->set_fill_color (UINT_RGBA_CHANGE_A (fill_color, 64));
316 TimeAxisViewItem::show_rect ()
321 if (name_highlight) {
322 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
323 name_highlight->set_fill_color (fill_color);
328 * Set the position of this item on the timeline.
330 * @param pos the new position
331 * @param src the identity of the object that initiated the change
332 * @return true on success
336 TimeAxisViewItem::set_position(framepos_t pos, void* src, double* delta)
338 if (position_locked) {
342 frame_position = pos;
344 double new_unit_pos = trackview.editor().sample_to_pixel (pos);
347 (*delta) = new_unit_pos - group->position().x;
352 if (new_unit_pos == group->position().x) {
357 group->set_x_position (new_unit_pos);
359 PositionChanged (frame_position, src); /* EMIT_SIGNAL */
364 /** @return position of this item on the timeline */
366 TimeAxisViewItem::get_position() const
368 return frame_position;
372 * Set the duration of this item.
374 * @param dur the new duration of this item
375 * @param src the identity of the object that initiated the change
376 * @return true on success
380 TimeAxisViewItem::set_duration (framecnt_t dur, void* src)
382 if ((dur > max_item_duration) || (dur < min_item_duration)) {
383 warning << string_compose (
384 P_("new duration %1 frame is out of bounds for %2", "new duration of %1 frames is out of bounds for %2", dur),
385 get_item_name(), dur)
396 reset_width_dependent_items (trackview.editor().sample_to_pixel (dur));
398 DurationChanged (dur, src); /* EMIT_SIGNAL */
402 /** @return duration of this item */
404 TimeAxisViewItem::get_duration() const
406 return item_duration;
410 * Set the maximum duration that this item can have.
412 * @param dur the new maximum duration
413 * @param src the identity of the object that initiated the change
416 TimeAxisViewItem::set_max_duration(framecnt_t dur, void* src)
418 max_item_duration = dur;
419 MaxDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
422 /** @return the maximum duration that this item may have */
424 TimeAxisViewItem::get_max_duration() const
426 return max_item_duration;
430 * Set the minimum duration that this item may have.
432 * @param the minimum duration that this item may be set to
433 * @param src the identity of the object that initiated the change
436 TimeAxisViewItem::set_min_duration(framecnt_t dur, void* src)
438 min_item_duration = dur;
439 MinDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
442 /** @return the minimum duration that this item mey have */
444 TimeAxisViewItem::get_min_duration() const
446 return min_item_duration;
450 * Set whether this item is locked to its current position.
451 * Locked items cannot be moved until the item is unlocked again.
453 * @param yn true to lock this item to its current position
454 * @param src the identity of the object that initiated the change
457 TimeAxisViewItem::set_position_locked(bool yn, void* src)
459 position_locked = yn;
460 set_trim_handle_colors();
461 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
464 /** @return true if this item is locked to its current position */
466 TimeAxisViewItem::get_position_locked() const
468 return position_locked;
472 * Set whether the maximum duration constraint is active.
474 * @param active set true to enforce the max duration constraint
475 * @param src the identity of the object that initiated the change
478 TimeAxisViewItem::set_max_duration_active (bool active, void* /*src*/)
480 max_duration_active = active;
483 /** @return true if the maximum duration constraint is active */
485 TimeAxisViewItem::get_max_duration_active() const
487 return max_duration_active;
491 * Set whether the minimum duration constraint is active.
493 * @param active set true to enforce the min duration constraint
494 * @param src the identity of the object that initiated the change
498 TimeAxisViewItem::set_min_duration_active (bool active, void* /*src*/)
500 min_duration_active = active;
503 /** @return true if the maximum duration constraint is active */
505 TimeAxisViewItem::get_min_duration_active() const
507 return min_duration_active;
511 * Set the name of this item.
513 * @param new_name the new name of this item
514 * @param src the identity of the object that initiated the change
518 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
520 if (new_name != item_name) {
521 std::string temp_name = item_name;
522 item_name = new_name;
523 NameChanged (item_name, temp_name, src); /* EMIT_SIGNAL */
527 /** @return the name of this item */
529 TimeAxisViewItem::get_item_name() const
535 * Set selection status.
537 * @param yn true if this item is currently selected
540 TimeAxisViewItem::set_selected(bool yn)
542 if (_selected != yn) {
543 Selectable::set_selected (yn);
548 /** @return the TimeAxisView that this item is on */
550 TimeAxisViewItem::get_time_axis_view () const
556 * Set the displayed item text.
557 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item.
559 * @param new_name the new name text to display
563 TimeAxisViewItem::set_name_text(const string& new_name)
569 name_text_width = pixel_width (new_name, NAME_FONT) + 2;
570 name_text->set (new_name);
575 * Set the height of this item.
577 * @param h new height
580 TimeAxisViewItem::set_height (double height)
584 manage_name_highlight ();
586 if (visibility & ShowNameText) {
587 if (Config->get_show_name_highlight()) {
588 name_text->set_y_position (NAME_Y_OFFSET);
590 name_text->set_y_position (height - NAME_Y_OFFSET);
595 frame->set_y1 (height);
596 if (frame_handle_start) {
597 frame_handle_start->set_y1 (height);
598 frame_handle_end->set_y1 (height);
602 vestigial_frame->set_y1 (height - 1.0);
608 TimeAxisViewItem::manage_name_highlight ()
610 if (!name_highlight) {
614 if (_height < NAME_HIGHLIGHT_THRESH) {
615 high_enough_for_name = false;
617 high_enough_for_name = true;
621 wide_enough_for_name = false;
623 wide_enough_for_name = true;
626 if (name_highlight && wide_enough_for_name && high_enough_for_name) {
628 name_highlight->show();
629 name_highlight->set (ArdourCanvas::Rect (0.0, (double) _height - NAME_HIGHLIGHT_SIZE, _width+RIGHT_EDGE_SHIFT, (double) _height - 1.0));
632 name_highlight->hide();
639 TimeAxisViewItem::set_color (Gdk::Color const & base_color)
641 compute_colors (base_color);
646 TimeAxisViewItem::get_canvas_frame()
652 TimeAxisViewItem::get_canvas_group()
658 TimeAxisViewItem::get_name_highlight()
660 return name_highlight;
664 * Calculate some contrasting color for displaying various parts of this item, based upon the base color.
666 * @param color the base color of the item
669 TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
671 unsigned char radius;
676 /* FILL: this is simple */
677 r = base_color.get_red()/256;
678 g = base_color.get_green()/256;
679 b = base_color.get_blue()/256;
680 fill_color = RGBA_TO_UINT(r,g,b,160);
683 if the overall saturation is strong, make the minor colors light.
684 if its weak, make them dark.
686 we do this by moving an equal distance to the other side of the
687 central circle in the color wheel from where we started.
690 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f));
691 minor_shift = 125 - radius;
693 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
695 r = base_color.get_red()/256;
696 g = base_color.get_green()/256;
697 b = base_color.get_blue()/256;
703 /* red sector => green */
708 /* green sector => blue */
716 /* blue sector => red */
721 /* green sector => blue */
730 label_color = RGBA_TO_UINT(r,g,b,255);
731 r = (base_color.get_red()/256) + 127;
732 g = (base_color.get_green()/256) + 127;
733 b = (base_color.get_blue()/256) + 127;
735 label_color = RGBA_TO_UINT(r,g,b,255);
737 /* XXX can we do better than this ? */
741 //frame_color_r = 192;
742 //frame_color_g = 192;
743 //frame_color_b = 194;
745 //selected_frame_color_r = 182;
746 //selected_frame_color_g = 145;
747 //selected_frame_color_b = 168;
749 //handle_color_r = 25;
750 //handle_color_g = 0;
751 //handle_color_b = 255;
752 //lock_handle_color_r = 235;
753 //lock_handle_color_g = 16;
754 //lock_handle_color_b = 16;
758 * Convenience method to set the various canvas item colors
761 TimeAxisViewItem::set_colors()
765 if (name_highlight) {
766 name_highlight->set_fill_color (fill_color);
772 const double black_r = 0.0;
773 const double black_g = 0.0;
774 const double black_b = 0.0;
776 const double white_r = 1.0;
777 const double white_g = 1.0;
778 const double white_b = 1.0;
780 ArdourCanvas::color_to_rgba (fill_color, r, g, b, a);
782 /* Use W3C contrast guideline calculation */
784 double white_contrast = (max (r, white_r) - min (r, white_r)) +
785 (max (g, white_g) - min (g, white_g)) +
786 (max (b, white_b) - min (b, white_b));
788 double black_contrast = (max (r, black_r) - min (r, black_r)) +
789 (max (g, black_g) - min (g, black_g)) +
790 (max (b, black_b) - min (b, black_b));
792 if (white_contrast > black_contrast) {
794 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
797 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
803 ArdourCanvas::color_to_hsv (fill_color, h, s, v);
806 /* fill is black, set text to white */
807 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
808 } else if (v == 1.0) {
809 /* fill is white, set text to black */
810 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
813 h = fabs (fmod ((h - 180), 360.0)); /* complementary color */
814 s = 1.0; /* fully saturate */
815 v = 0.9; /* increase lightness/brightness/value */
817 name_text->set_color (ArdourCanvas::hsv_to_color (h, s, v, 1.0));
823 set_trim_handle_colors();
827 TimeAxisViewItem::get_fill_color () const
833 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
838 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
841 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
842 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
853 * Sets the frame color depending on whether this item is selected
856 TimeAxisViewItem::set_frame_color()
864 f = get_fill_color ();
867 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
871 f = UINT_RGBA_CHANGE_A (f, 0);
874 frame->set_fill_color (f);
875 set_frame_gradient ();
879 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
881 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
885 f = UINT_RGBA_CHANGE_A (f, 64);
888 frame->set_outline_color (f);
893 TimeAxisViewItem::set_frame_gradient ()
895 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
896 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
900 ArdourCanvas::Fill::StopList stops;
903 ArdourCanvas::Color f (get_fill_color());
905 /* need to get alpha value */
906 ArdourCanvas::color_to_rgba (f, r, g, b, a);
908 stops.push_back (std::make_pair (0.0, f));
910 /* now a darker version */
912 ArdourCanvas::color_to_hsv (f, h, s, v);
914 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
916 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
917 stops.push_back (std::make_pair (1.0, darker));
919 frame->set_gradient (stops, true);
923 * Set the colors of the start and end trim handle depending on object state
926 TimeAxisViewItem::set_trim_handle_colors()
929 /* Leave them transparent for now */
930 if (frame_handle_start) {
931 frame_handle_start->set_fill_color (0x00000000);
932 frame_handle_end->set_fill_color (0x00000000);
935 if (frame_handle_start) {
936 if (position_locked) {
937 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
938 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
940 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
941 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
948 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
951 case GDK_LEAVE_NOTIFY:
952 /* always hide the handle whenever we leave, no matter what mode */
953 item->set_fill (false);
955 case GDK_ENTER_NOTIFY:
956 if (trackview.editor().effective_mouse_mode() == Editing::MouseObject &&
957 !trackview.editor().internal_editing()) {
958 /* never set this to be visible in internal
959 edit mode. Note, however, that we do need to
960 undo visibility (LEAVE_NOTIFY case above) no
961 matter what the mode is.
963 item->set_fill (true);
972 /** @return the frames per pixel */
974 TimeAxisViewItem::get_samples_per_pixel () const
976 return samples_per_pixel;
979 /** Set the frames per pixel of this item.
980 * This item is used to determine the relative visual size and position of this item
981 * based upon its duration and start value.
983 * @param fpp the new frames per pixel
986 TimeAxisViewItem::set_samples_per_pixel (double fpp)
988 samples_per_pixel = fpp;
989 set_position (this->get_position(), this);
990 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
994 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
996 _width = pixel_width;
998 manage_name_highlight ();
1000 if (pixel_width < 2.0) {
1002 if (show_vestigial) {
1003 vestigial_frame->show();
1010 if (frame_handle_start) {
1011 frame_handle_start->hide();
1012 frame_handle_end->hide();
1016 vestigial_frame->hide();
1020 frame->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1023 if (frame_handle_start) {
1024 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
1026 * there's less than GRAB_HANDLE_WIDTH of the region between
1027 * the right-hand end of frame_handle_start and the left-hand
1028 * end of frame_handle_end, so disable the handles
1031 frame_handle_start->hide();
1032 frame_handle_end->hide();
1034 frame_handle_start->show();
1035 frame_handle_end->set_x0 (pixel_width + RIGHT_EDGE_SHIFT - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1036 frame_handle_end->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1037 frame_handle_end->show();
1044 TimeAxisViewItem::manage_name_text ()
1046 int visible_name_width;
1052 if (!wide_enough_for_name || !high_enough_for_name) {
1057 if (name_text->text().empty()) {
1061 visible_name_width = name_text_width;
1063 if (visible_name_width > _width - NAME_X_OFFSET) {
1064 visible_name_width = _width - NAME_X_OFFSET;
1067 if (visible_name_width < 1) {
1070 name_text->clamp_width (visible_name_width);
1076 * Callback used to remove this time axis item during the gtk idle loop.
1077 * This is used to avoid deleting the obejct while inside the remove_this_item
1080 * @param item the TimeAxisViewItem to remove.
1081 * @param src the identity of the object that initiated the change.
1084 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1086 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1093 TimeAxisViewItem::set_y (double y)
1095 group->set_y_position (y);
1099 TimeAxisViewItem::parameter_changed (string p)
1101 if (p == "color-regions-using-track-color") {
1103 } else if (p == "timeline-item-gradient-depth") {
1104 set_frame_gradient ();