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 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::LEFT|ArdourCanvas::Rectangle::RIGHT));
215 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_RecordingRect());
217 frame->set_outline_color (ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame());
220 frame->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::RIGHT|ArdourCanvas::Rectangle::LEFT));
227 if (Config->get_show_name_highlight() && (visibility & ShowNameHighlight)) {
232 if (visibility & FullWidthNameHighlight) {
234 width = trackview.editor().sample_to_pixel(item_duration) + RIGHT_EDGE_SHIFT;
237 width = trackview.editor().sample_to_pixel(item_duration) - 2.0 + RIGHT_EDGE_SHIFT;
240 name_highlight = new ArdourCanvas::Rectangle (group,
241 ArdourCanvas::Rect (start,
242 trackview.current_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE,
243 width - 2.0 + RIGHT_EDGE_SHIFT,
244 trackview.current_height() - 1.0));
245 CANVAS_DEBUG_NAME (name_highlight, string_compose ("name highlight for %1", get_item_name()));
246 name_highlight->set_data ("timeaxisviewitem", this);
247 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
248 name_highlight->set_outline_color (RGBA_TO_UINT (0,0,0,255));
254 if (visibility & ShowNameText) {
255 name_text = new ArdourCanvas::Text (group);
256 CANVAS_DEBUG_NAME (name_text, string_compose ("name text for %1", get_item_name()));
257 if (Config->get_show_name_highlight()) {
258 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, trackview.current_height() - NAME_Y_OFFSET));
260 name_text->set_position (ArdourCanvas::Duple (NAME_X_OFFSET, NAME_Y_OFFSET));
262 name_text->set_font_description (NAME_FONT);
267 /* create our grab handles used for trimming/duration etc */
268 if (!_recregion && !_automation) {
269 double top = TimeAxisViewItem::GRAB_HANDLE_TOP;
270 double width = TimeAxisViewItem::GRAB_HANDLE_WIDTH;
272 frame_handle_start = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), true);
273 CANVAS_DEBUG_NAME (frame_handle_start, "TAVI frame handle start");
274 frame_handle_start->set_outline (false);
275 frame_handle_start->set_fill (false);
276 frame_handle_start->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_start));
278 frame_handle_end = new ArdourCanvas::DragHandle (group, ArdourCanvas::Rect (0.0, top, width, trackview.current_height()), false);
279 CANVAS_DEBUG_NAME (frame_handle_end, "TAVI frame handle end");
280 frame_handle_end->set_outline (false);
281 frame_handle_end->set_fill (false);
282 frame_handle_end->Event.connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisViewItem::frame_handle_crossing), frame_handle_end));
284 frame_handle_start = frame_handle_end = 0;
287 set_color (base_color);
289 set_duration (item_duration, this);
290 set_position (start, this);
292 Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&TimeAxisViewItem::parameter_changed, this, _1), gui_context ());
293 ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &TimeAxisViewItem::parameter_changed));
296 TimeAxisViewItem::~TimeAxisViewItem()
302 TimeAxisViewItem::canvas_group_event (GdkEvent* /*ev*/)
308 TimeAxisViewItem::hide_rect ()
310 rect_visible = false;
313 if (name_highlight) {
314 name_highlight->set_outline_what (ArdourCanvas::Rectangle::What (0));
315 name_highlight->set_fill_color (UINT_RGBA_CHANGE_A (fill_color, 64));
320 TimeAxisViewItem::show_rect ()
325 if (name_highlight) {
326 name_highlight->set_outline_what (ArdourCanvas::Rectangle::TOP);
327 name_highlight->set_fill_color (fill_color);
332 * Set the position of this item on the timeline.
334 * @param pos the new position
335 * @param src the identity of the object that initiated the change
336 * @return true on success
340 TimeAxisViewItem::set_position(framepos_t pos, void* src, double* delta)
342 if (position_locked) {
346 frame_position = pos;
348 double new_unit_pos = trackview.editor().sample_to_pixel (pos);
351 (*delta) = new_unit_pos - group->position().x;
356 if (new_unit_pos == group->position().x) {
361 group->set_x_position (new_unit_pos);
363 PositionChanged (frame_position, src); /* EMIT_SIGNAL */
368 /** @return position of this item on the timeline */
370 TimeAxisViewItem::get_position() const
372 return frame_position;
376 * Set the duration of this item.
378 * @param dur the new duration of this item
379 * @param src the identity of the object that initiated the change
380 * @return true on success
384 TimeAxisViewItem::set_duration (framecnt_t dur, void* src)
386 if ((dur > max_item_duration) || (dur < min_item_duration)) {
387 warning << string_compose (
388 P_("new duration %1 frame is out of bounds for %2", "new duration of %1 frames is out of bounds for %2", dur),
389 get_item_name(), dur)
400 reset_width_dependent_items (trackview.editor().sample_to_pixel (dur));
402 DurationChanged (dur, src); /* EMIT_SIGNAL */
406 /** @return duration of this item */
408 TimeAxisViewItem::get_duration() const
410 return item_duration;
414 * Set the maximum duration that this item can have.
416 * @param dur the new maximum duration
417 * @param src the identity of the object that initiated the change
420 TimeAxisViewItem::set_max_duration(framecnt_t dur, void* src)
422 max_item_duration = dur;
423 MaxDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
426 /** @return the maximum duration that this item may have */
428 TimeAxisViewItem::get_max_duration() const
430 return max_item_duration;
434 * Set the minimum duration that this item may have.
436 * @param the minimum duration that this item may be set to
437 * @param src the identity of the object that initiated the change
440 TimeAxisViewItem::set_min_duration(framecnt_t dur, void* src)
442 min_item_duration = dur;
443 MinDurationChanged(max_item_duration, src); /* EMIT_SIGNAL */
446 /** @return the minimum duration that this item mey have */
448 TimeAxisViewItem::get_min_duration() const
450 return min_item_duration;
454 * Set whether this item is locked to its current position.
455 * Locked items cannot be moved until the item is unlocked again.
457 * @param yn true to lock this item to its current position
458 * @param src the identity of the object that initiated the change
461 TimeAxisViewItem::set_position_locked(bool yn, void* src)
463 position_locked = yn;
464 set_trim_handle_colors();
465 PositionLockChanged (position_locked, src); /* EMIT_SIGNAL */
468 /** @return true if this item is locked to its current position */
470 TimeAxisViewItem::get_position_locked() const
472 return position_locked;
476 * Set whether the maximum duration constraint is active.
478 * @param active set true to enforce the max duration constraint
479 * @param src the identity of the object that initiated the change
482 TimeAxisViewItem::set_max_duration_active (bool active, void* /*src*/)
484 max_duration_active = active;
487 /** @return true if the maximum duration constraint is active */
489 TimeAxisViewItem::get_max_duration_active() const
491 return max_duration_active;
495 * Set whether the minimum duration constraint is active.
497 * @param active set true to enforce the min duration constraint
498 * @param src the identity of the object that initiated the change
502 TimeAxisViewItem::set_min_duration_active (bool active, void* /*src*/)
504 min_duration_active = active;
507 /** @return true if the maximum duration constraint is active */
509 TimeAxisViewItem::get_min_duration_active() const
511 return min_duration_active;
515 * Set the name of this item.
517 * @param new_name the new name of this item
518 * @param src the identity of the object that initiated the change
522 TimeAxisViewItem::set_item_name(std::string new_name, void* src)
524 if (new_name != item_name) {
525 std::string temp_name = item_name;
526 item_name = new_name;
527 NameChanged (item_name, temp_name, src); /* EMIT_SIGNAL */
531 /** @return the name of this item */
533 TimeAxisViewItem::get_item_name() const
539 * Set selection status.
541 * @param yn true if this item is currently selected
544 TimeAxisViewItem::set_selected(bool yn)
546 if (_selected != yn) {
547 Selectable::set_selected (yn);
552 /** @return the TimeAxisView that this item is on */
554 TimeAxisViewItem::get_time_axis_view () const
560 * Set the displayed item text.
561 * This item is the visual text name displayed on the canvas item, this can be different to the name of the item.
563 * @param new_name the new name text to display
567 TimeAxisViewItem::set_name_text(const string& new_name)
573 name_text_width = pixel_width (new_name, NAME_FONT) + 2;
574 name_text->set (new_name);
579 * Set the height of this item.
581 * @param h new height
584 TimeAxisViewItem::set_height (double height)
588 manage_name_highlight ();
590 if (visibility & ShowNameText) {
591 if (Config->get_show_name_highlight()) {
592 name_text->set_y_position (height - NAME_Y_OFFSET);
594 name_text->set_y_position (NAME_Y_OFFSET);
599 frame->set_y1 (height);
600 if (frame_handle_start) {
601 frame_handle_start->set_y1 (height);
602 frame_handle_end->set_y1 (height);
606 vestigial_frame->set_y1 (height - 1.0);
612 TimeAxisViewItem::manage_name_highlight ()
614 if (!name_highlight) {
618 if (_height < NAME_HIGHLIGHT_THRESH) {
619 high_enough_for_name = false;
621 high_enough_for_name = true;
625 wide_enough_for_name = false;
627 wide_enough_for_name = true;
630 if (name_highlight && wide_enough_for_name && high_enough_for_name) {
632 name_highlight->show();
633 name_highlight->set (ArdourCanvas::Rect (0.0, (double) _height - NAME_HIGHLIGHT_SIZE, _width+RIGHT_EDGE_SHIFT, (double) _height - 1.0));
636 name_highlight->hide();
643 TimeAxisViewItem::set_color (Gdk::Color const & base_color)
645 compute_colors (base_color);
650 TimeAxisViewItem::get_canvas_frame()
656 TimeAxisViewItem::get_canvas_group()
662 TimeAxisViewItem::get_name_highlight()
664 return name_highlight;
668 * Calculate some contrasting color for displaying various parts of this item, based upon the base color.
670 * @param color the base color of the item
673 TimeAxisViewItem::compute_colors (Gdk::Color const & base_color)
675 unsigned char radius;
680 /* FILL: this is simple */
681 r = base_color.get_red()/256;
682 g = base_color.get_green()/256;
683 b = base_color.get_blue()/256;
684 fill_color = RGBA_TO_UINT(r,g,b,160);
687 if the overall saturation is strong, make the minor colors light.
688 if its weak, make them dark.
690 we do this by moving an equal distance to the other side of the
691 central circle in the color wheel from where we started.
694 radius = (unsigned char) rint (floor (sqrt (static_cast<double>(r*r + g*g + b+b))/3.0f));
695 minor_shift = 125 - radius;
697 /* LABEL: rotate around color wheel by 120 degrees anti-clockwise */
699 r = base_color.get_red()/256;
700 g = base_color.get_green()/256;
701 b = base_color.get_blue()/256;
707 /* red sector => green */
712 /* green sector => blue */
720 /* blue sector => red */
725 /* green sector => blue */
734 label_color = RGBA_TO_UINT(r,g,b,255);
735 r = (base_color.get_red()/256) + 127;
736 g = (base_color.get_green()/256) + 127;
737 b = (base_color.get_blue()/256) + 127;
739 label_color = RGBA_TO_UINT(r,g,b,255);
741 /* XXX can we do better than this ? */
745 //frame_color_r = 192;
746 //frame_color_g = 192;
747 //frame_color_b = 194;
749 //selected_frame_color_r = 182;
750 //selected_frame_color_g = 145;
751 //selected_frame_color_b = 168;
753 //handle_color_r = 25;
754 //handle_color_g = 0;
755 //handle_color_b = 255;
756 //lock_handle_color_r = 235;
757 //lock_handle_color_g = 16;
758 //lock_handle_color_b = 16;
762 * Convenience method to set the various canvas item colors
765 TimeAxisViewItem::set_colors()
769 if (name_highlight) {
770 name_highlight->set_fill_color (fill_color);
776 const double black_r = 0.0;
777 const double black_g = 0.0;
778 const double black_b = 0.0;
780 const double white_r = 1.0;
781 const double white_g = 1.0;
782 const double white_b = 1.0;
784 ArdourCanvas::color_to_rgba (fill_color, r, g, b, a);
786 /* Use W3C contrast guideline calculation */
788 double white_contrast = (max (r, white_r) - min (r, white_r)) +
789 (max (g, white_g) - min (g, white_g)) +
790 (max (b, white_b) - min (b, white_b));
792 double black_contrast = (max (r, black_r) - min (r, black_r)) +
793 (max (g, black_g) - min (g, black_g)) +
794 (max (b, black_b) - min (b, black_b));
796 if (white_contrast > black_contrast) {
798 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
801 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
807 ArdourCanvas::color_to_hsv (fill_color, h, s, v);
810 /* fill is black, set text to white */
811 name_text->set_color (ArdourCanvas::rgba_to_color (1.0, 1.0, 1.0, 1.0));
812 } else if (v == 1.0) {
813 /* fill is white, set text to black */
814 name_text->set_color (ArdourCanvas::rgba_to_color (0.0, 0.0, 0.0, 1.0));
817 h = fabs (fmod ((h - 180), 360.0)); /* complementary color */
818 s = 1.0; /* fully saturate */
819 v = 0.9; /* increase lightness/brightness/value */
821 name_text->set_color (ArdourCanvas::hsv_to_color (h, s, v, 1.0));
827 set_trim_handle_colors();
831 TimeAxisViewItem::get_fill_color () const
837 f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
842 f = ARDOUR_UI::config()->get_canvasvar_RecordingRect();
845 if (high_enough_for_name && !ARDOUR_UI::config()->get_color_regions_using_track_color()) {
846 f = ARDOUR_UI::config()->get_canvasvar_FrameBase();
857 * Sets the frame color depending on whether this item is selected
860 TimeAxisViewItem::set_frame_color()
868 f = get_fill_color ();
871 f = UINT_RGBA_CHANGE_A (f, fill_opacity);
875 f = UINT_RGBA_CHANGE_A (f, 0);
878 frame->set_fill_color (f);
879 set_frame_gradient ();
883 f = ARDOUR_UI::config()->get_canvasvar_SelectedTimeAxisFrame();
885 f = ARDOUR_UI::config()->get_canvasvar_TimeAxisFrame();
889 f = UINT_RGBA_CHANGE_A (f, 64);
892 frame->set_outline_color (f);
897 TimeAxisViewItem::set_frame_gradient ()
899 if (ARDOUR_UI::config()->get_timeline_item_gradient_depth() == 0.0) {
900 frame->set_gradient (ArdourCanvas::Fill::StopList (), 0);
904 ArdourCanvas::Fill::StopList stops;
907 ArdourCanvas::Color f (get_fill_color());
909 /* need to get alpha value */
910 ArdourCanvas::color_to_rgba (f, r, g, b, a);
912 stops.push_back (std::make_pair (0.0, f));
914 /* now a darker version */
916 ArdourCanvas::color_to_hsv (f, h, s, v);
918 v = min (1.0, v * (1.0 - ARDOUR_UI::config()->get_timeline_item_gradient_depth()));
920 ArdourCanvas::Color darker = ArdourCanvas::hsv_to_color (h, s, v, a);
921 stops.push_back (std::make_pair (1.0, darker));
923 frame->set_gradient (stops, true);
927 * Set the colors of the start and end trim handle depending on object state
930 TimeAxisViewItem::set_trim_handle_colors()
933 /* Leave them transparent for now */
934 if (frame_handle_start) {
935 frame_handle_start->set_fill_color (0x00000000);
936 frame_handle_end->set_fill_color (0x00000000);
939 if (frame_handle_start) {
940 if (position_locked) {
941 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
942 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandleLocked());
944 frame_handle_start->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
945 frame_handle_end->set_fill_color (ARDOUR_UI::config()->get_canvasvar_TrimHandle());
952 TimeAxisViewItem::frame_handle_crossing (GdkEvent* ev, ArdourCanvas::Rectangle* item)
955 case GDK_LEAVE_NOTIFY:
956 /* always hide the handle whenever we leave, no matter what mode */
957 item->set_fill (false);
959 case GDK_ENTER_NOTIFY:
960 if (trackview.editor().effective_mouse_mode() == Editing::MouseObject &&
961 !trackview.editor().internal_editing()) {
962 /* never set this to be visible in internal
963 edit mode. Note, however, that we do need to
964 undo visibility (LEAVE_NOTIFY case above) no
965 matter what the mode is.
967 item->set_fill (true);
976 /** @return the frames per pixel */
978 TimeAxisViewItem::get_samples_per_pixel () const
980 return samples_per_pixel;
983 /** Set the frames per pixel of this item.
984 * This item is used to determine the relative visual size and position of this item
985 * based upon its duration and start value.
987 * @param fpp the new frames per pixel
990 TimeAxisViewItem::set_samples_per_pixel (double fpp)
992 samples_per_pixel = fpp;
993 set_position (this->get_position(), this);
994 reset_width_dependent_items ((double) get_duration() / samples_per_pixel);
998 TimeAxisViewItem::reset_width_dependent_items (double pixel_width)
1000 _width = pixel_width;
1002 manage_name_highlight ();
1004 if (pixel_width < 2.0) {
1006 if (show_vestigial) {
1007 vestigial_frame->show();
1014 if (frame_handle_start) {
1015 frame_handle_start->hide();
1016 frame_handle_end->hide();
1020 vestigial_frame->hide();
1024 frame->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1027 if (frame_handle_start) {
1028 if (pixel_width < (3 * TimeAxisViewItem::GRAB_HANDLE_WIDTH)) {
1030 * there's less than GRAB_HANDLE_WIDTH of the region between
1031 * the right-hand end of frame_handle_start and the left-hand
1032 * end of frame_handle_end, so disable the handles
1035 frame_handle_start->hide();
1036 frame_handle_end->hide();
1038 frame_handle_start->show();
1039 frame_handle_end->set_x0 (pixel_width + RIGHT_EDGE_SHIFT - (TimeAxisViewItem::GRAB_HANDLE_WIDTH));
1040 frame_handle_end->set_x1 (pixel_width + RIGHT_EDGE_SHIFT);
1041 frame_handle_end->show();
1048 TimeAxisViewItem::manage_name_text ()
1050 int visible_name_width;
1056 if (!wide_enough_for_name || !high_enough_for_name) {
1061 if (name_text->text().empty()) {
1065 visible_name_width = name_text_width;
1067 if (visible_name_width > _width - NAME_X_OFFSET) {
1068 visible_name_width = _width - NAME_X_OFFSET;
1071 if (visible_name_width < 1) {
1074 name_text->clamp_width (visible_name_width);
1080 * Callback used to remove this time axis item during the gtk idle loop.
1081 * This is used to avoid deleting the obejct while inside the remove_this_item
1084 * @param item the TimeAxisViewItem to remove.
1085 * @param src the identity of the object that initiated the change.
1088 TimeAxisViewItem::idle_remove_this_item(TimeAxisViewItem* item, void* src)
1090 item->ItemRemoved (item->get_item_name(), src); /* EMIT_SIGNAL */
1097 TimeAxisViewItem::set_y (double y)
1099 group->set_y_position (y);
1103 TimeAxisViewItem::parameter_changed (string p)
1105 if (p == "color-regions-using-track-color") {
1107 } else if (p == "timeline-item-gradient-depth") {
1108 set_frame_gradient ();