Audacity 3.2.0
CommonChannelView.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3Audacity: A Digital Audio Editor
4
5CommonChannelView.cpp
6
7Paul Licameli split from class TrackView (now called ChannelView)
8
9**********************************************************************/
10
11#include "CommonChannelView.h"
12
13#include "BackgroundCell.h"
14#include "CommonTrackInfo.h"
15#include "TimeShiftHandle.h"
16#include "TrackControls.h"
17#include "ZoomHandle.h"
18#include "../ui/SelectHandle.h"
19#include "AColor.h"
20#include "PendingTracks.h"
21#include "../../ProjectSettings.h"
22#include "Track.h"
23#include "../../TrackArtist.h"
24#include "../../TrackPanelDrawingContext.h"
25#include "../../TrackPanelMouseEvent.h"
26
27#include <wx/dc.h>
28#include <wx/graphics.h>
29
30std::vector<UIHandlePtr> CommonChannelView::HitTest
31(const TrackPanelMouseState &st,
32 const AudacityProject *pProject)
33{
34 UIHandlePtr result;
35 using namespace ToolCodes;
36 std::vector<UIHandlePtr> results;
37 const auto &settings = ProjectSettings::Get( *pProject );
38 const auto currentTool = settings.GetTool();
39 const bool isMultiTool = ( currentTool == multiTool );
40
41 // In other tools, let subclasses determine detailed hits.
42 results =
43 DetailedHitTest( st, pProject, currentTool, isMultiTool );
44
45 // There are still some general cases.
46
47 #if 0
48 // Sliding applies in more than one track type.
49 if ( !isMultiTool && currentTool == slideTool ) {
51 mTimeShiftHandle, FindTrack(), false);
52 if (result)
53 results.push_back(result);
54 }
55 #endif
56
57 // Let the multi-tool right-click handler apply only in default of all
58 // other detailed hits.
59 if ( isMultiTool ) {
60 result = ZoomHandle::HitTest(
61 BackgroundCell::Get( *pProject ).mZoomHandle, st.state);
62 if (result)
63 results.push_back(result);
64 }
65
66 // Finally, default of all is adjustment of the selection box.
67 if ( isMultiTool || currentTool == selectTool ) {
68 result = SelectHandle::HitTest(
69 mSelectHandle, st, pProject, shared_from_this() );
70 if (result)
71 results.push_back(result);
72 }
73
74 return results;
75}
76
77std::shared_ptr<TrackPanelCell> CommonChannelView::ContextMenuDelegate()
78{
79 const auto pTrack = FindTrack();
80 if (pTrack)
81 return TrackControls::Get(*pTrack).shared_from_this();
82 return nullptr;
83}
84
86{
87 const auto height = CommonTrackInfo::MinimumTrackHeight();
88 auto pChannel = FindChannel().get();
89 if (!pChannel)
90 return height;
91 const auto pTrack =
92 dynamic_cast<const Track *>(&pChannel->GetChannelGroup());
93 if (!pTrack)
94 return 0;
95 if (const auto pList = pTrack->GetOwner())
96 if (const auto p = pList->GetOwner())
97 pChannel =
99
100 // Find index of the channel in its group and use that to round off correctly
101 const auto index = pChannel->GetChannelIndex();
102 const auto nChannels = pChannel->GetChannelGroup().Channels().size();
103 return (height * (index + 1) / nChannels) - (height * index / nChannels);
104}
105
106#include "Envelope.h"
107#include "ZoomInfo.h"
109 double alignedTime, double sampleDur,
110 double *buffer, int bufferLen, int leftOffset,
111 const ZoomInfo &zoomInfo )
112{
113 // Getting many envelope values, corresponding to pixel columns, which may
114 // not be uniformly spaced in time when there is a fisheye.
115
116 double prevDiscreteTime=0.0, prevSampleVal=0.0, nextSampleVal=0.0;
117 for ( int xx = 0; xx < bufferLen; ++xx ) {
118 auto time = zoomInfo.PositionToTime( xx, -leftOffset );
119 if ( sampleDur <= 0 )
120 // Sample interval not defined (as for time track)
121 buffer[xx] = env.GetValue( time );
122 else {
123 // The level of zoom-in may resolve individual samples.
124 // If so, then instead of evaluating the envelope directly,
125 // we draw a piecewise curve with knees at each sample time.
126 // This actually makes clearer what happens as you drag envelope
127 // points and make discontinuities.
128 auto leftDiscreteTime = alignedTime +
129 sampleDur * floor( ( time - alignedTime ) / sampleDur );
130 if ( xx == 0 || leftDiscreteTime != prevDiscreteTime ) {
131 prevDiscreteTime = leftDiscreteTime;
132 prevSampleVal =
133 env.GetValue( prevDiscreteTime, sampleDur );
134 nextSampleVal =
135 env.GetValue( prevDiscreteTime + sampleDur, sampleDur );
136 }
137 auto ratio = ( time - leftDiscreteTime ) / sampleDur;
138 if ( env.GetExponential() )
139 buffer[ xx ] = exp(
140 ( 1.0 - ratio ) * log( prevSampleVal )
141 + ratio * log( nextSampleVal ) );
142 else
143 buffer[ xx ] =
144 ( 1.0 - ratio ) * prevSampleVal + ratio * nextSampleVal;
145 }
146 }
147}
std::shared_ptr< UIHandle > UIHandlePtr
Definition: CellularPanel.h:28
declares abstract base class Track, TrackList, and iterators over TrackList
static Settings & settings()
Definition: TrackInfo.cpp:51
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static BackgroundCell & Get(AudacityProject &project)
std::weak_ptr< ZoomHandle > mZoomHandle
size_t GetChannelIndex() const
Definition: Channel.cpp:25
auto FindChannel() -> std::shared_ptr< Subtype >
May return null.
std::weak_ptr< SelectHandle > mSelectHandle
std::vector< UIHandlePtr > HitTest(const TrackPanelMouseState &, const AudacityProject *pProject) final
std::weak_ptr< TimeShiftHandle > mTimeShiftHandle
virtual int GetMinimizedHeight() const override
static void GetEnvelopeValues(const Envelope &env, double aligned_time, double sampleDur, double *buffer, int bufferLen, int leftOffset, const ZoomInfo &zoomInfo)
Get many envelope points for pixel columns at once, but don't assume uniform time per pixel.
std::shared_ptr< TrackPanelCell > ContextMenuDelegate() override
virtual std::vector< UIHandlePtr > DetailedHitTest(const TrackPanelMouseState &, const AudacityProject *pProject, int currentTool, bool bMultiTool)=0
std::shared_ptr< Track > FindTrack()
Piecewise linear or piecewise exponential function from double to double.
Definition: Envelope.h:72
double GetValue(double t, double sampleDur=0) const
Get envelope value at time t.
Definition: Envelope.cpp:880
bool GetExponential() const
Definition: Envelope.h:93
static PendingTracks & Get(AudacityProject &project)
const Channel & SubstituteOriginalChannel(const Channel &channel) const
static ProjectSettings & Get(AudacityProject &project)
static UIHandlePtr HitTest(std::weak_ptr< SelectHandle > &holder, const TrackPanelMouseState &state, const AudacityProject *pProject, const std::shared_ptr< ChannelView > &pChannelView)
static UIHandlePtr HitAnywhere(std::weak_ptr< TimeShiftHandle > &holder, const std::shared_ptr< Track > &pTrack, bool gripHit)
static TrackControls & Get(Track &track)
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:110
static UIHandlePtr HitTest(std::weak_ptr< ZoomHandle > &holder, const wxMouseState &state)
Definition: ZoomHandle.cpp:73
double PositionToTime(int64 position, int64 origin=0, bool ignoreFisheye=false) const
Definition: ZoomInfo.cpp:34
AUDACITY_DLL_API unsigned MinimumTrackHeight()