src/tracks/labeltrack/ui/LabelTrackView.cpp
/// ComputeLayout determines which row each label
/// should be placed on, and reserves space for it.
/// Function assumes that the labels are sorted.
ComputeLayout determines which row each label
should be placed on, and reserves space for it.
Function assumes that the labels are sorted.
ComputeLayout determines which row each label should be placed on and reserves space for it . Function assumes that the labels are sorted .
void LabelTrackView::ComputeLayout(const wxRect & r, const ZoomInfo &zoomInfo) const
{
   int xUsed[MAX_NUM_ROWS];
   int iRow;
   const int yRowHeight = wxMax(mTextHeight,mIconHeight)+3;
   const int xExtra= (3 * mIconWidth)/2;
   bool bAvoidName = false;
   const int nRows = wxMin((r.height / yRowHeight) + 1, MAX_NUM_ROWS);
   if( nRows > 2 )
      bAvoidName = gPrefs->ReadBool(wxT("/GUI/ShowTrackNameInWaveform"), false);
   {
      const int xStart = INT_MIN;
      for (auto &x : xUsed)
         x = xStart;
   }
   int nRowsUsed=0;
   const auto pTrack = FindLabelTrack();
   const auto &mLabels = pTrack->GetLabels();
   { int i = -1; for (const auto &labelStruct : mLabels) { ++i;
      const int x = zoomInfo.TimeToPosition(labelStruct.getT0(), r.x);
      const int x1 = zoomInfo.TimeToPosition(labelStruct.getT1(), r.x);
      int y = r.y;
      labelStruct.x=x;
      labelStruct.x1=x1;
      labelStruct.y=-1;
      iRow=0;
      while( (iRow<nRowsUsed) && (xUsed[iRow] != x ))
         iRow++;
      if( iRow >= nRowsUsed )
      {
         iRow=0;
         while( (iRow<nRows) && (xUsed[iRow] > x ))
            iRow++;
      }
      if( iRow<nRows )
      {
         if( (i==0 ) && (iRow==0) && bAvoidName ){
            const int x2 = zoomInfo.TimeToPosition(0.0, r.x) + 200;
            xUsed[iRow]=x+labelStruct.width+xExtra;
            if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
            if( xUsed[iRow] < x2 ) xUsed[iRow]=x2;
            iRow=1;
         }
         if( iRow >= nRowsUsed )
            nRowsUsed=iRow+1;
         y= r.y + iRow * yRowHeight +(yRowHeight/2)+1;
         labelStruct.y=y;
         xUsed[iRow]=x+labelStruct.width+xExtra;
         if( xUsed[iRow] < x1 ) xUsed[iRow]=x1;
         ComputeTextPosition( r, i );
      }
   }}
}
void LabelTrackView :: ComputeLayout ( const wxRect & r , const ZoomInfo & zoomInfo ) const { int xUsed [ MAX_NUM_ROWS ] ; int iRow ; const int yRowHeight = wxMax ( mTextHeight , mIconHeight ) + 3 ; const int xExtra = ( 3 * mIconWidth ) / 2 ; bool bAvoidName = false ; const int nRows = wxMin ( ( r . height / yRowHeight ) + 1 , MAX_NUM_ROWS ) ; if ( nRows > 2 ) bAvoidName = gPrefs -> ReadBool ( wxT ( " " ) , false ) ; { const int xStart = INT_MIN ; for ( auto & x : xUsed ) x = xStart ; } int nRowsUsed = 0 ; const auto pTrack = FindLabelTrack ( ) ; const auto & mLabels = pTrack -> GetLabels ( ) ; { int i = -1 ; for ( const auto & labelStruct : mLabels ) { ++ i ; const int x = zoomInfo . TimeToPosition ( labelStruct . getT0 ( ) , r . x ) ; const int x1 = zoomInfo . TimeToPosition ( labelStruct . getT1 ( ) , r . x ) ; int y = r . y ; labelStruct . x = x ; labelStruct . x1 = x1 ; labelStruct . y = -1 ; iRow = 0 ; while ( ( iRow < nRowsUsed ) && ( xUsed [ iRow ] != x ) ) iRow ++ ; if ( iRow >= nRowsUsed ) { iRow = 0 ; while ( ( iRow < nRows ) && ( xUsed [ iRow ] > x ) ) iRow ++ ; } if ( iRow < nRows ) { if ( ( i == 0 ) && ( iRow == 0 ) && bAvoidName ) { const int x2 = zoomInfo . TimeToPosition ( 0.0 , r . x ) + 200 ; xUsed [ iRow ] = x + labelStruct . width + xExtra ; if ( xUsed [ iRow ] < x1 ) xUsed [ iRow ] = x1 ; if ( xUsed [ iRow ] < x2 ) xUsed [ iRow ] = x2 ; iRow = 1 ; } if ( iRow >= nRowsUsed ) nRowsUsed = iRow + 1 ; y = r . y + iRow * yRowHeight + ( yRowHeight / 2 ) + 1 ; labelStruct . y = y ; xUsed [ iRow ] = x + labelStruct . width + xExtra ; if ( xUsed [ iRow ] < x1 ) xUsed [ iRow ] = x1 ; ComputeTextPosition ( r , i ) ; } } } }
ComputeLayout determines which row each label
should be placed on, and reserves space for it.
ComputeLayout determines which row each label should be placed on and reserves space for it .
// Rows are the 'same' height as icons or as the text, // whichever is taller. // pixels. // Extra space at end of rows. // We allow space for one half icon at the start and two // half icon widths for extra x for the text frame. // [we don't allow half a width space for the end icon since it is // allowed to be obscured by the text]. // Initially none of the rows have been used. // So set a value that is less than any valid value. // Bug 502: With dragging left of zeros, labels can be in  // negative space.  So set least possible value as starting point. // -ve indicates nothing doing. // Our first preference is a row that ends where we start. // (This is to encourage merging of adjacent label boundaries). // IF we didn't find one THEN // find any row that can take a span starting at x. // IF we found such a row THEN record a valid position. // Logic to ameliorate case where first label is under the  // (on track) track name.  For later labels it does not matter // as we can scroll left or right and/or zoom. // A possible alternative idea would be to (instead) increase the  // translucency of the track name, when the mouse is inside it. // reserve some space in first row. // reserve max of 200px or t1, or text box right edge. // Possibly update the number of rows actually used. // Record the position for this label // On this row we have used up to max of end marker and width. // Plus also allow space to show the start icon and // some space for the text frame.