mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 23:29:41 +02:00
Own resizing area added to stereo wave tracks view and affordance view
(cherry picked from audacity commit 7949a0dc86b6e473ffa7fd41d4fe9ddad1e6ba51) Signed-off-by: akleja <storspov@gmail.com>
This commit is contained in:
parent
607e60ab4d
commit
e9d6aa2c5c
@ -16,6 +16,7 @@
|
||||
#include "../../../../TrackPanelMouseEvent.h"
|
||||
#include "../../../../TrackArtist.h"
|
||||
#include "../../../../TrackPanelDrawingContext.h"
|
||||
#include "../../../../TrackPanelResizeHandle.h"
|
||||
#include "../../../../ViewInfo.h"
|
||||
#include "../../../../WaveTrack.h"
|
||||
#include "../../../../WaveClip.h"
|
||||
@ -34,14 +35,29 @@ std::vector<UIHandlePtr> WaveTrackAffordanceControls::HitTest(const TrackPanelMo
|
||||
|
||||
std::vector<UIHandlePtr> results;
|
||||
|
||||
const auto track = FindTrack();
|
||||
|
||||
const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
|
||||
auto px = state.state.m_x;
|
||||
auto py = state.state.m_y;
|
||||
|
||||
const auto rect = state.rect;
|
||||
|
||||
auto px = state.state.m_x;
|
||||
auto py = state.state.m_y;
|
||||
const auto track = FindTrack();
|
||||
|
||||
auto trackList = track->GetOwner();
|
||||
if ((std::abs(rect.GetTop() - py) <= WaveTrackView::kChannelSeparatorThickness / 2)
|
||||
&& trackList
|
||||
&& !track->IsLeader())
|
||||
{
|
||||
//given that track is not a leader there always should be
|
||||
//another track before this one
|
||||
auto prev = --trackList->Find(track.get());
|
||||
auto result = std::static_pointer_cast<UIHandle>(
|
||||
std::make_shared<TrackPanelResizeHandle>((*prev)->shared_from_this(), py)
|
||||
);
|
||||
result = AssignUIHandlePtr(mResizeHandle, result);
|
||||
results.push_back(result);
|
||||
}
|
||||
|
||||
const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
|
||||
|
||||
auto& zoomInfo = ViewInfo::Get(*pProject);
|
||||
for (const auto& clip : waveTrack->GetClips())
|
||||
|
@ -19,6 +19,7 @@ class TENACITY_DLL_API WaveTrackAffordanceControls : public CommonTrackCell
|
||||
{
|
||||
std::weak_ptr<WaveClip> mFocusClip;
|
||||
std::weak_ptr<AffordanceHandle> mAffordanceHandle;
|
||||
std::weak_ptr<UIHandle> mResizeHandle;
|
||||
public:
|
||||
WaveTrackAffordanceControls(const std::shared_ptr<Track>& pTrack);
|
||||
|
||||
|
@ -31,6 +31,7 @@ Paul Licameli split from TrackPanel.cpp
|
||||
#include "../../../../TrackArtist.h"
|
||||
#include "../../../../TrackPanelDrawingContext.h"
|
||||
#include "../../../../TrackPanelMouseEvent.h"
|
||||
#include "../../../../TrackPanelResizeHandle.h"
|
||||
#include "../../../../ViewInfo.h"
|
||||
#include "../../../../prefs/TracksPrefs.h"
|
||||
|
||||
@ -703,6 +704,49 @@ std::pair<
|
||||
mCloseHandle,
|
||||
*pWaveTrackView, *this, state ) )
|
||||
results.second.push_back( pHandle );
|
||||
|
||||
auto channels = TrackList::Channels(wt.get());
|
||||
if(channels.size() > 1) {
|
||||
// Only one cell is tested and we need to know
|
||||
// which one and it's relative location to the border.
|
||||
auto subviews = pWaveTrackView->GetSubViews();
|
||||
auto currentSubview = std::find_if(subviews.begin(), subviews.end(),
|
||||
[self = shared_from_this()](const auto& p){
|
||||
return self == p.second;
|
||||
});
|
||||
if (currentSubview != subviews.end())
|
||||
{
|
||||
auto currentSubviewIndex = std::distance(subviews.begin(), currentSubview);
|
||||
|
||||
const auto py = state.state.GetY();
|
||||
const auto topBorderHit = std::abs(py - state.rect.GetTop())
|
||||
<= WaveTrackView::kChannelSeparatorThickness / 2;
|
||||
const auto bottomBorderHit = std::abs(py - state.rect.GetBottom())
|
||||
<= WaveTrackView::kChannelSeparatorThickness / 2;
|
||||
|
||||
auto currentChannel = channels.find(wt.get());
|
||||
auto currentChannelIndex = std::distance(channels.begin(), currentChannel);
|
||||
|
||||
if (//for not-last-view check the bottom border hit
|
||||
((currentChannelIndex != channels.size() - 1)
|
||||
&& (currentSubviewIndex == static_cast<int>(subviews.size()) - 1)
|
||||
&& bottomBorderHit)
|
||||
||
|
||||
//or for not-first-view check the top border hit
|
||||
((currentChannelIndex != 0) && currentSubviewIndex == 0 && topBorderHit))
|
||||
{
|
||||
//depending on which border hit test succeeded on we
|
||||
//need to choose a proper target for resizing
|
||||
auto it = bottomBorderHit ? currentChannel : currentChannel.advance(-1);
|
||||
auto result = std::static_pointer_cast<UIHandle>(
|
||||
std::make_shared<TrackPanelResizeHandle>((*it)->shared_from_this(), py)
|
||||
);
|
||||
result = AssignUIHandlePtr(mResizeHandle, result);
|
||||
results.second.push_back(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( auto pHandle = SubViewAdjustHandle::HitTest(
|
||||
mAdjustHandle,
|
||||
*pWaveTrackView, *this, state ) )
|
||||
@ -964,6 +1008,11 @@ void WaveTrackView::DoSetDisplay(Display display, bool exclusive)
|
||||
}
|
||||
|
||||
auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
||||
{
|
||||
return GetSubViews(&rect);
|
||||
}
|
||||
|
||||
auto WaveTrackView::GetSubViews(const wxRect* rect) -> Refinement
|
||||
{
|
||||
BuildSubViews();
|
||||
|
||||
@ -974,41 +1023,51 @@ auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
||||
std::vector< Item > items;
|
||||
size_t ii = 0;
|
||||
float total = 0;
|
||||
WaveTrackSubViews::ForEach( [&]( WaveTrackSubView &subView ){
|
||||
auto &placement = mPlacements[ii];
|
||||
WaveTrackSubViews::ForEach([&](WaveTrackSubView& subView) {
|
||||
auto& placement = mPlacements[ii];
|
||||
auto index = placement.index;
|
||||
auto fraction = placement.fraction;
|
||||
if ( index >= 0 && fraction > 0.0 )
|
||||
if (index >= 0 && fraction > 0.0)
|
||||
total += fraction,
|
||||
items.push_back( { index, fraction, subView.shared_from_this() } );
|
||||
items.push_back({ index, fraction, subView.shared_from_this() });
|
||||
++ii;
|
||||
} );
|
||||
std::sort( items.begin(), items.end(), [](const Item &a, const Item &b){
|
||||
});
|
||||
std::sort(items.begin(), items.end(), [](const Item& a, const Item& b) {
|
||||
return a.index < b.index;
|
||||
} );
|
||||
});
|
||||
|
||||
// Remove views we don't need
|
||||
auto begin = items.begin(), end = items.end(),
|
||||
newEnd = std::remove_if( begin, end,
|
||||
[]( const Item &item ){ return !item.pView; } );
|
||||
items.erase( newEnd, end );
|
||||
newEnd = std::remove_if(begin, end,
|
||||
[](const Item& item) { return !item.pView; });
|
||||
items.erase(newEnd, end);
|
||||
|
||||
// Assign coordinates, redenominating to the total height,
|
||||
// storing integer values
|
||||
Refinement results;
|
||||
results.reserve( items.size() );
|
||||
const auto top = rect.GetTop();
|
||||
const auto height = rect.GetHeight();
|
||||
float partial = 0;
|
||||
wxCoord lastCoord = 0;
|
||||
for ( const auto &item : items ) {
|
||||
wxCoord newCoord = top + (partial / total) * height;
|
||||
results.emplace_back( newCoord, item.pView );
|
||||
partial += item.fraction;
|
||||
}
|
||||
|
||||
// Cache for the use of sub-view dragging
|
||||
mLastHeight = height;
|
||||
if (rect != nullptr)
|
||||
{
|
||||
// Assign coordinates, redenominating to the total height,
|
||||
// storing integer values
|
||||
results.reserve(items.size());
|
||||
const auto top = rect->GetTop();
|
||||
const auto height = rect->GetHeight();
|
||||
float partial = 0;
|
||||
wxCoord lastCoord = 0;
|
||||
for (const auto& item : items) {
|
||||
wxCoord newCoord = top + (partial / total) * height;
|
||||
results.emplace_back(newCoord, item.pView);
|
||||
partial += item.fraction;
|
||||
}
|
||||
|
||||
// Cache for the use of sub-view dragging
|
||||
mLastHeight = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::transform(items.begin(), items.end(), std::back_inserter(results), [](const auto& item) {
|
||||
return std::make_pair(0, item.pView);
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::weak_ptr<UIHandle> mCloseHandle;
|
||||
std::weak_ptr<UIHandle> mResizeHandle;
|
||||
std::weak_ptr<UIHandle> mAdjustHandle;
|
||||
std::weak_ptr<UIHandle> mRearrangeHandle;
|
||||
std::weak_ptr<CutlineHandle> mCutlineHandle;
|
||||
@ -77,6 +78,8 @@ class TENACITY_DLL_API WaveTrackView final
|
||||
WaveTrackView &operator=( const WaveTrackView& ) = delete;
|
||||
|
||||
public:
|
||||
static constexpr int kChannelSeparatorThickness{ 8 };
|
||||
|
||||
using Display = WaveTrackViewConstants::Display;
|
||||
|
||||
static WaveTrackView &Get( WaveTrack &track );
|
||||
@ -128,6 +131,15 @@ public:
|
||||
|
||||
std::weak_ptr<WaveClip> GetSelectedClip();
|
||||
|
||||
// Returns a visible subset of subviews, sorted in the same
|
||||
// order as they are supposed to be displayed
|
||||
|
||||
|
||||
// Get the visible sub-views,
|
||||
// if rect is provided then result will contain
|
||||
// y coordinate for each subview within this rect
|
||||
Refinement GetSubViews(const wxRect* rect = nullptr);
|
||||
|
||||
private:
|
||||
void BuildSubViews() const;
|
||||
void DoSetDisplay(Display display, bool exclusive = true);
|
||||
@ -143,8 +155,7 @@ private:
|
||||
override;
|
||||
|
||||
// TrackView implementation
|
||||
// Get the visible sub-views with top y coordinates
|
||||
Refinement GetSubViews( const wxRect &rect ) override;
|
||||
Refinement GetSubViews(const wxRect& rect) override;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<CommonTrackCell> DoGetAffordanceControls() override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user