mirror of
https://github.com/cookiengineer/audacity
synced 2025-06-29 06:38:38 +02:00
No hidden dependencies on TrackView & TrackControls subclasses...
... from the Track subclasses, caused by splitting their virtual function definitions, making dependencies that scripts/graph.pl did not detect. Instead use a new system for registering tables of factory functions and type-switching on the Track objects' RTTI to get to the right function.
This commit is contained in:
commit
3e4480ce6f
@ -30,6 +30,7 @@ src/AdornedRulerPanel.h
|
||||
src/AboutDialog.cpp
|
||||
src/AboutDialog.h
|
||||
src/AllThemeResources.h
|
||||
src/AttachedVirtualFunction.h
|
||||
src/Audacity.h
|
||||
src/AudacityApp.cpp
|
||||
src/AudacityApp.h
|
||||
|
@ -3364,6 +3364,7 @@
|
||||
5ED1D0AF1CDE560C00471E3C /* BackedPanel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BackedPanel.cpp; sourceTree = "<group>"; };
|
||||
5ED1D0B01CDE560C00471E3C /* BackedPanel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BackedPanel.h; sourceTree = "<group>"; };
|
||||
5EE8984821D68D88006DE939 /* CommandManagerWindowClasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommandManagerWindowClasses.h; sourceTree = "<group>"; };
|
||||
5EEE942021F397C00038E68E /* AttachedVirtualFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AttachedVirtualFunction.h; sourceTree = "<group>"; };
|
||||
5EF17C211D1F0A690090A642 /* ScrubbingToolBar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrubbingToolBar.cpp; sourceTree = "<group>"; };
|
||||
5EF17C221D1F0A690090A642 /* ScrubbingToolBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrubbingToolBar.h; sourceTree = "<group>"; };
|
||||
5EF3E643203FBAFB006C6882 /* AudacityCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AudacityCommand.cpp; sourceTree = "<group>"; };
|
||||
@ -4470,6 +4471,7 @@
|
||||
1790AFCA09883BFD008A330A /* AColor.h */,
|
||||
5E08C7382180D460004079AE /* AdornedRulerPanel.h */,
|
||||
28FB12230A3790DF006F0917 /* AllThemeResources.h */,
|
||||
5EEE942021F397C00038E68E /* AttachedVirtualFunction.h */,
|
||||
1790AFCC09883BFD008A330A /* Audacity.h */,
|
||||
1790AFCF09883BFD008A330A /* AudacityApp.h */,
|
||||
5ECCE7651DE49834009900E9 /* AudacityException.h */,
|
||||
|
258
src/AttachedVirtualFunction.h
Normal file
258
src/AttachedVirtualFunction.h
Normal file
@ -0,0 +1,258 @@
|
||||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AttachedVirtualFunction.h
|
||||
|
||||
Paul Licameli
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef __AUDACITY_ATTACHED_VIRTUAL_FUNCTION__
|
||||
#define __AUDACITY_ATTACHED_VIRTUAL_FUNCTION__
|
||||
|
||||
/* \brief Define a "virtual" function with multiple bodies chosen by type-switch
|
||||
on the runtime class of the first argument, leaving the set of functions
|
||||
open-ended for extension, but also requiring no modification of the definition
|
||||
of the base class of the type hierarchy that is switched on.
|
||||
|
||||
The invocation of the function is not as efficient as for true virtual functions
|
||||
but the advantage of this utility is greater compilation decoupling. A client
|
||||
can attach its own virtual functions to a class hierarchy in the core.
|
||||
|
||||
Beware that invocation of the function should not be done during initialization
|
||||
of file scope static objects. Dispatch might not go to the correct subclass
|
||||
case if initializations are not yet complete.
|
||||
|
||||
Example usage:
|
||||
|
||||
////////
|
||||
// Core classes in Host.h:
|
||||
class AbstractHost
|
||||
{
|
||||
// ...
|
||||
};
|
||||
|
||||
class SpecialHost : public Abstract Host
|
||||
{
|
||||
// ...
|
||||
};
|
||||
|
||||
class ExtraSpecialHost : public SpecialHost
|
||||
{
|
||||
// ...
|
||||
};
|
||||
|
||||
////////
|
||||
// Declare the root of the attached function hierarchy in Client.h,
|
||||
// which Host.cpp need not include at all:
|
||||
|
||||
enum class ErrorCode { Ok, Bad, // ...
|
||||
}; // a return type for our function
|
||||
|
||||
// First this empty structure serving just to distinguish among instantiations
|
||||
// of AttachedVirtualFunction with otherwise identical arguments
|
||||
// An incomplete type is enough
|
||||
struct DoSomethingTag;
|
||||
|
||||
// Now declare the "virtual function"
|
||||
using DoSomething =
|
||||
AttachedVirtualFunction<
|
||||
DoSomethingTag,
|
||||
ErrorCode,
|
||||
AbstractHost, // class to be switched on by runtime type
|
||||
int, double // other arguments
|
||||
>;
|
||||
|
||||
////////
|
||||
// Usage of the "virtual function"
|
||||
#include "Client.h"
|
||||
void UseDoSomething( AbstractHost &host )
|
||||
{
|
||||
// ...
|
||||
auto error = DoSomething::Call( host, 0, 1.0 );
|
||||
// ...
|
||||
}
|
||||
|
||||
////////
|
||||
// Out-of-line registrations needed in Client.cpp:
|
||||
|
||||
// Define the default function body here (as a function returning a function!)
|
||||
template<> auto DoSomething::Implementation() -> Function {
|
||||
return [](AbstractHost &host, int arg1, double arg2) {
|
||||
return ErrorCode::Ok;
|
||||
};
|
||||
// or you could return nullptr to force InconsistencyException at runtime if
|
||||
// the virtual function is invoked for a host subclass for which no override
|
||||
// was defined
|
||||
}
|
||||
// Must also guarantee construction of an instance of class DoSomething at least
|
||||
// once before any use of DoSomething::Call()
|
||||
static DoSomething registerMe;
|
||||
|
||||
////////
|
||||
// An override of the function is defined in SpecialClient.cpp,
|
||||
// building up a hierarchy of function bodies parallel to the host class
|
||||
// hierarchy
|
||||
using DoSomethingSpecial = DoSomething::Override< SpecialHost >;
|
||||
template<> template<> auto DoSomethingSpecial::Implementation() -> Function {
|
||||
// The function can be defined assuming downcast of the first argument
|
||||
// has been done
|
||||
return [](SpecialHost &host, int arg1, double arg2) {
|
||||
return arg1 == 0 ? ErrorCode::Ok : ErrorCode::Bad;
|
||||
};
|
||||
}
|
||||
static DoSomethingSpecial registerMe;
|
||||
|
||||
////////
|
||||
// A further override in ExtraSpecialClient.cpp, demonstrating call-through too
|
||||
using DoSomethingExtraSpecial =
|
||||
DoSomething::Override< ExtraSpecialHost, DoSomethingSpecial >;
|
||||
template<> template<>
|
||||
auto DoSomethingExtraSpecial::Implementation() -> Function {
|
||||
return [](ExtraSpecialHost &host, int arg1, double arg2){
|
||||
// Call the immediately overridden version of the function
|
||||
auto result = Callthrough( host, arg1, arg2 );
|
||||
if ( result == ErrorCode::OK ) {
|
||||
if ( arg2 != 1066.0 )
|
||||
result = ErrorCode::Bad;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
static DoSomethinExtraSpecial registerMe;
|
||||
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "InconsistencyException.h"
|
||||
|
||||
template< typename Tag, typename Return, typename This, typename... Arguments >
|
||||
class AttachedVirtualFunction
|
||||
{
|
||||
public:
|
||||
|
||||
// The type of an overriding function, taking a more specific first
|
||||
// argument
|
||||
template< typename Subclass >
|
||||
using ImplementationFor = std::function< Return( Subclass&, Arguments... ) >;
|
||||
|
||||
// These member names are declared in this class template and redeclared
|
||||
// in each override
|
||||
using Object = This;
|
||||
using Function = ImplementationFor< This >;
|
||||
// A function returning a std::function, which you define elsewhere;
|
||||
// it may return nullptr in case this must act somewhat as a "pure virtual",
|
||||
// throwing InconsistencyException if the function is invoked on a subclass
|
||||
// for which no override was defined
|
||||
static Function Implementation();
|
||||
|
||||
// This class must be instantiated once at least to register the function in
|
||||
// a table, but may be instantiated multiply (and will be if there are any
|
||||
// overrides)
|
||||
AttachedVirtualFunction()
|
||||
{
|
||||
static std::once_flag flag;
|
||||
std::call_once( flag, []{ Register<This>( Implementation() ); } );
|
||||
}
|
||||
|
||||
// For defining overrides of the virtual function; template arguments
|
||||
// are the more specific subclass and the immediately overridden version
|
||||
// of the function, defaulting to the base version
|
||||
template<
|
||||
typename Subclass, typename Overridden = AttachedVirtualFunction >
|
||||
struct Override : Overridden
|
||||
{
|
||||
using Object = Subclass;
|
||||
|
||||
// Check that inheritance is correct
|
||||
static_assert(
|
||||
std::is_base_of< typename Overridden::Object, Object >::value,
|
||||
"overridden class must be a base of the overriding class"
|
||||
);
|
||||
|
||||
using Function = ImplementationFor< Subclass >;
|
||||
// A function returning a std::function that must be defined out-of-line
|
||||
static Function Implementation();
|
||||
// May be used in the body of the overriding function, defining it in
|
||||
// terms of the overridden one:
|
||||
static Return Callthrough(
|
||||
typename Overridden::Object &object, Arguments &&...arguments )
|
||||
{
|
||||
return Overridden::Implementation()(
|
||||
object, std::forward< Arguments >( arguments )... );
|
||||
}
|
||||
Override()
|
||||
{
|
||||
static std::once_flag flag;
|
||||
std::call_once( flag, []{
|
||||
// Register in the table an adaptor thunk that downcasts the object
|
||||
auto implementation = Implementation();
|
||||
Register< Subclass >( [=]( This &obj, Arguments &&...arguments ){
|
||||
return implementation(
|
||||
static_cast< Subclass& >( obj ),
|
||||
std::forward< Arguments >( arguments )... );
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
static Return Call( This &obj, Arguments &&...arguments )
|
||||
{
|
||||
try {
|
||||
// Note that the constructors of this class and overrides cause
|
||||
// the registry to be topologically sorted, with functions for
|
||||
// less-derived classes earlier in the table; so take the last
|
||||
// one that matches the object. (The object might not be of the exact
|
||||
// class corresponding to any of the overrides, which is why this
|
||||
// solution involves calling the predicates generated in Register,
|
||||
// and wouldn't work just with hashing on std::type_index; but perhaps
|
||||
// such a cache could be memo-ized)
|
||||
auto ®istry = GetRegistry();
|
||||
auto iter = registry.rbegin(), end = registry.rend();
|
||||
for ( ; iter != end; ++iter ) {
|
||||
auto &entry = *iter;
|
||||
if ( entry.predicate( &obj ) )
|
||||
return entry.function(
|
||||
obj, std::forward< Arguments >( arguments )... );
|
||||
}
|
||||
throw std::bad_function_call{};
|
||||
}
|
||||
catch ( const std::bad_function_call& ) {
|
||||
// No matching case found with a non-null function.
|
||||
// Translate the exception
|
||||
THROW_INCONSISTENCY_EXCEPTION;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template< typename Subclass >
|
||||
static void Register( const ImplementationFor< This > &function )
|
||||
{
|
||||
// Push back a dynamic type test and corresponding function body
|
||||
GetRegistry().push_back({
|
||||
[]( This *b ){ return dynamic_cast< Subclass * >( b ) != nullptr; },
|
||||
function
|
||||
});
|
||||
}
|
||||
|
||||
using Predicate = std::function< bool( This* ) >;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
Predicate predicate;
|
||||
ImplementationFor< This > function;
|
||||
};
|
||||
|
||||
using Registry = std::vector< Entry >;
|
||||
static Registry &GetRegistry()
|
||||
{
|
||||
static Registry registry;
|
||||
return registry;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -169,10 +169,6 @@ public:
|
||||
double mClipLen;
|
||||
|
||||
int miLastLabel; // used by FindNextLabel and FindPrevLabel
|
||||
|
||||
private:
|
||||
std::shared_ptr<TrackView> DoGetView() override;
|
||||
std::shared_ptr<TrackControls> DoGetControls() override;
|
||||
};
|
||||
|
||||
struct LabelTrackEvent : TrackListEvent
|
||||
|
@ -103,6 +103,7 @@ audacity_SOURCES = \
|
||||
AdornedRulerPanel.cpp \
|
||||
AdornedRulerPanel.h \
|
||||
AllThemeResources.h \
|
||||
AttachedVirtualFunction.h \
|
||||
Audacity.h \
|
||||
AudacityApp.cpp \
|
||||
AudacityApp.h \
|
||||
|
@ -287,16 +287,17 @@ am__audacity_SOURCES_DIST = BlockFile.cpp BlockFile.h DirManager.cpp \
|
||||
blockfile/SimpleBlockFile.cpp blockfile/SimpleBlockFile.h \
|
||||
xml/XMLTagHandler.cpp xml/XMLTagHandler.h AboutDialog.cpp \
|
||||
AboutDialog.h AColor.cpp AColor.h AdornedRulerPanel.cpp \
|
||||
AdornedRulerPanel.h AllThemeResources.h Audacity.h \
|
||||
AudacityApp.cpp AudacityApp.h AudacityException.cpp \
|
||||
AudacityException.h AudacityLogger.cpp AudacityLogger.h \
|
||||
AudioIO.cpp AudioIO.h AudioIOBase.cpp AudioIOBase.h \
|
||||
AudioIOListener.h AutoRecovery.cpp AutoRecovery.h \
|
||||
AutoRecoveryDialog.cpp AutoRecoveryDialog.h \
|
||||
BatchCommandDialog.cpp BatchCommandDialog.h BatchCommands.cpp \
|
||||
BatchCommands.h BatchProcessDialog.cpp BatchProcessDialog.h \
|
||||
Benchmark.cpp Benchmark.h CellularPanel.cpp CellularPanel.h \
|
||||
ClientData.h ClientDataHelpers.h Clipboard.cpp Clipboard.h \
|
||||
AdornedRulerPanel.h AllThemeResources.h \
|
||||
AttachedVirtualFunction.h Audacity.h AudacityApp.cpp \
|
||||
AudacityApp.h AudacityException.cpp AudacityException.h \
|
||||
AudacityLogger.cpp AudacityLogger.h AudioIO.cpp AudioIO.h \
|
||||
AudioIOBase.cpp AudioIOBase.h AudioIOListener.h \
|
||||
AutoRecovery.cpp AutoRecovery.h AutoRecoveryDialog.cpp \
|
||||
AutoRecoveryDialog.h BatchCommandDialog.cpp \
|
||||
BatchCommandDialog.h BatchCommands.cpp BatchCommands.h \
|
||||
BatchProcessDialog.cpp BatchProcessDialog.h Benchmark.cpp \
|
||||
Benchmark.h CellularPanel.cpp CellularPanel.h ClientData.h \
|
||||
ClientDataHelpers.h Clipboard.cpp Clipboard.h \
|
||||
CommonCommandFlags.cpp CommonCommandFlags.h CrashReport.cpp \
|
||||
CrashReport.h Dependencies.cpp Dependencies.h DeviceChange.cpp \
|
||||
DeviceChange.h DeviceManager.cpp DeviceManager.h Diags.cpp \
|
||||
@ -1380,16 +1381,17 @@ audacity_LDADD = $(EXPAT_LIBS) $(FILEDIALOG_LIBS) $(PORTAUDIO_LIBS) \
|
||||
$(am__append_43) $(am__append_45) $(am__append_48)
|
||||
audacity_SOURCES = $(libaudacity_la_SOURCES) AboutDialog.cpp \
|
||||
AboutDialog.h AColor.cpp AColor.h AdornedRulerPanel.cpp \
|
||||
AdornedRulerPanel.h AllThemeResources.h Audacity.h \
|
||||
AudacityApp.cpp AudacityApp.h AudacityException.cpp \
|
||||
AudacityException.h AudacityLogger.cpp AudacityLogger.h \
|
||||
AudioIO.cpp AudioIO.h AudioIOBase.cpp AudioIOBase.h \
|
||||
AudioIOListener.h AutoRecovery.cpp AutoRecovery.h \
|
||||
AutoRecoveryDialog.cpp AutoRecoveryDialog.h \
|
||||
BatchCommandDialog.cpp BatchCommandDialog.h BatchCommands.cpp \
|
||||
BatchCommands.h BatchProcessDialog.cpp BatchProcessDialog.h \
|
||||
Benchmark.cpp Benchmark.h CellularPanel.cpp CellularPanel.h \
|
||||
ClientData.h ClientDataHelpers.h Clipboard.cpp Clipboard.h \
|
||||
AdornedRulerPanel.h AllThemeResources.h \
|
||||
AttachedVirtualFunction.h Audacity.h AudacityApp.cpp \
|
||||
AudacityApp.h AudacityException.cpp AudacityException.h \
|
||||
AudacityLogger.cpp AudacityLogger.h AudioIO.cpp AudioIO.h \
|
||||
AudioIOBase.cpp AudioIOBase.h AudioIOListener.h \
|
||||
AutoRecovery.cpp AutoRecovery.h AutoRecoveryDialog.cpp \
|
||||
AutoRecoveryDialog.h BatchCommandDialog.cpp \
|
||||
BatchCommandDialog.h BatchCommands.cpp BatchCommands.h \
|
||||
BatchProcessDialog.cpp BatchProcessDialog.h Benchmark.cpp \
|
||||
Benchmark.h CellularPanel.cpp CellularPanel.h ClientData.h \
|
||||
ClientDataHelpers.h Clipboard.cpp Clipboard.h \
|
||||
CommonCommandFlags.cpp CommonCommandFlags.h CrashReport.cpp \
|
||||
CrashReport.h Dependencies.cpp Dependencies.h DeviceChange.cpp \
|
||||
DeviceChange.h DeviceManager.cpp DeviceManager.h Diags.cpp \
|
||||
|
@ -222,10 +222,6 @@ public:
|
||||
int mVisibleChannels; // bit set of visible channels
|
||||
|
||||
std::weak_ptr<StretchHandle> mStretchHandle;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TrackView> DoGetView() override;
|
||||
std::shared_ptr<TrackControls> DoGetControls() override;
|
||||
};
|
||||
|
||||
/// Data used to display a note track
|
||||
|
@ -113,10 +113,6 @@ private:
|
||||
Track::Holder Clone() const override;
|
||||
|
||||
friend class TrackFactory;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TrackView> DoGetView() override;
|
||||
std::shared_ptr<TrackControls> DoGetControls() override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1284,3 +1284,13 @@ void TrackFactory::Destroy( AudacityProject &project )
|
||||
{
|
||||
project.AttachedObjects::Assign( key2, nullptr );
|
||||
}
|
||||
|
||||
template<> auto DoGetControls::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetControls registerDoGetControls;
|
||||
|
||||
template<> auto DoGetView::Implementation() -> Function {
|
||||
return nullptr;
|
||||
}
|
||||
static DoGetView registerDoGetView;
|
||||
|
26
src/Track.h
26
src/Track.h
@ -704,12 +704,6 @@ public:
|
||||
bool HandleCommonXMLAttribute(const wxChar *attr, const wxChar *value);
|
||||
|
||||
protected:
|
||||
|
||||
// These are called to create controls on demand:
|
||||
virtual std::shared_ptr<TrackView> DoGetView() = 0;
|
||||
virtual std::shared_ptr<TrackControls> DoGetControls() = 0;
|
||||
|
||||
// These hold the controls:
|
||||
std::shared_ptr<TrackView> mpView;
|
||||
std::shared_ptr<CommonTrackCell> mpControls;
|
||||
};
|
||||
@ -1595,4 +1589,24 @@ class AUDACITY_DLL_API TrackFactory final
|
||||
#endif
|
||||
};
|
||||
|
||||
#include "AttachedVirtualFunction.h"
|
||||
|
||||
struct DoGetControlsTag;
|
||||
|
||||
using DoGetControls =
|
||||
AttachedVirtualFunction<
|
||||
DoGetControlsTag,
|
||||
std::shared_ptr< TrackControls >,
|
||||
Track
|
||||
>;
|
||||
|
||||
struct DoGetViewTag;
|
||||
|
||||
using DoGetView =
|
||||
AttachedVirtualFunction<
|
||||
DoGetViewTag,
|
||||
std::shared_ptr< TrackView >,
|
||||
Track
|
||||
>;
|
||||
|
||||
#endif
|
||||
|
@ -682,10 +682,6 @@ private:
|
||||
|
||||
std::unique_ptr<SpectrogramSettings> mpSpectrumSettings;
|
||||
std::unique_ptr<WaveformSettings> mpWaveformSettings;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<TrackView> DoGetView() override;
|
||||
std::shared_ptr<TrackControls> DoGetControls() override;
|
||||
};
|
||||
|
||||
// This is meant to be a short-lived object, during whose lifetime,
|
||||
|
@ -170,3 +170,11 @@ PopupMenuTable *LabelTrackControls::GetMenuExtension(Track *)
|
||||
{
|
||||
return &LabelTrackMenuTable::Instance();
|
||||
}
|
||||
|
||||
using DoGetLabelTrackControls = DoGetControls::Override< LabelTrack >;
|
||||
template<> template<> auto DoGetLabelTrackControls::Implementation() -> Function {
|
||||
return [](LabelTrack &track) {
|
||||
return std::make_shared<LabelTrackControls>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetLabelTrackControls registerDoGetLabelTrackControls;
|
||||
|
@ -2080,15 +2080,13 @@ int LabelTrackView::DialogForLabelName(
|
||||
return status;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackView> LabelTrack::DoGetView()
|
||||
{
|
||||
return std::make_shared<LabelTrackView>( SharedPointer() );
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackControls> LabelTrack::DoGetControls()
|
||||
{
|
||||
return std::make_shared<LabelTrackControls>( SharedPointer() );
|
||||
using DoGetLabelTrackView = DoGetView::Override< LabelTrack >;
|
||||
template<> template<> auto DoGetLabelTrackView::Implementation() -> Function {
|
||||
return [](LabelTrack &track) {
|
||||
return std::make_shared<LabelTrackView>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetLabelTrackView registerDoGetLabelTrackView;
|
||||
|
||||
std::shared_ptr<TrackVRulerControls> LabelTrackView::DoGetVRulerControls()
|
||||
{
|
||||
|
@ -310,3 +310,11 @@ void NoteTrackControls::ReCreateVelocitySlider( wxEvent &evt )
|
||||
pParent;
|
||||
#endif
|
||||
}
|
||||
|
||||
using DoGetNoteTrackControls = DoGetControls::Override< NoteTrack >;
|
||||
template<> template<> auto DoGetNoteTrackControls::Implementation() -> Function {
|
||||
return [](NoteTrack &track) {
|
||||
return std::make_shared<NoteTrackControls>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetNoteTrackControls registerDoGetNoteTrackControls;
|
||||
|
@ -53,15 +53,13 @@ std::vector<UIHandlePtr> NoteTrackView::DetailedHitTest
|
||||
return results;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackView> NoteTrack::DoGetView()
|
||||
{
|
||||
return std::make_shared<NoteTrackView>( SharedPointer() );
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackControls> NoteTrack::DoGetControls()
|
||||
{
|
||||
return std::make_shared<NoteTrackControls>( SharedPointer() );
|
||||
using DoGetNoteTrackView = DoGetView::Override< NoteTrack >;
|
||||
template<> template<> auto DoGetNoteTrackView::Implementation() -> Function {
|
||||
return [](NoteTrack &track) {
|
||||
return std::make_shared<NoteTrackView>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetNoteTrackView registerDoGetNoteTrackView;
|
||||
|
||||
std::shared_ptr<TrackVRulerControls> NoteTrackView::DoGetVRulerControls()
|
||||
{
|
||||
|
@ -1283,3 +1283,11 @@ void WaveTrackControls::ReCreatePanSlider( wxEvent &event )
|
||||
PAN_SLIDER);
|
||||
gPanCaptured->SetDefaultValue(defPos);
|
||||
}
|
||||
|
||||
using DoGetWaveTrackControls = DoGetControls::Override< WaveTrack >;
|
||||
template<> template<> auto DoGetWaveTrackControls::Implementation() -> Function {
|
||||
return [](WaveTrack &track) {
|
||||
return std::make_shared<WaveTrackControls>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetWaveTrackControls registerDoGetWaveTrackControls;
|
||||
|
@ -156,15 +156,13 @@ void WaveTrackView::DoSetMinimized( bool minimized )
|
||||
TrackView::DoSetMinimized( minimized );
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackView> WaveTrack::DoGetView()
|
||||
{
|
||||
return std::make_shared<WaveTrackView>( SharedPointer() );
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackControls> WaveTrack::DoGetControls()
|
||||
{
|
||||
return std::make_shared<WaveTrackControls>( SharedPointer() );
|
||||
using DoGetWaveTrackView = DoGetView::Override< WaveTrack >;
|
||||
template<> template<> auto DoGetWaveTrackView::Implementation() -> Function {
|
||||
return [](WaveTrack &track) {
|
||||
return std::make_shared<WaveTrackView>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetWaveTrackView registerDoGetWaveTrackView;
|
||||
|
||||
std::shared_ptr<TrackVRulerControls> WaveTrackView::DoGetVRulerControls()
|
||||
{
|
||||
|
@ -170,3 +170,11 @@ PopupMenuTable *TimeTrackControls::GetMenuExtension(Track *)
|
||||
{
|
||||
return &TimeTrackMenuTable::Instance();
|
||||
}
|
||||
|
||||
using DoGetTimeTrackControls = DoGetControls::Override< TimeTrack >;
|
||||
template<> template<> auto DoGetTimeTrackControls::Implementation() -> Function {
|
||||
return [](TimeTrack &track) {
|
||||
return std::make_shared<TimeTrackControls>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetTimeTrackControls registerDoGetTimeTrackControls;
|
||||
|
@ -43,15 +43,13 @@ std::vector<UIHandlePtr> TimeTrackView::DetailedHitTest
|
||||
return results;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackView> TimeTrack::DoGetView()
|
||||
{
|
||||
return std::make_shared<TimeTrackView>( SharedPointer() );
|
||||
}
|
||||
|
||||
std::shared_ptr<TrackControls> TimeTrack::DoGetControls()
|
||||
{
|
||||
return std::make_shared<TimeTrackControls>( SharedPointer() );
|
||||
using DoGetTimeTrackView = DoGetView::Override< TimeTrack >;
|
||||
template<> template<> auto DoGetTimeTrackView::Implementation() -> Function {
|
||||
return [](TimeTrack &track) {
|
||||
return std::make_shared<TimeTrackView>( track.SharedPointer() );
|
||||
};
|
||||
}
|
||||
static DoGetTimeTrackView registerDoGetTimeTrackView;
|
||||
|
||||
std::shared_ptr<TrackVRulerControls> TimeTrackView::DoGetVRulerControls()
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ std::shared_ptr<TrackView> Track::GetTrackView()
|
||||
{
|
||||
if (!mpView)
|
||||
// create on demand
|
||||
mpView = DoGetView();
|
||||
mpView = DoGetView::Call( *this );
|
||||
return mpView;
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ std::shared_ptr<TrackPanelCell> Track::GetTrackControls()
|
||||
{
|
||||
if (!mpControls)
|
||||
// create on demand
|
||||
mpControls = DoGetControls();
|
||||
mpControls = DoGetControls::Call( *this );
|
||||
return mpControls;
|
||||
}
|
||||
|
||||
|
@ -508,6 +508,7 @@
|
||||
<ClInclude Include="..\..\..\src\AColor.h" />
|
||||
<ClInclude Include="..\..\..\src\AdornedRulerPanel.h" />
|
||||
<ClInclude Include="..\..\..\src\AllThemeResources.h" />
|
||||
<ClInclude Include="..\..\..\src\AttachedVirtualFunction.h" />
|
||||
<ClInclude Include="..\..\..\src\Audacity.h" />
|
||||
<ClInclude Include="..\..\..\src\AudacityApp.h" />
|
||||
<ClInclude Include="..\..\..\src\AudacityException.h" />
|
||||
|
@ -1225,6 +1225,9 @@
|
||||
<ClInclude Include="..\..\..\src\AllThemeResources.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\AttachedVirtualFunction.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\..\src\Audacity.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user