[ardour-users] Experimental patch for layer "stacking"

Carl Hetherington lists at carlh.net
Sun Mar 4 14:54:21 PST 2007


Hi all,

I've been playing with a patch to provide vertical "stacking" of layers on 
tracks.  It works a bit like Cubase's "lanes" mode, whereby the different 
regions on a track are displayed at different y positions rather than 
being overlaid on screen.

It's not at all polished and needs more work (in particular, crossfade 
display is broken), but I just wondered what people thought and whether 
its anything people are interested in seeing.  I find this kind of display 
quite useful in Cubase, especially for editing.

To see it in action, go to a track's View menu and go to the new "Layers 
submenu" and select "Overlaid".

Patch against SVN head is attached, comments welcome.

Cheers

Carl
-------------- next part --------------
Index: gtk2_ardour/region_view.h
===================================================================
--- gtk2_ardour/region_view.h	(revision 1552)
+++ gtk2_ardour/region_view.h	(working copy)
@@ -56,7 +56,7 @@
 	bool is_valid() const    { return valid; }
     void set_valid (bool yn) { valid = yn; }
 
-    virtual void set_height (double) = 0;
+    virtual void set_y_position_and_height (double, double) = 0;
     virtual void set_samples_per_unit (double);
     virtual bool set_duration (nframes_t, void*);
 
@@ -129,7 +129,6 @@
 
     bool     valid; ///< see StreamView::redisplay_diskstream() 
     double  _pixel_width;
-    double  _height;
     bool    in_destructor;
     
     bool             wait_for_data;
Index: gtk2_ardour/audio_time_axis.cc
===================================================================
--- gtk2_ardour/audio_time_axis.cc	(revision 1552)
+++ gtk2_ardour/audio_time_axis.cc	(working copy)
@@ -287,6 +287,17 @@
 	}
 
 	items.push_back (MenuElem (_("Waveform"), *waveform_menu));
+
+	Menu *layers_menu = manage(new Menu);
+	MenuList &layers_items = layers_menu->items();
+	layers_menu->set_name("ArdourContextMenu");
+
+	RadioMenuItem::Group layers_group;
+	
+	layers_items.push_back(RadioMenuElem (layers_group, _("Overlaid"), bind (mem_fun (*this, &AudioTimeAxisView::set_layer_display), Overlaid)));
+	layers_items.push_back(RadioMenuElem (layers_group, _("Stacked"), bind (mem_fun (*this, &AudioTimeAxisView::set_layer_display), Stacked)));
+
+	items.push_back (MenuElem (_("Layers"), *layers_menu));
 }
 
 void
@@ -345,9 +356,19 @@
 	}
 
 	map_frozen ();
-}	
+}
 
 void
+AudioTimeAxisView::set_layer_display (LayerDisplay d)
+{
+	AudioStreamView* asv = audio_view();
+	
+	if (asv) {
+		asv->set_layer_display (d);
+	}
+}
+
+void
 AudioTimeAxisView::add_gain_automation_child ()
 {
 	XMLProperty* prop;
Index: gtk2_ardour/audio_streamview.h
===================================================================
--- gtk2_ardour/audio_streamview.h	(revision 1552)
+++ gtk2_ardour/audio_streamview.h	(working copy)
@@ -63,7 +63,6 @@
 	void set_waveform_scale (WaveformScale);
 	WaveformScale get_waveform_scale () const { return _waveform_scale; }
 
-	int set_height (gdouble h);
 	int set_samples_per_unit (gdouble spp);
 
 	int     set_amplitude_above_axis (gdouble app);
@@ -90,15 +89,16 @@
 
 	void undisplay_diskstream ();
 	void redisplay_diskstream ();
-	void playlist_modified ();
+	void playlist_modified (boost::shared_ptr<ARDOUR::Diskstream>);
 	void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
 
 	void add_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
 	void remove_crossfade (boost::shared_ptr<ARDOUR::Crossfade>);
 
 	void color_handler (ColorID id, uint32_t val);
-	
 
+	void update_content_heights();
+
 	double _amplitude_above_axis;
 	
 	typedef list<CrossfadeView*> CrossfadeViewList;
Index: gtk2_ardour/imageframe_time_axis_group.cc
===================================================================
--- gtk2_ardour/imageframe_time_axis_group.cc	(revision 1552)
+++ gtk2_ardour/imageframe_time_axis_group.cc	(working copy)
@@ -123,15 +123,13 @@
 ImageFrameTimeAxisGroup::set_item_heights(gdouble h)
 {
 	/* limit the values to something sane-ish */
-	if (h < 10.0 || h > 1000.0)
-	{
+	if (h < 10.0 || h > 1000.0) {
 		return(-1) ;
 	}
 
-	// set the heights of all the imaeg frame views within the group
-	for(ImageFrameViewList::const_iterator citer = imageframe_views.begin(); citer != imageframe_views.end(); ++citer)
-	{
-		(*citer)->set_height(h) ;
+	// set the heights of all the image frame views within the group
+	for(ImageFrameViewList::const_iterator citer = imageframe_views.begin(); citer != imageframe_views.end(); ++citer) {
+		(*citer)->set_y_position_and_height(0, h);
 	}
 
 	return(0) ;
Index: gtk2_ardour/region_view.cc
===================================================================
--- gtk2_ardour/region_view.cc	(revision 1552)
+++ gtk2_ardour/region_view.cc	(working copy)
@@ -72,7 +72,6 @@
 	  , current_visible_sync_position(0.0)
 	  , valid(false)
 	  , _pixel_width(1.0)
-	  , _height(1.0)
 	  , in_destructor(false)
 	  , wait_for_data(false)
 {
@@ -92,7 +91,6 @@
 	, current_visible_sync_position(0.0)
 	, valid(false)
 	, _pixel_width(1.0)
-	, _height(1.0)
 	, in_destructor(false)
 	, wait_for_data(false)
 {
@@ -104,7 +102,6 @@
 	editor        = 0;
 	valid         = true;
 	in_destructor = false;
-	_height       = 0;
 	wait_for_data = wfd;
 
 	compute_colors (basic_color);
@@ -130,7 +127,7 @@
 
 	reset_width_dependent_items ((double) _region->length() / samples_per_unit);
 
-	set_height (trackview.height);
+	set_y_position_and_height (0, trackview.height);
 
 	_region->StateChanged.connect (mem_fun(*this, &RegionView::region_changed));
 
Index: gtk2_ardour/crossfade_view.h
===================================================================
--- gtk2_ardour/crossfade_view.h	(revision 1552)
+++ gtk2_ardour/crossfade_view.h	(working copy)
@@ -46,7 +46,7 @@
     AudioRegionView& left_view;    // and these too
     AudioRegionView& right_view;
 
-    void set_height (double);
+    void set_y_position_and_height (double y, double h);
 
     bool valid() const { return _valid; }
     bool visible() const { return _visible; }
@@ -68,6 +68,8 @@
     bool _visible;
 
     double spu;
+    double _y_position;
+    double _height;
 
     ArdourCanvas::Item *overlap_rect;
     ArdourCanvas::Line *fade_in;
Index: gtk2_ardour/streamview.cc
===================================================================
--- gtk2_ardour/streamview.cc	(revision 1552)
+++ gtk2_ardour/streamview.cc	(working copy)
@@ -56,6 +56,8 @@
 	, use_rec_regions(tv.editor.show_waveforms_recording())
 	, region_color(_trackview.color())
 	, stream_base_color(0xFFFFFFFF)
+	, height(0)
+	, layers(1)
 {
 	/* set_position() will position the group */
 
@@ -95,7 +97,6 @@
 
 int
 StreamView::set_position (gdouble x, gdouble y)
-
 {
 	canvas_group->property_x() = x;
 	canvas_group->property_y() = y;
@@ -106,27 +107,38 @@
 StreamView::set_height (gdouble h)
 {
 	/* limit the values to something sane-ish */
-
 	if (h < 10.0 || h > 1000.0) {
 		return -1;
 	}
 
-	canvas_rect->property_y2() = h;
+	height = h;
+	update_content_heights ();
+	return 0;
+}
 
+void
+StreamView::update_content_heights ()
+{
+	canvas_rect->property_y2() = height;
+
+	const double lh = height / layers;
+
 	for (RegionViewList::iterator i = region_views.begin(); i != region_views.end(); ++i) {
-		(*i)->set_height (h);
+		switch (_layer_display) {
+		case Overlaid:
+			(*i)->set_y_position_and_height (0, height);
+			break;
+		case Stacked:
+			const double y = (*i)->region()->layer() * lh;
+			(*i)->set_y_position_and_height (y, lh);
+			break;
+		}
 	}
 
-	/*for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-		(*i)->set_height (h);
-	}*/
-
 	for (vector<RecBoxInfo>::iterator i = rec_rects.begin(); i != rec_rects.end(); ++i) {
 		RecBoxInfo &recbox = (*i);
-		recbox.rectangle->property_y2() = h - 1.0;
+		recbox.rectangle->property_y2() = height - 1.0;
 	}
-
-	return 0;
 }
 
 int 
@@ -161,6 +173,7 @@
 StreamView::add_region_view (boost::shared_ptr<Region> r)
 {
 	add_region_view_internal (r, true);
+	update_content_heights ();
 }
 
 void
@@ -202,10 +215,14 @@
 }
 
 void
-StreamView::playlist_modified ()
+StreamView::playlist_modified (boost::shared_ptr<Diskstream> ds)
 {
-	ENSURE_GUI_THREAD (mem_fun (*this, &StreamView::playlist_modified));
+	ENSURE_GUI_THREAD (bind (mem_fun (*this, &StreamView::playlist_modified), ds));
 
+	/* update layers count and heights of our regions */
+	layers = ds->playlist()->top_layer() + 1;
+	update_content_heights();
+
 	redisplay_diskstream ();
 }
 
@@ -229,7 +246,11 @@
 
 	/* catch changes */
 
-	playlist_connections.push_back (ds->playlist()->Modified.connect (mem_fun (*this, &StreamView::playlist_modified)));
+	playlist_connections.push_back (ds->playlist()->Modified.connect (bind (mem_fun (*this, &StreamView::playlist_modified), ds)));
+
+	/* update layers count and heights of our regions */
+	layers = ds->playlist()->top_layer() + 1;
+	update_content_heights();
 }
 
 void
@@ -389,3 +410,9 @@
 	}
 }
 
+void
+StreamView::set_layer_display (LayerDisplay d)
+{
+	_layer_display = d;
+	update_content_heights ();
+}
Index: gtk2_ardour/audio_region_view.h
===================================================================
--- gtk2_ardour/audio_region_view.h	(revision 1552)
+++ gtk2_ardour/audio_region_view.h	(working copy)
@@ -61,7 +61,7 @@
 	
 	boost::shared_ptr<ARDOUR::AudioRegion> audio_region() const;
 	
-	void set_height (double);
+	void set_y_position_and_height (double y, double h);
 	void set_samples_per_unit (double);
 	
 	void set_amplitude_above_axis (gdouble spp);
@@ -146,7 +146,7 @@
 	void color_handler (ColorID, uint32_t);
 
     vector<GnomeCanvasWaveViewCache*> wave_caches;
-    vector<ArdourCanvas::WaveView *>  waves;
+    vector<ArdourCanvas::WaveView *>  waves; ///< canvas objects to display waves
     vector<ArdourCanvas::WaveView *>  tmp_waves; ///< see ::create_waves()
     ArdourCanvas::Polygon*            sync_mark; ///< polgyon for sync position 
     ArdourCanvas::SimpleLine*         zero_line;
@@ -157,9 +157,16 @@
     AudioRegionGainLine*              gain_line;
 
     double _amplitude_above_axis;
+    double _y_position;
+    double _height;
 
     uint32_t _flags;
     uint32_t fade_color;
+
+  private:
+
+    void setup_fade_handle_positions();
+
 };
 
 #endif /* __gtk_ardour_audio_region_view_h__ */
Index: gtk2_ardour/enums.h
===================================================================
--- gtk2_ardour/enums.h	(revision 1552)
+++ gtk2_ardour/enums.h	(working copy)
@@ -13,6 +13,10 @@
 	LogWaveform,
 };
 
+enum LayerDisplay {
+	Overlaid,
+	Stacked
+};
 
 enum Width {
 	Wide,
Index: gtk2_ardour/audio_time_axis.h
===================================================================
--- gtk2_ardour/audio_time_axis.h	(revision 1552)
+++ gtk2_ardour/audio_time_axis.h	(working copy)
@@ -98,6 +98,7 @@
 	void set_waveform_shape (WaveformShape);
 	void toggle_waveforms ();
 	void set_waveform_scale (WaveformScale);
+	void set_layer_display (LayerDisplay);
 
 	void show_all_automation ();
 	void show_existing_automation ();
Index: gtk2_ardour/editor_mouse.cc
===================================================================
--- gtk2_ardour/editor_mouse.cc	(revision 1552)
+++ gtk2_ardour/editor_mouse.cc	(working copy)
@@ -3259,7 +3259,7 @@
 		  
 						tvp2 = trackview_by_y_position (iy1 + y_delta);
 						temp_atv = dynamic_cast<AudioTimeAxisView*>(tvp2);
-						rv->set_height (temp_atv->height);
+						rv->set_y_position_and_height (0, temp_atv->height);
 	
 						/*   if you un-comment the following, the region colours will follow the track colours whilst dragging,
 						     personally, i think this can confuse things, but never mind.
Index: gtk2_ardour/audio_region_view.cc
===================================================================
--- gtk2_ardour/audio_region_view.cc	(revision 1552)
+++ gtk2_ardour/audio_region_view.cc	(working copy)
@@ -135,20 +135,18 @@
 		fade_in_handle = new ArdourCanvas::SimpleRect (*group);
 		fade_in_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
 		fade_in_handle->property_outline_pixels() = 0;
-		fade_in_handle->property_y1() = 2.0;
-		fade_in_handle->property_y2() = 7.0;
 		
 		fade_in_handle->set_data ("regionview", this);
 		
 		fade_out_handle = new ArdourCanvas::SimpleRect (*group);
 		fade_out_handle->property_fill_color_rgba() = RGBA_TO_UINT(r,g,b,0);
 		fade_out_handle->property_outline_pixels() = 0;
-		fade_out_handle->property_y1() = 2.0;
-		fade_out_handle->property_y2() = 7.0;
 		
 		fade_out_handle->set_data ("regionview", this);
 	}
 
+	setup_fade_handle_positions ();
+
 	string foo = _region->name();
 	foo += ':';
 	foo += "gain";
@@ -163,7 +161,7 @@
 
 	gain_line->reset ();
 
-	set_height (trackview.height);
+	set_y_position_and_height (0, trackview.height);
 
 	region_muted ();
 	region_sync_changed ();
@@ -364,41 +362,45 @@
 
 
 void
-AudioRegionView::set_height (gdouble height)
+AudioRegionView::set_y_position_and_height (double y, double h)
 {
-	uint32_t wcnt = waves.size();
-
-	// FIXME: ick
-	TimeAxisViewItem::set_height (height - 2);
+	TimeAxisViewItem::set_y_position_and_height (y, h - 2);
 	
-	_height = height;
+	_y_position = y;
+	_height = h;
 
-	for (uint32_t n=0; n < wcnt; ++n) {
-		gdouble ht;
+	/* set up wave displays */
+	const uint32_t wcnt = waves.size();
+	for (uint32_t n = 0; n < wcnt; ++n) {
+		double ht;
 
-		if ((height) <= NAME_HIGHLIGHT_THRESH) {
-			ht = ((height-2*wcnt) / (double) wcnt);
+		/* allow space for a name if the height is sufficient */
+		if (h <= NAME_HIGHLIGHT_THRESH) {
+			ht = ((h - 2 * wcnt) / (double) wcnt);
 		} else {
-			ht = (((height-2*wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
+			ht = (((h - 2 * wcnt) - NAME_HIGHLIGHT_SIZE) / (double) wcnt);
 		}
 		
-		gdouble yoff = n * (ht+1);
+		const double yoff = n * (ht + 1);
 		
 		waves[n]->property_height() = ht;
-		waves[n]->property_y() = yoff + 2;
+		waves[n]->property_y() = y + yoff + 2;
 	}
 
+	/* set up gain line if we've got one */
 	if (gain_line) {
-		if ((height/wcnt) < NAME_HIGHLIGHT_SIZE) {
+
+		if ((h / wcnt) < NAME_HIGHLIGHT_SIZE) {
 			gain_line->hide ();
 		} else {
 			if (_flags & EnvelopeVisible) {
 				gain_line->show ();
 			}
 		}
-		gain_line->set_height ((uint32_t) rint (height - NAME_HIGHLIGHT_SIZE));
+		gain_line->set_height ((uint32_t) rint (h - NAME_HIGHLIGHT_SIZE));
 	}
 
+	setup_fade_handle_positions ();
 	manage_zero_line ();
 	reset_fade_shapes ();
 	
@@ -408,6 +410,25 @@
 }
 
 void
+AudioRegionView::setup_fade_handle_positions()
+{
+	/* position of fade handle offset from the top of the region view */
+	const double handle_pos = 2;
+	/* height of fade handles */
+	const double handle_height = 5;
+
+	if (fade_in_handle) {
+		fade_in_handle->property_y1() = _y_position + handle_pos;
+		fade_in_handle->property_y2() = _y_position + handle_pos + handle_height;
+	}
+	
+	if (fade_out_handle) {
+		fade_out_handle->property_y1() = _y_position + handle_pos;
+		fade_out_handle->property_y2() = _y_position + handle_height;
+	}
+}
+
+void
 AudioRegionView::manage_zero_line ()
 {
 	if (!zero_line) {
@@ -415,7 +436,7 @@
 	}
 
 	if (_height >= 100) {
-		gdouble wave_midpoint = (_height - NAME_HIGHLIGHT_SIZE) / 2.0;
+		const double wave_midpoint = _y_position + (_height - NAME_HIGHLIGHT_SIZE) / 2.0;
 		zero_line->property_y1() = wave_midpoint;
 		zero_line->property_y2() = wave_midpoint;
 		zero_line->show();
Index: gtk2_ardour/imageframe_view.cc
===================================================================
--- gtk2_ardour/imageframe_view.cc	(revision 1552)
+++ gtk2_ardour/imageframe_view.cc	(working copy)
@@ -248,19 +248,20 @@
 // ui methods
 		
 /**
- * Set the height of this item
+ * Set the y position and height of this item
  *
+ * @param y the new y position
  * @param h the new height
  */
 void
-ImageFrameView::set_height (gdouble h)
+ImageFrameView::set_y_position_and_height (double y, double h)
 {
 	// set the image size
 	// @todo might have to re-get the image data, for a large height...hmmm.
-	double im_ratio = (double)image_data_width/(double)image_data_height ;
+	const double im_ratio = (double)image_data_width/(double)image_data_height ;
 
 	imageframe->property_width() = (h - TimeAxisViewItem::NAME_Y_OFFSET) * im_ratio;
-	imageframe->property_height() = h - TimeAxisViewItem::NAME_Y_OFFSET;
+	imageframe->property_height() = y + h - TimeAxisViewItem::NAME_Y_OFFSET;
 
 	frame->raise_to_top();
 	imageframe->raise_to_top();
@@ -269,11 +270,12 @@
 	frame_handle_start->raise_to_top();
 	frame_handle_end->raise_to_top();
  
-	name_text->property_y() = h - TimeAxisViewItem::NAME_Y_OFFSET;
-	frame->property_y2() = h;
+	name_text->property_y() = y + h - TimeAxisViewItem::NAME_Y_OFFSET;
+	frame->property_y1() = y;
+	frame->property_y2() = y + h;
 
-	name_highlight->property_y1() = (gdouble) h - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
-	name_highlight->property_y2() = (gdouble) h - 1.0;
+	name_highlight->property_y1() = (double) y + h - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE;
+	name_highlight->property_y2() = (double) y + h - 1.0;
 }
 
 
Index: gtk2_ardour/crossfade_view.cc
===================================================================
--- gtk2_ardour/crossfade_view.cc	(revision 1552)
+++ gtk2_ardour/crossfade_view.cc	(working copy)
@@ -59,6 +59,8 @@
 {
 	_valid = true;
 	_visible = true;
+	_y_position = 0;
+	_height = 1;
 
 	fade_in = new Line (*group);
 	fade_in->property_fill_color_rgba() = color_map[cCrossfadeLine];
@@ -68,7 +70,7 @@
 	fade_out->property_fill_color_rgba() = color_map[cCrossfadeLine];
 	fade_out->property_width_pixels() = 1;
 	
-	set_height (get_time_axis_view().height);
+	set_y_position_and_height (0, get_time_axis_view().height); // FIXMECTH
 
 	/* no frame around the xfade or overlap rects */
 
@@ -105,14 +107,17 @@
 }
 
 void
-CrossfadeView::set_height (double height)
+CrossfadeView::set_y_position_and_height (double y, double h)
 {
-	if (height == TimeAxisView::hSmaller ||
-	    height == TimeAxisView::hSmall)
-		TimeAxisViewItem::set_height (height - 3 );
-	else
-		TimeAxisViewItem::set_height (height - NAME_HIGHLIGHT_SIZE - 3 );
+	if (h == TimeAxisView::hSmaller || h == TimeAxisView::hSmall) {
+		TimeAxisViewItem::set_y_position_and_height (y, h - 3 );
+	} else {
+		TimeAxisViewItem::set_y_position_and_height (y, h - NAME_HIGHLIGHT_SIZE - 3 );
+	}
 
+	_y_position = y;
+	_height = h;
+
 	redraw_curves ();
 }
 
@@ -158,9 +163,8 @@
 	 At "height - 3.0" the bottom of the crossfade touches the name highlight or the bottom of the track (if the
 	 track is either Small or Smaller.
 	 */
-	double tav_height = get_time_axis_view().height;
-	if (tav_height == TimeAxisView::hSmaller ||
-	    tav_height == TimeAxisView::hSmall) {
+	const double tav_height = get_time_axis_view().height;
+	if (tav_height == TimeAxisView::hSmaller || tav_height == TimeAxisView::hSmall) {
 		h = tav_height - 3.0;
 	} else {
 		h = tav_height - NAME_HIGHLIGHT_SIZE - 3.0;
@@ -190,7 +194,7 @@
 	for (int i = 0, pci = 0; i < npoints; ++i) {
 		Art::Point &p = (*points)[pci++];
 		p.set_x(i);
-		p.set_y(2.0 + h - (h * vec[i]));
+		p.set_y(_y_position + 2.0 + h - (h * vec[i]));
 	}
 	fade_in->property_points() = *points;
 
@@ -198,7 +202,7 @@
 	for (int i = 0, pci = 0; i < npoints; ++i) {
 		Art::Point &p = (*points)[pci++];
 		p.set_x(i);
-		p.set_y(2.0 + h - (h * vec[i]));
+		p.set_y(_y_position + 2.0 + h - (h * vec[i]));
 	}
 	fade_out->property_points() = *points;
 
Index: gtk2_ardour/streamview.h
===================================================================
--- gtk2_ardour/streamview.h	(revision 1552)
+++ gtk2_ardour/streamview.h	(working copy)
@@ -73,6 +73,9 @@
 	virtual int set_samples_per_unit (gdouble spp);
 	gdouble     get_samples_per_unit () { return _samples_per_unit; }
 
+	void set_layer_display (LayerDisplay);
+	LayerDisplay get_layer_display() const { return _layer_display; }
+  
 	ArdourCanvas::Item* canvas_item() { return canvas_group; }
 
 	enum ColorTarget {
@@ -82,7 +85,6 @@
 
 	Gdk::Color get_region_color () const { return region_color; }
 	void       apply_color (Gdk::Color&, ColorTarget t);
-
 	RegionView*  find_view (boost::shared_ptr<const ARDOUR::Region>);
 	void         foreach_regionview (sigc::slot<void,RegionView*> slot);
 
@@ -117,7 +119,7 @@
 	void         diskstream_changed ();
 	
 	virtual void playlist_changed (boost::shared_ptr<ARDOUR::Diskstream>);
-	virtual void playlist_modified ();
+	virtual void playlist_modified (boost::shared_ptr<ARDOUR::Diskstream>);
 	
 	virtual void color_handler (ColorID, uint32_t) = 0;
 
@@ -143,6 +145,12 @@
 
 	vector<sigc::connection> playlist_connections;
 	sigc::connection         playlist_change_connection;
+
+	double height;
+	int layers;
+	LayerDisplay _layer_display;
+  
+	virtual void update_content_heights ();
 };
 
 #endif /* __ardour_streamview_h__ */
Index: gtk2_ardour/audio_streamview.cc
===================================================================
--- gtk2_ardour/audio_streamview.cc	(revision 1552)
+++ gtk2_ardour/audio_streamview.cc	(working copy)
@@ -80,21 +80,19 @@
 {
 }
 
-int
-AudioStreamView::set_height (gdouble h)
+void
+AudioStreamView::update_content_heights ()
 {
-	/* limit the values to something sane-ish */
-	if (h < 10.0 || h > 1000.0) {
-		return -1;
-	}
+	StreamView::update_content_heights();
 
-	StreamView::set_height(h);
-
 	for (CrossfadeViewList::iterator i = crossfade_views.begin(); i != crossfade_views.end(); ++i) {
-		(*i)->set_height (h);
+		if (_layer_display == Overlaid) {
+			(*i)->set_y_position_and_height(0, height);
+		} else {
+			/* FIXME */
+		}
 	}
-
-	return 0;
+	
 }
 
 int 
@@ -256,11 +254,11 @@
 }
 
 void
-AudioStreamView::playlist_modified ()
+AudioStreamView::playlist_modified (boost::shared_ptr<Diskstream> ds)
 {
-	ENSURE_GUI_THREAD (mem_fun (*this, &AudioStreamView::playlist_modified));
+	ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::playlist_modified), ds));
 
-	StreamView::playlist_modified();
+	StreamView::playlist_modified(ds);
 	
 	/* make sure xfades are on top and all the regionviews are stacked correctly. */
 
@@ -420,7 +418,7 @@
 			arv->set_waveform_shape (shape);
 	}
 	_waveform_shape = shape;
-}		
+}
 
 void
 AudioStreamView::set_waveform_scale (WaveformScale scale)
@@ -431,7 +429,7 @@
 			arv->set_waveform_scale (scale);
 	}
 	_waveform_scale = scale;
-}		
+}
 
 void
 AudioStreamView::setup_rec_box ()
Index: gtk2_ardour/time_axis_view_item.cc
===================================================================
--- gtk2_ardour/time_axis_view_item.cc	(revision 1552)
+++ gtk2_ardour/time_axis_view_item.cc	(working copy)
@@ -534,15 +534,16 @@
 }
 
 /**
- * Set the height of this item
+ * Set the y position and height of this item
  *
+ * @param y the new y position
  * @param h the new height
  */		
 void
-TimeAxisViewItem::set_height(double height)
+TimeAxisViewItem::set_y_position_and_height(double y, double h)
 {
 	if (name_highlight) {
-		if (height < NAME_HIGHLIGHT_THRESH) {
+		if (h < NAME_HIGHLIGHT_THRESH) {
 			name_highlight->hide();
 			if (name_text) {
 				name_text->hide();
@@ -554,20 +555,20 @@
 			}
 		}
 
-		if (height > NAME_HIGHLIGHT_SIZE) {
-			name_highlight->property_y1() = (double) height+1 - NAME_HIGHLIGHT_SIZE;
-			name_highlight->property_y2() = (double) height;
+		if (h > NAME_HIGHLIGHT_SIZE) {
+			name_highlight->property_y1() = (double) y + h + 1 - NAME_HIGHLIGHT_SIZE;
+			name_highlight->property_y2() = (double) y + h;
 		}
 		else {
 			/* it gets hidden now anyway */
-			name_highlight->property_y1() = (double) 1.0;
-			name_highlight->property_y2() = (double) height;
+			name_highlight->property_y1() = (double) y;
+			name_highlight->property_y2() = (double) y + h;
 		}
 	}
 
 	if (name_text) {
-		name_text->property_y() = height+1 - NAME_Y_OFFSET;
-		if (height < NAME_HIGHLIGHT_THRESH) {
+		name_text->property_y() = y + h + 1 - NAME_Y_OFFSET;
+		if (h < NAME_HIGHLIGHT_THRESH) {
 			name_text->property_fill_color_rgba() =  fill_color;
 		}
 		else {
@@ -576,10 +577,12 @@
 	}
 
 	if (frame) {
-		frame->property_y2() = height+1;
+		frame->property_y1() = y;
+		frame->property_y2() = y + h + 1;
 	}
 
-	vestigial_frame->property_y2() = height+1;
+	vestigial_frame->property_y1() = y;
+	vestigial_frame->property_y2() = y + h + 1;
 }
 
 /**
Index: gtk2_ardour/marker_time_axis_view.cc
===================================================================
--- gtk2_ardour/marker_time_axis_view.cc	(revision 1552)
+++ gtk2_ardour/marker_time_axis_view.cc	(working copy)
@@ -124,7 +124,7 @@
 
 	for (MarkerViewList::iterator i = marker_view_list.begin(); i != marker_view_list.end(); ++i)
 	{
-		(*i)->set_height(h) ;
+		(*i)->set_y_position_and_height(0, h) ;
 	}
 
 	return 0;
Index: gtk2_ardour/imageframe_view.h
===================================================================
--- gtk2_ardour/imageframe_view.h	(revision 1552)
+++ gtk2_ardour/imageframe_view.h	(working copy)
@@ -123,11 +123,12 @@
 		// ui methods
 		
 		/**
-		 * Set the height of this item
+		 * Set the y position and height of this item
 		 *
+		 * @param y the new y position
 		 * @param h the new height
 		 */
-		virtual void set_height(gdouble h) ;
+		virtual void set_y_position_and_height(double y, double h) ;
 	
 		
 		//---------------------------------------------------------------------------------------//
Index: gtk2_ardour/time_axis_view_item.h
===================================================================
--- gtk2_ardour/time_axis_view_item.h	(revision 1552)
+++ gtk2_ardour/time_axis_view_item.h	(working copy)
@@ -199,11 +199,12 @@
     void set_name_text(std::string new_name) ;
     
     /**
-     * Set the height of this item
+     * Set the y position and height of this item
      *
+     * @param y the new y position
      * @param h the new height
      */
-    virtual void set_height(double h) ;
+    virtual void set_y_position_and_height(double y, double h) ;
     
     /**
      * 



More information about the Ardour-Users mailing list