13#include <unordered_set>
19#include <wx/graphics.h>
25#include "../../../../../images/Cursors.h"
29#include "../../../../HitTestResult.h"
31#include "../../../../RefreshCode.h"
33#include "../../../../TrackArtist.h"
34#include "../../../../TrackPanel.h"
36#include "../../../../TrackPanelDrawingContext.h"
37#include "../../../../TrackPanelMouseEvent.h"
38#include "../../../../TrackPanelResizeHandle.h"
40#include "../../../../prefs/TracksPrefs.h"
42#include "../../../ui/TimeShiftHandle.h"
43#include "../../../ui/ButtonHandle.h"
44#include "../../../ui/CommonTrackInfo.h"
46#include "../WaveTrackUtils.h"
62 std::unique_ptr<Cloneable<>>
Clone()
const {
63 return std::make_unique<PlacementArray>(*
this); }
65 bool mMultiView{
false };
69key { [](
auto &) {
return std::make_unique<PlacementArray>(); } };
80 return Get(
const_cast<Track &
>(track));
86 auto &waveTrack = *std::dynamic_pointer_cast<WaveTrack>(
FindTrack());
97 auto &waveTrack = *std::dynamic_pointer_cast<WaveTrack>(
FindTrack());
130 return placement.index < 0 || placement.fraction <= 0;
132 const auto comp = [
this](
size_t ii,
size_t jj ){
134 bool iInvisible = invisible( pi );
137 bool jInvisible = invisible( pj );
140 if ( iInvisible != jInvisible )
142 else if ( !iInvisible )
143 return pi.index < pj.index;
150 auto first = std::find_if(
begin,
end, [
this](
size_t ii){
161 bool rotated =
false;
186 for (
auto pIter = pBegin; pIter != pFirst; ++pIter ) {
188 placement.index = -1;
189 placement.fraction = 0;
192 for (
auto pIter = pFirst; pIter != pEnd; ++pIter )
200 auto iter = std::find_if(
begin,
end, [&](
size_t ii){
201 return mSubViews[ ii ].get() == &subView;
206 std::pair< size_t, bool >
208 wxCoord yy, wxCoord top, wxCoord height)
212 if ( index < (
int)
size ) {
214 if ( yy >= 0 && yy < HotZoneSize && index > 0 )
215 return { index,
true };
220 return { index,
false };
222 return {
size,
false };
231 total += std::max( 0.f, placement.fraction );
234 wxCoord lastCoord = 0;
235 std::vector<wxCoord> result;
238 auto fraction = std::max( 0.f, placement.fraction );
239 wxCoord coord = ( (partial + fraction ) / total ) * totalHeight;
240 auto height = coord - lastCoord;
241 result.emplace_back( height );
251 auto pView =
mwView.lock();
253 auto pTrack =
static_cast< WaveTrack*
>( pView->FindTrack().get() );
282 auto hit = adjuster.
HitTest( subView,
283 state.
state.GetY(), state.
rect.GetTop(), state.
rect.GetHeight() );
284 auto index = hit.first;
286 if ( index < adjuster.mPermutation.size() ) {
287 auto result = std::make_shared< SubViewAdjustHandle >(
288 std::move( adjuster ), index, view.
GetLastHeight(), hit.second
299 wxCoord viewHeight,
bool top )
313 return pView->FindChannel();
322 const auto size = permutation.size();
326 if (event.
event.LeftDClick()) {
328 if ( placement.index >= 0 )
329 placement.fraction = 1.0f;
331 placement.fraction = 0.0f;
340 const auto &rect =
event.rect;
341 const auto height = rect.GetHeight();
350 for (; index !=
end; ++index)
358 mYMax = rect.GetBottom();
362 mOrigY = rect.GetBottom();
363 mYMin = rect.GetTop();
379 const auto delta = newY -
mOrigY;
380 wxCoord newHeight =
mTop
384 wxASSERT( newHeight >= 0 && newHeight <=
mTotalHeight );
392 myPlacement.fraction = newHeight;
396 const auto adjustHeight = [&](
size_t ii) {
404 auto &fraction = placement.fraction;
406 if (excess > oldFraction) {
407 excess -= oldFraction, fraction = 0;
411 auto newFraction = oldFraction - excess;
414 myPlacement.fraction += newFraction;
418 fraction = newFraction;
425 if ( adjustHeight( ii ) )
433 if ( adjustHeight( ii ) )
446 static auto resizeCursor =
447 ::MakeCursor(wxCURSOR_ARROW, SubViewsCursorXpm, 16, 16);
450"Click and drag to adjust sizes of sub-views, double-click to split evenly"),
457 wxWindow *pParent)
override
501 if ( adjuster.NVisible() < 2 )
504 auto relX = state.
state.GetX() - state.
rect.GetLeft();
508 auto index = adjuster.FindIndex( subView );
515 auto relY = state.
state.GetY() - state.
rect.GetTop();
516 auto height = state.
rect.GetHeight();
518 ( ( 3 * relY < height ) && index > 0 )
520 ( ( 3 * relY > 2 * height ) &&
521 index < adjuster.mPermutation.size() - 1 )
526 auto result = std::make_shared< SubViewRearrangeHandle >(
527 std::move( adjuster ),
547 return pView->FindChannel();
556 const auto size = permutation.size();
563 wxCoord heightAbove = 0;
567 mTopY =
event.rect.GetTop() - heightAbove;
580 auto yy =
event.event.GetY();
586 for (
auto nn =
mHeights.size(); ii < nn; ++ii ) {
647 static auto hoverCursor =
648 ::MakeCursor(wxCURSOR_HAND, RearrangeCursorXpm, 16, 16);
649 static auto clickedCursor =
650 ::MakeCursor(wxCURSOR_HAND, RearrangingCursorXpm, 16, 16);
652 XO(
"Click and drag to rearrange sub-views"),
653 Clicked() ? &*clickedCursor : &*hoverCursor,
654 XO(
"Rearrange sub-views")
660 wxWindow *pParent)
override
702 if ( adjuster.NVisible() < 2 )
706 if ( !rect.Contains( state.
state.GetPosition() ) )
708 auto index = adjuster.FindIndex( subView );
709 auto result = std::make_shared<SubViewCloseHandle>(
710 std::move( adjuster ), index, view.
FindTrack(), rect );
717 const std::shared_ptr<Track> &pTrack,
const wxRect &rect )
725 const wxMouseEvent &event,
AudacityProject *pProject, wxWindow *pParent)
731 myPlacement.fraction = 0;
739 return XO(
"Close sub-view");
760 std::vector<UIHandlePtr>
764 const std::shared_ptr<WaveTrack> &wt)
767 state, pProject, currentTool, bMultiTool, wt, *
this);
772 if ( pWaveChannelView && !state.
state.HasModifiers() ) {
775 *pWaveChannelView, *
this, state ) )
776 results.second.push_back( pHandle );
779 if(channels.size() > 1) {
782 auto subviews = pWaveChannelView->GetSubViews();
783 auto currentSubview = std::find_if(subviews.begin(), subviews.end(),
784 [self = shared_from_this()](
const auto& p){
785 return self == p.second;
787 if (currentSubview != subviews.end())
789 auto currentSubviewIndex = std::distance(subviews.begin(), currentSubview);
791 const auto py = state.
state.GetY();
792 const auto topBorderHit = std::abs(py - state.
rect.GetTop())
794 const auto bottomBorderHit = std::abs(py - state.
rect.GetBottom())
797 auto currentChannel = channels.find(wt.get());
798 auto currentChannelIndex = std::distance(channels.begin(), currentChannel);
801 ((currentChannelIndex != channels.size() - 1)
802 && (currentSubviewIndex ==
static_cast<int>(subviews.size()) - 1)
806 ((currentChannelIndex != 0) && currentSubviewIndex == 0 && topBorderHit))
810 auto it = bottomBorderHit ? currentChannel : currentChannel.advance(-1);
811 auto result = std::make_shared<TrackPanelResizeHandle>(
812 (*it)->GetChannel(0), py);
814 results.second.push_back(result);
821 *pWaveChannelView, *
this, state ) )
822 results.second.push_back( pHandle );
825 *pWaveChannelView, *
this, state ) )
826 results.second.push_back( pHandle );
828 if( pWaveChannelView )
832 *pWaveChannelView, pProject, state))
833 results.second.push_back(pHandle);
839 results.second.push_back(result);
849 auto &dc = context.
dc;
852 const auto &zoomInfo = *artist->pZoomInfo;
854#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
858 bool highlightLoc =
false;
859#ifdef EXPERIMENTAL_TRACK_PANEL_HIGHLIGHTING
861 target2 && target2->
GetTrack().get() == &track &&
862 target2->GetLocation() == loc;
864 const int xx = zoomInfo.TimeToPosition(loc.pos);
865 if (xx >= 0 && xx < rect.width) {
867 AColor::Line(dc, (
int) (rect.x + xx - 1), rect.y, (
int) (rect.x + xx - 1), rect.y + rect.height);
869 AColor::Line(dc, (
int) (rect.x + xx), rect.y, (
int) (rect.x + xx), rect.y + rect.height);
871 AColor::Line(dc, (
int) (rect.x + xx + 1), rect.y, (
int) (rect.x + xx + 1), rect.y + rect.height);
882 const wxRect &rect,
const wxPoint *pPosition,
AudacityProject *pProject)
883 -> std::vector<MenuItem>
886 if(pTrack !=
nullptr && pPosition !=
nullptr)
889 const auto t = viewInfo.PositionToTime(pPosition->x, rect.x);
890 if((pTrack->IsSelected() &&
891 t > viewInfo.selectedRegion.t0() && t < viewInfo.selectedRegion.t1() &&
892 !pTrack->GetClipsIntersecting(viewInfo.selectedRegion.t0(), viewInfo.selectedRegion.t1()).empty())
894 pTrack->GetClipAtTime(t))
900 { L
"Paste",
XO(
"Paste") },
902 { L
"TrackMute",
XO(
"Mute/Unmute Track") },
927 const std::shared_ptr<Track> &pTrack,
size_t channel
934 waveChannelView.
FindTrack(), waveChannelView.GetChannelIndex() }
937 waveChannelView.shared_from_this() );
957 auto srcSubViewsPtrs =
959 auto destSubViewsPtrs =
961 wxASSERT(srcSubViewsPtrs.size() == destSubViewsPtrs.size());
963 for(
auto i = 0; i != srcSubViewsPtrs.size(); i++){
964 srcSubViewsPtrs[i]->CopyToSubView(destSubViewsPtrs[i].get());
978std::pair< bool, std::vector<UIHandlePtr> >
982 const std::shared_ptr<WaveTrack> &pTrack,
993 std::vector<UIHandlePtr> results;
997 for (
auto& clip : pTrack->GetClips())
1005 waveChannelView.mAffordanceHandle,
1006 std::make_shared<WaveTrackAffordanceHandle>(pTrack, clip)
1012 if (bMultiTool && st.
state.CmdDown()) {
1019 results.push_back(result);
1020 return {
true, results };
1023 return {
false, results };
1032 using Pair = std::pair<int, WaveChannelSubView::Type>;
1033 std::vector< Pair > pairs;
1037 auto &placement = placements[ii];
1038 if (placement.fraction > 0)
1039 pairs.emplace_back(placement.index, subView.
SubViewType());
1042 std::sort( pairs.begin(), pairs.end() );
1043 std::vector<WaveChannelSubView::Type> results;
1044 for (
const auto &pair : pairs)
1045 results.push_back(pair.second);
1068 auto &foundPlacement = placements[found];
1069 if ( foundPlacement.fraction > 0.0 ) {
1076 auto index = foundPlacement.index;
1077 foundPlacement = { -1, 0.0 };
1079 for (
auto &placement : placements ) {
1080 if ( placement.index > index )
1092 for (
const auto &placement : placements ) {
1093 if ( placement.fraction > 0.0 && placement.index >= 0 ) {
1094 total += placement.fraction;
1095 greatest = std::max( greatest, placement.index );
1101 foundPlacement = { greatest + 1, total / nn };
1120 std::vector<std::pair<WaveChannelViewConstants::Display, size_t>> pairs;
1122 pairs.push_back({ subView.
SubViewType().
id, ii++ });
1124 std::sort( pairs.begin(), pairs.end() );
1128 for (
const auto &pair : pairs ) {
1129 auto &placement = placements[ pair.second ];
1130 if (pair.first == display) {
1132 placement = { 0, 1.0 };
1134 else if( exclusive )
1136 placement = { -1, 0.0 };
1142 placement = { jj++, 1.0 };
1147 template<
typename Iter,
typename Comp>
1152 it = std::find_if(
begin,
end, comp);
1166 auto waveTrack = std::dynamic_pointer_cast<WaveTrack>(
FindTrack());
1169 auto clips = waveTrack->SortedClipArray();
1177 return other->GetPlayStartTime() >= viewInfo.selectedRegion.t1();
1183 return other->GetPlayStartTime() <= viewInfo.selectedRegion.t0();
1191 auto it = std::find(clips.begin(), clips.end(), clip);
1192 auto index = std::distance(clips.begin(), it);
1199 "%s, %d of %d clip",
1200 "%s, %d of %d clips",
1204 static_cast<int>(index + 1),
1205 static_cast<int>(clips.size())
1214 return GetSubViews(&rect);
1223 int index;
float fraction; std::shared_ptr<ChannelView> pView;
1225 std::vector< Item > items;
1228 const auto &placements = DoGetPlacements();
1230 auto& placement = placements[ii];
1231 auto index = placement.index;
1232 auto fraction = placement.fraction;
1233 if (index >= 0 && fraction > 0.0)
1235 items.push_back({ index, fraction, subView.shared_from_this() });
1238 std::sort(items.begin(), items.end(), [](
const Item& a,
const Item& b) {
1239 return a.index < b.index;
1243 auto begin = items.begin(),
end = items.end(),
1244 newEnd = std::remove_if(
begin,
end,
1245 [](
const Item& item) {
return !item.pView; });
1246 items.erase(newEnd,
end);
1250 if (rect !=
nullptr)
1254 results.reserve(items.size());
1255 const auto top = rect->GetTop();
1256 const auto height = rect->GetHeight();
1258 wxCoord lastCoord = 0;
1259 for (
const auto& item : items) {
1260 wxCoord newCoord = top + (partial / total) * height;
1261 results.emplace_back(newCoord, item.pView);
1262 partial += item.fraction;
1266 mLastHeight = height;
1270 std::transform(items.begin(), items.end(), std::back_inserter(results), [](
const auto& item) {
1271 return std::make_pair(0, item.pView);
1287 wxKeyEvent& event,
ViewInfo& viewInfo, wxWindow* pParent,
1292 for (
auto pChannel : pTrack->Channels()) {
1296 for (
auto &subView : waveChannelView.GetSubViews()) {
1298 wxASSERT(!event.GetSkipped());
1299 result |= subView.second->CaptureKey(event, viewInfo, pParent,
project);
1300 if (!event.GetSkipped()) {
1309 if (
auto affordance = waveChannelView.GetAffordanceControls()) {
1310 result |= affordance->CaptureKey(event, viewInfo, pParent,
project);
1311 if (!event.GetSkipped()) {
1319 switch (event.GetKeyCode())
1325 event, viewInfo, pParent,
project);
1328 if (!event.GetSkipped()) {
1336 wxKeyEvent& event,
ViewInfo& viewInfo, wxWindow* pParent,
1341 if (
auto pWaveChannelView =
1344 if (event.GetKeyCode() == WXK_TAB)
1350 result |= pWaveChannelView->CommonChannelView::KeyDown(
1351 event, viewInfo, pParent,
project);
1354 result |= delegate->KeyDown(event, viewInfo, pParent,
project);
1363 wxKeyEvent& event,
ViewInfo& viewInfo, wxWindow* pParent,
1368 if (
auto pWaveChannelView =
1370 result |= pWaveChannelView->CommonChannelView::Char(
1371 event, viewInfo, pParent,
project);
1373 result |= delegate->Char(event, viewInfo, pParent,
project);
1385 if (
auto pWaveChannelView =
1387 result = pWaveChannelView->CommonChannelView::LoseFocus(
project);
1389 result = delegate->LoseFocus(
project);
1399 const auto pLeader =
static_cast<WaveTrack*
>(
1402 if (
const auto affordance =
1403 std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
1404 channelView.GetAffordanceControls()).get()
1405 ; affordance && (affordance->*pmf)(
project)
1425 const ZoomInfo& zoomInfo,
const wxRect& viewRect)
1430 bool showSamples{
false };
1436 const ZoomInfo& zoomInfo,
const wxRect& viewRect)
1438 bool showSamples{
false };
1443 return clipRect.Inflate(2, 0);
1447 const ZoomInfo& viewInfo,
const wxRect& viewRect,
const wxPoint& pos)
1464std::vector<std::shared_ptr<WaveChannelSubView>>
1469 std::vector<std::shared_ptr<WaveChannelSubView>> results;
1471 results.push_back(std::static_pointer_cast<WaveChannelSubView>(
1472 subView.shared_from_this()));
1480 if (track->IsLeader())
1496std::shared_ptr<CommonTrackCell>
1526 constexpr double pixelsOffset { 2 };
1530 return pixelsOffset /
1543 const auto trackRectT1 = zoomInfo.
PositionToTime(viewRect.width, 0,
true);
1544 return viewRect.width / (trackRectT1 - h);
1548 int sampleRate,
double stretchRatio,
double pixelsPerSecond)
1550 const auto secondsPerSample = stretchRatio /
sampleRate;
1551 const auto pixelsPerSample = pixelsPerSecond * secondsPerSample;
1552 return pixelsPerSample > 0.5;
1558) : trackRectT0 { zoomInfo.PositionToTime(0, 0, true) }
1561 clip.
GetRate(), clip.GetStretchRatio(), averagePixelsPerSecond) }
1563 const auto trackRectT1 = zoomInfo.
PositionToTime(rect.width, 0,
true);
1571 const auto tpost = trackRectT1 - playStartTime;
1577 t0 = std::max(tpre, .0);
1603 wxInt64 time64 = zoomInfo.
TimeToPosition(playStartTime, 0,
true);
1620 const int hiddenRightOffset = (time64 < rect.width) ? (
int)time64 : rect.width;
1634 wxInt64 time64 = zoomInfo.
TimeToPosition(playStartTime, 0,
false);
1637 leftOffset = (time64 < rect.width) ? (
int)time64 : rect.width;
1651 const int distortedRightOffset = (time64 < rect.width) ? (
int)time64 : rect.width;
1658 const ZoomInfo& zoomInfo,
const wxRect& viewRect,
bool* outShowSamples)
1663 const auto clipEndingAdjustment =
1665 if (outShowSamples !=
nullptr)
1667 constexpr auto edgeLeft =
1669 constexpr auto edgeRight =
1671 const auto left = std::clamp(
1673 edgeLeft, edgeRight);
1674 const auto right = std::clamp(
1677 clipEndingAdjustment,
1679 edgeLeft, edgeRight);
1685 static_cast<int>(left), viewRect.y,
1686 std::max(1,
static_cast<int>(right - left)), viewRect.height);
1704 if (
auto affordance = std::dynamic_pointer_cast<WaveTrackAffordanceControls>(
GetAffordanceControls()))
1707 if(
auto interval = *affordance->GetSelectedInterval())
1709 return interval->GetClip(0);
1726 auto &placements = pThis->DoGetPlacements();
1727 if (placements.empty()) {
1730 auto pTrack = pThis->FindTrack();
1734 pThis->SetMultiView(
true );
1738 pThis->DoSetDisplay( display, !multi );
1745 const wxRect &rect,
unsigned iPass)
std::shared_ptr< UIHandle > UIHandlePtr
#define XP(sing, plur, n)
@ Grouped
Can be part of a group.
std::unique_ptr< wxCursor > MakeCursor(int WXUNUSED(CursorId), const char *const pXpm[36], int HotX, int HotY)
std::shared_ptr< Subclass > AssignUIHandlePtr(std::weak_ptr< Subclass > &holder, const std::shared_ptr< Subclass > &pNew)
DEFINE_ATTACHED_VIRTUAL_OVERRIDE(DoGetWaveChannelView)
std::vector< std::shared_ptr< WaveChannelSubView > > WaveChannelSubViewPtrs
constexpr int kClipDetailedViewMinimumWidth
std::vector< WaveChannelSubViewPlacement > WaveChannelSubViewPlacements
std::vector< CommonTrackPanelCell::MenuItem > GetWaveClipMenuItems()
WaveTrackLocations FindWaveTrackLocations(const WaveTrack &track)
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
std::shared_ptr< ChannelType > GetChannel(size_t iChannel)
Retrieve a channel, cast to the given type.
static ChannelView * Find(Channel *pChannel)
static ChannelView & Get(Channel &channel)
bool GetMinimized() const
virtual void DoSetMinimized(bool isMinimized)
std::vector< std::pair< wxCoord, std::shared_ptr< ChannelView > > > Refinement
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
size_t size() const
How many attachment pointers are in the Site.
ClientData * FindIf(const Function &function)
Return pointer to first attachment in this that is not null and satisfies a predicate,...
void ForEach(const Function &function)
Invoke function on each ClientData object that has been created in this.
void BuildAll()
For each RegisteredFactory, if the corresponding attachment is absent in this, build and store it.
virtual double GetPlayEndTime() const =0
virtual int GetRate() const =0
virtual double GetStretchRatio() const =0
virtual double GetPlayStartTime() const =0
Implements some hit-testing shared by many ChannelView subtypes.
std::weak_ptr< TimeShiftHandle > mTimeShiftHandle
void Reparent(const std::shared_ptr< Track > &parent) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
size_t GetChannelIndex() const
std::shared_ptr< Track > FindTrack()
std::shared_ptr< WaveTrack > GetTrack()
static UIHandlePtr HitTest(std::weak_ptr< CutlineHandle > &holder, const wxMouseState &state, const wxRect &rect, const AudacityProject *pProject, std::shared_ptr< WaveTrack > pTrack)
bool setTimes(double t0, double t1)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
SubViewAdjuster mAdjuster
static UIHandlePtr HitTest(std::weak_ptr< SubViewAdjustHandle > &holder, WaveChannelView &view, WaveChannelSubView &subView, const TrackPanelMouseState &state)
std::shared_ptr< const Channel > FindChannel() const override
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *) override
SubViewAdjustHandle(SubViewAdjuster &&adjuster, size_t subViewIndex, wxCoord viewHeight, bool top)
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
std::vector< wxCoord > mOrigHeights
Result Cancel(AudacityProject *) override
SubViewAdjuster mAdjuster
TranslatableString Tip(const wxMouseState &state, AudacityProject &project) const override
static wxRect GetButtonRect(const wxRect &rect)
SubViewCloseHandle(SubViewAdjuster &&adjuster, size_t index, const std::shared_ptr< Track > &pTrack, const wxRect &rect)
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
Result CommitChanges(const wxMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
static UIHandlePtr HitTest(std::weak_ptr< SubViewCloseHandle > &holder, WaveChannelView &view, WaveChannelSubView &subView, const TrackPanelMouseState &state)
SubViewRearrangeHandle(SubViewAdjuster &&adjuster, size_t subViewIndex, wxCoord viewHeight)
DragChoice_t DragChoice(const TrackPanelMouseEvent &event) const
HitTestPreview Preview(const TrackPanelMouseState &state, AudacityProject *) override
Result Release(const TrackPanelMouseEvent &event, AudacityProject *pProject, wxWindow *pParent) override
Result Click(const TrackPanelMouseEvent &event, AudacityProject *pProject) override
static UIHandlePtr HitTest(std::weak_ptr< SubViewRearrangeHandle > &holder, WaveChannelView &view, WaveChannelSubView &subView, const TrackPanelMouseState &state)
std::vector< wxCoord > mHeights
SubViewAdjuster mAdjuster
Result Drag(const TrackPanelMouseEvent &event, AudacityProject *) override
std::shared_ptr< const Channel > FindChannel() const override
Result Cancel(AudacityProject *) override
static UIHandlePtr HitAnywhere(std::weak_ptr< TimeShiftHandle > &holder, const std::shared_ptr< Track > &pTrack, bool gripHit)
static TrackArtist * Get(TrackPanelDrawingContext &)
Abstract base class for an object holding data associated with points on a time axis.
std::shared_ptr< Subclass > SharedPointer()
ChannelGroupData & GetGroupData()
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
virtual unsigned CaptureKey(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project)
virtual void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass)
static WaveChannelViewConstants::Display ViewModeChoice()
Holds a msgid for the translation catalog; may also bind format arguments.
Short-lived drawing and event-handling object associated with a TrackPanelCell.
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
std::weak_ptr< SubViewAdjustHandle > mAdjustHandle
virtual const Type & SubViewType() const =0
std::weak_ptr< CutlineHandle > mCutlineHandle
virtual void CopyToSubView(WaveChannelSubView *destSubView) const
std::weak_ptr< TrackPanelResizeHandle > mResizeHandle
std::weak_ptr< WaveChannelView > mwWaveChannelView
std::weak_ptr< WaveClipAdjustBorderHandle > mClipBorderAdjustHandle
WaveChannelSubView(WaveChannelView &waveChannelView)
std::pair< bool, std::vector< UIHandlePtr > > DoDetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool, const std::shared_ptr< WaveTrack > &wt)
std::weak_ptr< SubViewCloseHandle > mCloseHandle
std::weak_ptr< WaveChannelView > GetWaveChannelView() const
static void DrawBoldBoundaries(TrackPanelDrawingContext &context, const WaveTrack &track, const wxRect &rect)
std::weak_ptr< SubViewRearrangeHandle > mRearrangeHandle
std::vector< MenuItem > GetMenuItems(const wxRect &rect, const wxPoint *pPosition, AudacityProject *pProject) override
Return a list of items for DoContextMenu() (empties for separators)
std::vector< std::shared_ptr< WaveChannelSubView > > GetAllSubViews()
void SetDisplay(Display display, bool exclusive=true)
std::shared_ptr< CommonTrackCell > GetAffordanceControls() override
const WaveChannelSubViewPlacements & SavePlacements() const
bool GetMultiView() const
void BuildSubViews() const
void Reparent(const std::shared_ptr< Track > &parent) override
Object may be shared among tracks but hold a special back-pointer to one of them; reassign it.
std::shared_ptr< ChannelVRulerControls > DoGetVRulerControls() override
unsigned LoseFocus(AudacityProject *project) override
unsigned Char(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
static WaveChannelView * Find(WaveChannel *pChannel)
static wxRect ClipHitTestArea(const WaveClip &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect)
std::weak_ptr< WaveClip > GetSelectedClip()
std::shared_ptr< CommonTrackCell > mpAffordanceCellControl
bool ToggleSubView(Display id)
WaveChannelView(const WaveChannelView &)=delete
std::weak_ptr< TrackPanelCell > mKeyEventDelegate
static bool ClipDetailsVisible(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect)
unsigned KeyDown(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
std::vector< UIHandlePtr > DetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool) override
~WaveChannelView() override
static WaveChannelView & Get(WaveChannel &channel)
bool CopySelectedText(AudacityProject &project)
WaveChannelSubViewPlacements & DoGetPlacements()
static bool HitTest(const WaveClip &clip, const ZoomInfo &zoomInfo, const wxRect &rect, const wxPoint &pos)
bool CutSelectedText(AudacityProject &project)
void DoSetMinimized(bool minimized) override
static constexpr int kChannelSeparatorThickness
unsigned CaptureKey(wxKeyEvent &event, ViewInfo &viewInfo, wxWindow *pParent, AudacityProject *project) override
Refinement GetSubViews(const wxRect *rect=nullptr)
bool PasteText(AudacityProject &project)
void DoSetDisplay(Display display, bool exclusive=true)
wxCoord GetLastHeight() const
void Draw(TrackPanelDrawingContext &context, const wxRect &rect, unsigned iPass) override
bool SelectAllText(AudacityProject &project)
std::shared_ptr< CommonTrackCell > DoGetAffordance(const std::shared_ptr< Track > &track)
void RestorePlacements(const WaveChannelSubViewPlacements &placements)
static std::pair< bool, std::vector< UIHandlePtr > > DoDetailedHitTest(const TrackPanelMouseState &state, const AudacityProject *pProject, int currentTool, bool bMultiTool, const std::shared_ptr< WaveTrack > &wt, CommonChannelView &view)
std::vector< WaveChannelSubView::Type > GetDisplays() const
bool SelectNextClip(ViewInfo &viewInfo, AudacityProject *project, bool forward)
void CopyTo(Track &track) const override
Copy state, for undo/redo purposes.
static UIHandlePtr HitTest(std::weak_ptr< WaveClipAdjustBorderHandle > &holder, WaveChannelView &view, const AudacityProject *pProject, const TrackPanelMouseState &state)
This allows multiple clips to be a part of one WaveTrack.
bool OnTextCopy(AudacityProject &project)
bool OnTextSelect(AudacityProject &project)
bool OnTextCut(AudacityProject &project)
bool OnTextPaste(AudacityProject &project)
A Track that contains audio waveform data.
size_t NChannels() const override
May report more than one only when this is a leader track.
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
int64 TimeToPosition(double time, int64 origin=0, bool ignoreFisheye=false) const
STM: Converts a project time to screen x position.
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
AUDACITY_DLL_API void DrawCloseButton(TrackPanelDrawingContext &context, const wxRect &bev, const Track *pTrack, UIHandle *target)
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Namespace containing an enum 'what to do on a refresh?'.
@ MultiView
"Multi" is special, not really a view type on par with the others.
Iter SelectedClip(const ViewInfo &viewInfo, Iter begin, Iter end)
constexpr auto sampleRate
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
std::pair< const char *, const char * > Pair
bool Comp(const CollectedItems::NewItem &a, const CollectedItems::NewItem &b)
double GetRate(const Track &track)
std::shared_ptr< Track > FindTrack(TrackPanelCell *pCell)
double GetPixelsPerSecond(const wxRect &viewRect, const ZoomInfo &zoomInfo)
bool ShowIndividualSamples(int sampleRate, double stretchRatio, double pixelsPerSecond)
double GetBlankSpaceBeforePlayEndTime(const ClipTimes &clip)
bool(WaveTrackAffordanceControls::*)(AudacityProject &) PMF
const WaveClip * NextClipLooped(ViewInfo &viewInfo, Iter begin, Iter end, Comp comp)
static const ChannelGroup::Attachments::RegisteredFactory key
double CalculateAdjustmentForZoomLevel(double avgPixPerSecond, bool showSamples)
bool AnyAffordance(AudacityProject &project, WaveChannelView &view, PMF pmf)
void rotate(const float *oldPhase, const float *newPhase, std::complex< float > *dst, int32_t n)
For defining overrides of the method.
A convenient base class defining abstract virtual Clone() for a given kind of pointer.
ClipParameters(const ClipTimes &clip, const wxRect &rect, const ZoomInfo &zoomInfo)
static wxRect GetClipRect(const ClipTimes &clip, const ZoomInfo &zoomInfo, const wxRect &viewRect, bool *outShowSamples=nullptr)
const double averagePixelsPerSecond
const bool showIndividualSamples
SubViewAdjuster(WaveChannelView &view)
std::pair< size_t, bool > HitTest(WaveChannelSubView &subView, wxCoord yy, wxCoord top, wxCoord height)
WaveChannelSubViewPtrs mSubViews
WaveChannelSubViewPlacements mNewPlacements
std::vector< wxCoord > ComputeHeights(wxCoord totalHeight)
WaveChannelSubViewPlacements mOrigPlacements
void UpdateViews(bool rollback)
bool ModifyPermutation(bool top)
std::vector< size_t > mPermutation
std::weak_ptr< WaveChannelView > mwView
size_t FindIndex(WaveChannelSubView &subView) const
static Display Default()
Return a preferred type.
~PlacementArray()=default
std::unique_ptr< Cloneable<> > Clone() const
WaveChannelSubViewPlacements mPlacements