mirror of
https://github.com/cookiengineer/audacity
synced 2025-08-02 17:09:26 +02:00
Bug2256: Resizing channels should not change subview proportions
This commit is contained in:
parent
f39f505205
commit
17ed4899ec
@ -204,16 +204,18 @@ public:
|
|||||||
|
|
||||||
if ( index < adjuster.mPermutation.size() )
|
if ( index < adjuster.mPermutation.size() )
|
||||||
return std::make_shared< SubViewAdjustHandle >(
|
return std::make_shared< SubViewAdjustHandle >(
|
||||||
std::move( adjuster ), index, hit.second
|
std::move( adjuster ), index, view.GetLastHeight(), hit.second
|
||||||
);
|
);
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
SubViewAdjustHandle(
|
SubViewAdjustHandle(
|
||||||
SubViewAdjuster &&adjuster, size_t subViewIndex, bool top )
|
SubViewAdjuster &&adjuster, size_t subViewIndex,
|
||||||
|
wxCoord viewHeight, bool top )
|
||||||
: mAdjuster{ std::move( adjuster ) }
|
: mAdjuster{ std::move( adjuster ) }
|
||||||
, mMySubView{ subViewIndex }
|
, mMySubView{ subViewIndex }
|
||||||
|
, mViewHeight{ viewHeight }
|
||||||
, mTop{ top }
|
, mTop{ top }
|
||||||
{
|
{
|
||||||
if ( mAdjuster.ModifyPermutation( top ) )
|
if ( mAdjuster.ModifyPermutation( top ) )
|
||||||
@ -233,22 +235,33 @@ public:
|
|||||||
const auto height = rect.GetHeight();
|
const auto height = rect.GetHeight();
|
||||||
mOrigHeight = height;
|
mOrigHeight = height;
|
||||||
|
|
||||||
wxASSERT( height ==
|
// Compute integer-valued heights
|
||||||
mAdjuster.mOrigPlacements[ mAdjuster.mPermutation[ mMySubView ] ]
|
{
|
||||||
.fraction
|
float total = 0;
|
||||||
);
|
for (const auto index : mAdjuster.mPermutation ) {
|
||||||
|
const auto &placement = mAdjuster.mOrigPlacements[ index ];
|
||||||
// Find the total height of the sub-views that may resize
|
total += std::max( 0.f, placement.fraction );
|
||||||
// Note that this depends on the redenomination of fractions that
|
}
|
||||||
// happened in the last call to GetSubViews
|
float partial = 0;
|
||||||
mTotalHeight = 0;
|
wxCoord lastCoord = 0;
|
||||||
const auto begin = permutation.begin();
|
for (const auto index : mAdjuster.mPermutation ) {
|
||||||
auto iter = begin + ( mTop ? mAdjuster.mFirstSubView : mMySubView );
|
const auto &placement = mAdjuster.mOrigPlacements[ index ];
|
||||||
const auto end = ( mTop ? begin + mMySubView + 1 : permutation.end() );
|
auto fraction = std::max( 0.f, placement.fraction );
|
||||||
for (; iter != end; ++iter) {
|
wxCoord coord = ( (partial + fraction ) / total ) * mViewHeight;
|
||||||
const auto &placement = mAdjuster.mOrigPlacements[ *iter ];
|
mOrigHeights.emplace_back( coord - lastCoord );
|
||||||
mTotalHeight += placement.fraction;
|
lastCoord = coord;
|
||||||
|
partial += fraction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the total height of the sub-views that may resize
|
||||||
|
mTotalHeight = 0;
|
||||||
|
auto index = ( mTop ? mAdjuster.mFirstSubView : mMySubView );
|
||||||
|
const auto end = ( mTop ? mMySubView + 1 : permutation.size() );
|
||||||
|
for (; index != end; ++index)
|
||||||
|
mTotalHeight += mOrigHeights[ index ];
|
||||||
|
|
||||||
|
wxASSERT( height == mOrigHeights[ mMySubView ] );
|
||||||
|
|
||||||
// Compute the maximum and minimum Y coordinates for drag effect
|
// Compute the maximum and minimum Y coordinates for drag effect
|
||||||
if ( mTop ) {
|
if ( mTop ) {
|
||||||
@ -295,11 +308,9 @@ public:
|
|||||||
if (excess == 0)
|
if (excess == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
const auto oldFraction = mOrigHeights[ ii ];
|
||||||
|
|
||||||
auto index = mAdjuster.mPermutation[ ii ];
|
auto index = mAdjuster.mPermutation[ ii ];
|
||||||
|
|
||||||
const auto &origPlacement = mAdjuster.mOrigPlacements[ index ];
|
|
||||||
const auto oldFraction = origPlacement.fraction;
|
|
||||||
|
|
||||||
auto &placement = mAdjuster.mNewPlacements[ index ];
|
auto &placement = mAdjuster.mNewPlacements[ index ];
|
||||||
auto &fraction = placement.fraction;
|
auto &fraction = placement.fraction;
|
||||||
|
|
||||||
@ -368,12 +379,14 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
SubViewAdjuster mAdjuster;
|
SubViewAdjuster mAdjuster;
|
||||||
|
std::vector<wxCoord> mOrigHeights;
|
||||||
|
|
||||||
// An index into mAdjuster.mPermutation
|
// An index into mAdjuster.mPermutation
|
||||||
size_t mMySubView{};
|
size_t mMySubView{};
|
||||||
|
|
||||||
wxCoord mYMin{}, mYMax{};
|
wxCoord mYMin{}, mYMax{};
|
||||||
wxCoord mTotalHeight{};
|
wxCoord mViewHeight{}; // Total height of all sub-views
|
||||||
|
wxCoord mTotalHeight{}; // Total height of adjusting sub-views only
|
||||||
wxCoord mOrigHeight{};
|
wxCoord mOrigHeight{};
|
||||||
wxCoord mOrigY{};
|
wxCoord mOrigY{};
|
||||||
|
|
||||||
@ -531,17 +544,17 @@ auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
|||||||
Refinement results;
|
Refinement results;
|
||||||
|
|
||||||
// Collect the visible views in the right sequence
|
// Collect the visible views in the right sequence
|
||||||
using Pair = std::pair< float*, std::shared_ptr< TrackView > >;
|
using Pair = std::pair< float, std::shared_ptr< TrackView > >;
|
||||||
std::vector< Pair > pairs( mPlacements.size() );
|
std::vector< Pair > pairs( mPlacements.size() );
|
||||||
size_t ii = 0;
|
size_t ii = 0;
|
||||||
float total = 0;
|
float total = 0;
|
||||||
WaveTrackSubViews::ForEach( [&]( WaveTrackSubView &subView ){
|
WaveTrackSubViews::ForEach( [&]( WaveTrackSubView &subView ){
|
||||||
auto &placement = mPlacements[ii];
|
auto &placement = mPlacements[ii];
|
||||||
auto index = placement.index;
|
auto index = placement.index;
|
||||||
auto &fraction = placement.fraction;
|
auto fraction = placement.fraction;
|
||||||
if ( index >= 0 && fraction > 0.0 )
|
if ( index >= 0 && fraction > 0.0 )
|
||||||
total += fraction,
|
total += fraction,
|
||||||
pairs[ index ] = { &fraction, subView.shared_from_this() };
|
pairs[ index ] = { fraction, subView.shared_from_this() };
|
||||||
++ii;
|
++ii;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@ -552,25 +565,20 @@ auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
|||||||
pairs.erase( newEnd, end );
|
pairs.erase( newEnd, end );
|
||||||
results.reserve( pairs.size() );
|
results.reserve( pairs.size() );
|
||||||
|
|
||||||
// Assign coordinates
|
// Assign coordinates, redenominating to the total height,
|
||||||
// Also update the stored placements, redenominating to the total height,
|
|
||||||
// storing integer values
|
// storing integer values
|
||||||
const auto top = rect.GetTop();
|
const auto top = rect.GetTop();
|
||||||
const auto height = rect.GetHeight();
|
const auto height = rect.GetHeight();
|
||||||
float partial = 0;
|
float partial = 0;
|
||||||
wxCoord lastCoord = 0;
|
wxCoord lastCoord = 0;
|
||||||
float *lastFraction = nullptr;
|
|
||||||
for ( const auto &pair : pairs ) {
|
for ( const auto &pair : pairs ) {
|
||||||
wxCoord newCoord = top + (partial / total) * height;
|
wxCoord newCoord = top + (partial / total) * height;
|
||||||
results.emplace_back( newCoord, pair.second );
|
results.emplace_back( newCoord, pair.second );
|
||||||
partial += *pair.first;
|
partial += pair.first;
|
||||||
if (lastFraction)
|
|
||||||
*lastFraction = newCoord - lastCoord;
|
|
||||||
lastFraction = pair.first;
|
|
||||||
lastCoord = newCoord;
|
|
||||||
}
|
}
|
||||||
if ( lastFraction )
|
|
||||||
*lastFraction = top + height - lastCoord;
|
// Cache for the use of sub-view dragging
|
||||||
|
mLastHeight = height;
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,9 @@ public:
|
|||||||
// correspondence with the result of SavePlacements
|
// correspondence with the result of SavePlacements
|
||||||
std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
|
std::vector< std::shared_ptr< WaveTrackSubView > > GetAllSubViews();
|
||||||
|
|
||||||
|
// Return cached height of rect in last call of GetSubViews
|
||||||
|
wxCoord GetLastHeight() const { return mLastHeight; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void BuildSubViews() const;
|
void BuildSubViews() const;
|
||||||
void DoSetDisplay(WaveTrackDisplay display);
|
void DoSetDisplay(WaveTrackDisplay display);
|
||||||
@ -117,6 +120,7 @@ protected:
|
|||||||
void DoSetMinimized( bool minimized ) override;
|
void DoSetMinimized( bool minimized ) override;
|
||||||
|
|
||||||
WaveTrackSubViewPlacements mPlacements;
|
WaveTrackSubViewPlacements mPlacements;
|
||||||
|
mutable wxCoord mLastHeight{};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper for drawing routines
|
// Helper for drawing routines
|
||||||
|
Loading…
x
Reference in New Issue
Block a user