mirror of
https://github.com/cookiengineer/audacity
synced 2025-09-16 16:20:50 +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 "../../../../TrackPanelMouseEvent.h"
|
||||||
#include "../../../../TrackArtist.h"
|
#include "../../../../TrackArtist.h"
|
||||||
#include "../../../../TrackPanelDrawingContext.h"
|
#include "../../../../TrackPanelDrawingContext.h"
|
||||||
|
#include "../../../../TrackPanelResizeHandle.h"
|
||||||
#include "../../../../ViewInfo.h"
|
#include "../../../../ViewInfo.h"
|
||||||
#include "../../../../WaveTrack.h"
|
#include "../../../../WaveTrack.h"
|
||||||
#include "../../../../WaveClip.h"
|
#include "../../../../WaveClip.h"
|
||||||
@ -34,14 +35,29 @@ std::vector<UIHandlePtr> WaveTrackAffordanceControls::HitTest(const TrackPanelMo
|
|||||||
|
|
||||||
std::vector<UIHandlePtr> results;
|
std::vector<UIHandlePtr> results;
|
||||||
|
|
||||||
const auto track = FindTrack();
|
auto px = state.state.m_x;
|
||||||
|
auto py = state.state.m_y;
|
||||||
const auto waveTrack = std::static_pointer_cast<WaveTrack>(track->SubstitutePendingChangedTrack());
|
|
||||||
|
|
||||||
const auto rect = state.rect;
|
const auto rect = state.rect;
|
||||||
|
|
||||||
auto px = state.state.m_x;
|
const auto track = FindTrack();
|
||||||
auto py = state.state.m_y;
|
|
||||||
|
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);
|
auto& zoomInfo = ViewInfo::Get(*pProject);
|
||||||
for (const auto& clip : waveTrack->GetClips())
|
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<WaveClip> mFocusClip;
|
||||||
std::weak_ptr<AffordanceHandle> mAffordanceHandle;
|
std::weak_ptr<AffordanceHandle> mAffordanceHandle;
|
||||||
|
std::weak_ptr<UIHandle> mResizeHandle;
|
||||||
public:
|
public:
|
||||||
WaveTrackAffordanceControls(const std::shared_ptr<Track>& pTrack);
|
WaveTrackAffordanceControls(const std::shared_ptr<Track>& pTrack);
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ Paul Licameli split from TrackPanel.cpp
|
|||||||
#include "../../../../TrackArtist.h"
|
#include "../../../../TrackArtist.h"
|
||||||
#include "../../../../TrackPanelDrawingContext.h"
|
#include "../../../../TrackPanelDrawingContext.h"
|
||||||
#include "../../../../TrackPanelMouseEvent.h"
|
#include "../../../../TrackPanelMouseEvent.h"
|
||||||
|
#include "../../../../TrackPanelResizeHandle.h"
|
||||||
#include "../../../../ViewInfo.h"
|
#include "../../../../ViewInfo.h"
|
||||||
#include "../../../../prefs/TracksPrefs.h"
|
#include "../../../../prefs/TracksPrefs.h"
|
||||||
|
|
||||||
@ -703,6 +704,49 @@ std::pair<
|
|||||||
mCloseHandle,
|
mCloseHandle,
|
||||||
*pWaveTrackView, *this, state ) )
|
*pWaveTrackView, *this, state ) )
|
||||||
results.second.push_back( pHandle );
|
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(
|
if ( auto pHandle = SubViewAdjustHandle::HitTest(
|
||||||
mAdjustHandle,
|
mAdjustHandle,
|
||||||
*pWaveTrackView, *this, state ) )
|
*pWaveTrackView, *this, state ) )
|
||||||
@ -964,6 +1008,11 @@ void WaveTrackView::DoSetDisplay(Display display, bool exclusive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
||||||
|
{
|
||||||
|
return GetSubViews(&rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WaveTrackView::GetSubViews(const wxRect* rect) -> Refinement
|
||||||
{
|
{
|
||||||
BuildSubViews();
|
BuildSubViews();
|
||||||
|
|
||||||
@ -974,41 +1023,51 @@ auto WaveTrackView::GetSubViews( const wxRect &rect ) -> Refinement
|
|||||||
std::vector< Item > items;
|
std::vector< Item > items;
|
||||||
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,
|
||||||
items.push_back( { index, fraction, subView.shared_from_this() } );
|
items.push_back({ index, fraction, subView.shared_from_this() });
|
||||||
++ii;
|
++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;
|
return a.index < b.index;
|
||||||
} );
|
});
|
||||||
|
|
||||||
// Remove views we don't need
|
// Remove views we don't need
|
||||||
auto begin = items.begin(), end = items.end(),
|
auto begin = items.begin(), end = items.end(),
|
||||||
newEnd = std::remove_if( begin, end,
|
newEnd = std::remove_if(begin, end,
|
||||||
[]( const Item &item ){ return !item.pView; } );
|
[](const Item& item) { return !item.pView; });
|
||||||
items.erase( newEnd, end );
|
items.erase(newEnd, end);
|
||||||
|
|
||||||
// Assign coordinates, redenominating to the total height,
|
|
||||||
// storing integer values
|
|
||||||
Refinement results;
|
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
|
if (rect != nullptr)
|
||||||
mLastHeight = height;
|
{
|
||||||
|
// 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;
|
return results;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<UIHandle> mCloseHandle;
|
std::weak_ptr<UIHandle> mCloseHandle;
|
||||||
|
std::weak_ptr<UIHandle> mResizeHandle;
|
||||||
std::weak_ptr<UIHandle> mAdjustHandle;
|
std::weak_ptr<UIHandle> mAdjustHandle;
|
||||||
std::weak_ptr<UIHandle> mRearrangeHandle;
|
std::weak_ptr<UIHandle> mRearrangeHandle;
|
||||||
std::weak_ptr<CutlineHandle> mCutlineHandle;
|
std::weak_ptr<CutlineHandle> mCutlineHandle;
|
||||||
@ -77,6 +78,8 @@ class TENACITY_DLL_API WaveTrackView final
|
|||||||
WaveTrackView &operator=( const WaveTrackView& ) = delete;
|
WaveTrackView &operator=( const WaveTrackView& ) = delete;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static constexpr int kChannelSeparatorThickness{ 8 };
|
||||||
|
|
||||||
using Display = WaveTrackViewConstants::Display;
|
using Display = WaveTrackViewConstants::Display;
|
||||||
|
|
||||||
static WaveTrackView &Get( WaveTrack &track );
|
static WaveTrackView &Get( WaveTrack &track );
|
||||||
@ -128,6 +131,15 @@ public:
|
|||||||
|
|
||||||
std::weak_ptr<WaveClip> GetSelectedClip();
|
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:
|
private:
|
||||||
void BuildSubViews() const;
|
void BuildSubViews() const;
|
||||||
void DoSetDisplay(Display display, bool exclusive = true);
|
void DoSetDisplay(Display display, bool exclusive = true);
|
||||||
@ -143,8 +155,7 @@ private:
|
|||||||
override;
|
override;
|
||||||
|
|
||||||
// TrackView implementation
|
// TrackView implementation
|
||||||
// Get the visible sub-views with top y coordinates
|
Refinement GetSubViews(const wxRect& rect) override;
|
||||||
Refinement GetSubViews( const wxRect &rect ) override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<CommonTrackCell> DoGetAffordanceControls() override;
|
std::shared_ptr<CommonTrackCell> DoGetAffordanceControls() override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user