Updates for wx3
A long way to go yet, but many OSX issues fixed including conversion of Audio Unit effects.
This commit is contained in:
parent
2188f492a6
commit
d1f66d768f
|
@ -34,14 +34,14 @@ DEFINE_EVENT_TYPE(EVT_FILEDIALOG_SELECTION_CHANGED);
|
|||
DEFINE_EVENT_TYPE(EVT_FILEDIALOG_FILTER_CHANGED);
|
||||
DEFINE_EVENT_TYPE(EVT_FILEDIALOG_ADD_CONTROLS);
|
||||
|
||||
void FileDialog::EnableButton(wxString label, fdCallback cb, void *data)
|
||||
void FileDialogBase::EnableButton(wxString label, fdCallback cb, void *data)
|
||||
{
|
||||
m_buttonlabel = label;
|
||||
m_callback = cb;
|
||||
m_cbdata = data;
|
||||
}
|
||||
|
||||
void FileDialog::ClickButton(int index)
|
||||
void FileDialogBase::ClickButton(int index)
|
||||
{
|
||||
if (m_callback)
|
||||
{
|
||||
|
|
|
@ -17,21 +17,11 @@ custom controls.
|
|||
#ifndef _FILE_DIALOG_H_
|
||||
#define _FILE_DIALOG_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
#include "wx/filedlg.h"
|
||||
#include <wx/defs.h>
|
||||
#include <wx/filedlg.h>
|
||||
|
||||
typedef void (*fdCallback)(void *, int);
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
#include "gtk/FileDialogPrivate.h"
|
||||
#elif defined(__WXMAC__)
|
||||
#include "mac/FileDialogPrivate.h"
|
||||
#elif defined(__WXMSW__)
|
||||
#include "win/FileDialogPrivate.h"
|
||||
#else
|
||||
#error Unknown implementation
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: filedlg.h
|
||||
// Purpose: wxFileDialog base header
|
||||
|
@ -52,8 +42,33 @@ DECLARE_EVENT_TYPE(EVT_FILEDIALOG_ADD_CONTROLS, -1);
|
|||
|
||||
#define FD_NO_ADD_EXTENSION 0x0400
|
||||
|
||||
class FileDialogBase : public wxFileDialogBase
|
||||
{
|
||||
public:
|
||||
FileDialogBase() {};
|
||||
virtual ~FileDialogBase() {};
|
||||
|
||||
virtual void EnableButton(wxString label, fdCallback cb, void *cbdata);
|
||||
virtual void ClickButton(int index);
|
||||
|
||||
protected:
|
||||
wxString m_buttonlabel;
|
||||
fdCallback m_callback;
|
||||
void *m_cbdata;
|
||||
};
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
#include "gtk/FileDialog.h"
|
||||
#elif defined(__WXMAC__)
|
||||
#include "mac/FileDialog.h"
|
||||
#elif defined(__WXMSW__)
|
||||
#include "win/FileDialog.h"
|
||||
#else
|
||||
#error Unknown implementation
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// wxFileDialog convenience functions
|
||||
// FileDialog convenience functions
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
wxString
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
//
|
||||
// Copied from wx 3.0.2 and modified to support additional features
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/osx/filedlg.h
|
||||
// Purpose: wxFileDialog class
|
||||
// Author: Stefan Csomor
|
||||
// Modified by:
|
||||
// Created: 1998-01-01
|
||||
// Copyright: (c) Stefan Csomor
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _FILEDIALOG_H_
|
||||
#define _FILEDIALOG_H_
|
||||
|
||||
#include <wx/choice.h>
|
||||
|
||||
#include "../FileDialog.h"
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// wxFileDialog
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_CORE FileDialog: public FileDialogBase
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(FileDialog)
|
||||
protected:
|
||||
wxArrayString m_fileNames;
|
||||
wxArrayString m_paths;
|
||||
|
||||
public:
|
||||
FileDialog() { Init(); }
|
||||
FileDialog(wxWindow *parent,
|
||||
const wxString& message = wxFileSelectorPromptStr,
|
||||
const wxString& defaultDir = wxEmptyString,
|
||||
const wxString& defaultFile = wxEmptyString,
|
||||
const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
|
||||
long style = wxFD_DEFAULT_STYLE,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& sz = wxDefaultSize,
|
||||
const wxString& name = wxFileDialogNameStr)
|
||||
{
|
||||
Init();
|
||||
|
||||
Create(parent,message,defaultDir,defaultFile,wildCard,style,pos,sz,name);
|
||||
}
|
||||
|
||||
void Create(wxWindow *parent,
|
||||
const wxString& message = wxFileSelectorPromptStr,
|
||||
const wxString& defaultDir = wxEmptyString,
|
||||
const wxString& defaultFile = wxEmptyString,
|
||||
const wxString& wildCard = wxFileSelectorDefaultWildcardStr,
|
||||
long style = wxFD_DEFAULT_STYLE,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& sz = wxDefaultSize,
|
||||
const wxString& name = wxFileDialogNameStr);
|
||||
|
||||
#if wxOSX_USE_COCOA
|
||||
~FileDialog();
|
||||
#endif
|
||||
|
||||
virtual void EnableButton(wxString label, fdCallback cb, void *cbdata)
|
||||
{
|
||||
FileDialogBase::EnableButton(label, cb, cbdata);
|
||||
}
|
||||
|
||||
virtual void ClickButton(int index)
|
||||
{
|
||||
FileDialogBase::ClickButton(index);
|
||||
};
|
||||
|
||||
virtual void GetPaths(wxArrayString& paths) const { paths = m_paths; }
|
||||
virtual void GetFilenames(wxArrayString& files) const { files = m_fileNames ; }
|
||||
|
||||
virtual int ShowModal();
|
||||
|
||||
#if wxOSX_USE_COCOA
|
||||
virtual void ShowWindowModal();
|
||||
virtual void ModalFinishedCallback(void* panel, int resultCode);
|
||||
#endif
|
||||
|
||||
virtual bool SupportsExtraControl() const;
|
||||
|
||||
// implementation only
|
||||
|
||||
#if wxOSX_USE_COCOA
|
||||
// returns true if the file can be shown as active
|
||||
bool CheckFile( const wxString& filename );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// not supported for file dialog, RR
|
||||
virtual void DoSetSize(int WXUNUSED(x), int WXUNUSED(y),
|
||||
int WXUNUSED(width), int WXUNUSED(height),
|
||||
int WXUNUSED(sizeFlags) = wxSIZE_AUTO) {}
|
||||
|
||||
void SetupExtraControls(WXWindow nativeWindow);
|
||||
|
||||
#if wxOSX_USE_COCOA
|
||||
virtual wxWindow* CreateFilterPanel(wxWindow *extracontrol);
|
||||
void DoOnFilterSelected(int index);
|
||||
virtual void OnFilterSelected(wxCommandEvent &event);
|
||||
|
||||
wxArrayString m_filterExtensions;
|
||||
wxArrayString m_filterNames;
|
||||
wxChoice* m_filterChoice;
|
||||
wxWindow* m_filterPanel;
|
||||
bool m_useFileTypeFilter;
|
||||
int m_firstFileTypeFilter;
|
||||
wxArrayString m_currentExtensions;
|
||||
WX_NSObject m_delegate;
|
||||
WX_NSObject m_sheetDelegate;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Common part of all ctors.
|
||||
void Init();
|
||||
};
|
||||
|
||||
#endif // _FILEDIALOG_H_
|
|
@ -0,0 +1,714 @@
|
|||
//
|
||||
// Copied from wxWidgets 3.0.2 and modified to support additional features
|
||||
//
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: src/cocoa/filedlg.mm
|
||||
// Purpose: wxFileDialog for wxCocoa
|
||||
// Author: Ryan Norton
|
||||
// Modified by:
|
||||
// Created: 2004-10-02
|
||||
// Copyright: (c) Ryan Norton
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#include "FileDialog.h"
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/msgdlg.h"
|
||||
#include "wx/app.h"
|
||||
#include "wx/sizer.h"
|
||||
#include "wx/stattext.h"
|
||||
#include "wx/choice.h"
|
||||
#endif
|
||||
|
||||
#include "wx/filename.h"
|
||||
#include "wx/tokenzr.h"
|
||||
#include "wx/evtloop.h"
|
||||
|
||||
#include "wx/osx/private.h"
|
||||
#include "wx/sysopt.h"
|
||||
#include "wx/modalhook.h"
|
||||
|
||||
#include <mach-o/dyld.h>
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// Open Items:
|
||||
// - parameter support for descending into packages as directories (setTreatsFilePackagesAsDirectories)
|
||||
// - as setAllowedFileTypes is only functional for NSOpenPanel on 10.6+, on earlier systems, the file
|
||||
// type choice will not be shown, but all possible file items will be shown, if a popup must be working
|
||||
// then the delegate method - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename will have to
|
||||
// be implemented
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool HasAppKit_10_6()
|
||||
{
|
||||
// Even if we require 10.6, we might be loaded by an application that
|
||||
// was linked against 10.5. setAllowedFileTypes will still be ignored
|
||||
// in this case. From NSSavePanel.h:
|
||||
// NSOpenPanel: On versions less than 10.6, this property is ignored.
|
||||
// For applications that link against 10.6 and higher, this property will
|
||||
// determine which files should be enabled in the open panel.
|
||||
int32_t version = NSVersionOfLinkTimeLibrary("AppKit");
|
||||
if (version == -1)
|
||||
{
|
||||
// If we're loaded by an application that doesn't link against AppKit,
|
||||
// use the runtime version instead. This check will not work for the
|
||||
// case above.
|
||||
version = NSVersionOfRunTimeLibrary("AppKit");
|
||||
}
|
||||
|
||||
// Notice that this still works correctly even if version is -1.
|
||||
return version >= 0x40e2400 /* version of 10.6 AppKit */;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@interface OpenPanelDelegate : NSObject wxOSX_10_6_AND_LATER(<NSOpenSavePanelDelegate>)
|
||||
{
|
||||
FileDialog* _dialog;
|
||||
}
|
||||
|
||||
- (FileDialog*) fileDialog;
|
||||
- (void) setFileDialog:(FileDialog*) dialog;
|
||||
|
||||
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OpenPanelDelegate
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
_dialog = NULL;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (FileDialog*) fileDialog
|
||||
{
|
||||
return _dialog;
|
||||
}
|
||||
|
||||
- (void) setFileDialog:(FileDialog*) dialog
|
||||
{
|
||||
_dialog = dialog;
|
||||
}
|
||||
|
||||
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
|
||||
{
|
||||
BOOL showObject = YES;
|
||||
|
||||
NSString* resolvedLink = [[NSFileManager defaultManager] pathContentOfSymbolicLinkAtPath:filename];
|
||||
if ( resolvedLink != nil )
|
||||
filename = resolvedLink;
|
||||
|
||||
NSDictionary* fileAttribs = [[NSFileManager defaultManager]
|
||||
fileAttributesAtPath:filename traverseLink:YES];
|
||||
if (fileAttribs)
|
||||
{
|
||||
// check for packages
|
||||
if ([NSFileTypeDirectory isEqualTo:[fileAttribs objectForKey:NSFileType]])
|
||||
{
|
||||
if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename] == NO)
|
||||
showObject = YES; // it's a folder, OK to show
|
||||
else
|
||||
{
|
||||
// it's a packaged directory, apply check
|
||||
wxCFStringRef filecf([filename retain]);
|
||||
showObject = _dialog->CheckFile(filecf.AsString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the code above only solves links, not aliases, do this here:
|
||||
|
||||
NSString* resolvedAlias = nil;
|
||||
|
||||
CFURLRef url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault,
|
||||
(CFStringRef)filename,
|
||||
kCFURLPOSIXPathStyle,
|
||||
NO);
|
||||
if (url != NULL)
|
||||
{
|
||||
FSRef fsRef;
|
||||
if (CFURLGetFSRef(url, &fsRef))
|
||||
{
|
||||
Boolean targetIsFolder, wasAliased;
|
||||
OSErr err = FSResolveAliasFile (&fsRef, true, &targetIsFolder, &wasAliased);
|
||||
|
||||
if ((err == noErr) && wasAliased)
|
||||
{
|
||||
CFURLRef resolvedUrl = CFURLCreateFromFSRef(kCFAllocatorDefault, &fsRef);
|
||||
if (resolvedUrl != NULL)
|
||||
{
|
||||
resolvedAlias = (NSString*) CFURLCopyFileSystemPath(resolvedUrl,
|
||||
kCFURLPOSIXPathStyle);
|
||||
CFRelease(resolvedUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
CFRelease(url);
|
||||
}
|
||||
|
||||
if (resolvedAlias != nil)
|
||||
{
|
||||
// recursive call
|
||||
[resolvedAlias autorelease];
|
||||
showObject = [self panel:sender shouldShowFilename:resolvedAlias];
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCFStringRef filecf([filename retain]);
|
||||
showObject = _dialog->CheckFile(filecf.AsString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return showObject;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
IMPLEMENT_CLASS(FileDialog, FileDialogBase)
|
||||
|
||||
void FileDialog::Init()
|
||||
{
|
||||
m_filterIndex = -1;
|
||||
m_delegate = nil;
|
||||
m_sheetDelegate = nil;
|
||||
m_filterPanel = NULL;
|
||||
m_filterChoice = NULL;
|
||||
}
|
||||
|
||||
void FileDialog::Create(
|
||||
wxWindow *parent, const wxString& message,
|
||||
const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
|
||||
long style, const wxPoint& pos, const wxSize& sz, const wxString& name)
|
||||
{
|
||||
FileDialogBase::Create(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name);
|
||||
|
||||
m_sheetDelegate = [[ModalDialogDelegate alloc] init];
|
||||
[(ModalDialogDelegate*)m_sheetDelegate setImplementation: this];
|
||||
}
|
||||
|
||||
FileDialog::~FileDialog()
|
||||
{
|
||||
[m_sheetDelegate release];
|
||||
}
|
||||
|
||||
bool FileDialog::SupportsExtraControl() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NSArray* GetTypesFromExtension( const wxString extensiongroup, wxArrayString& extensions )
|
||||
{
|
||||
NSMutableArray* types = nil;
|
||||
extensions.Clear();
|
||||
|
||||
wxStringTokenizer tokenizer( extensiongroup, wxT(";") ) ;
|
||||
while ( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
wxString extension = tokenizer.GetNextToken() ;
|
||||
// Remove leading '*'
|
||||
if ( extension.length() && (extension.GetChar(0) == '*') )
|
||||
extension = extension.Mid( 1 );
|
||||
|
||||
// Remove leading '.'
|
||||
if ( extension.length() && (extension.GetChar(0) == '.') )
|
||||
extension = extension.Mid( 1 );
|
||||
|
||||
// Remove leading '*', this is for handling *.*
|
||||
if ( extension.length() && (extension.GetChar(0) == '*') )
|
||||
extension = extension.Mid( 1 );
|
||||
|
||||
if ( extension.IsEmpty() )
|
||||
{
|
||||
extensions.Clear();
|
||||
[types release];
|
||||
types = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ( types == nil )
|
||||
types = [[NSMutableArray alloc] init];
|
||||
|
||||
extensions.Add(extension.Lower());
|
||||
wxCFStringRef cfext(extension);
|
||||
[types addObject: (NSString*)cfext.AsNSString() ];
|
||||
#if 0
|
||||
// add support for classic fileType / creator here
|
||||
wxUint32 fileType, creator;
|
||||
// extension -> mactypes
|
||||
#endif
|
||||
}
|
||||
[types autorelease];
|
||||
return types;
|
||||
}
|
||||
|
||||
NSArray* GetTypesFromFilter( const wxString& filter, wxArrayString& names, wxArrayString& extensiongroups )
|
||||
{
|
||||
NSMutableArray* types = nil;
|
||||
bool allowAll = false;
|
||||
|
||||
names.Clear();
|
||||
extensiongroups.Clear();
|
||||
|
||||
if ( !filter.empty() )
|
||||
{
|
||||
wxStringTokenizer tokenizer( filter, wxT("|") );
|
||||
int numtokens = (int)tokenizer.CountTokens();
|
||||
if(numtokens == 1)
|
||||
{
|
||||
// we allow for compatibility reason to have a single filter expression (like *.*) without
|
||||
// an explanatory text, in that case the first part is name and extension at the same time
|
||||
wxString extension = tokenizer.GetNextToken();
|
||||
names.Add( extension );
|
||||
extensiongroups.Add( extension );
|
||||
}
|
||||
else
|
||||
{
|
||||
int numextensions = numtokens / 2;
|
||||
for(int i = 0; i < numextensions; i++)
|
||||
{
|
||||
wxString name = tokenizer.GetNextToken();
|
||||
wxString extension = tokenizer.GetNextToken();
|
||||
names.Add( name );
|
||||
extensiongroups.Add( extension );
|
||||
}
|
||||
}
|
||||
|
||||
const size_t extCount = extensiongroups.GetCount();
|
||||
wxArrayString extensions;
|
||||
for ( size_t i = 0 ; i < extCount; i++ )
|
||||
{
|
||||
NSArray* exttypes = GetTypesFromExtension(extensiongroups[i], extensions);
|
||||
if ( exttypes != nil )
|
||||
{
|
||||
if ( allowAll == false )
|
||||
{
|
||||
if ( types == nil )
|
||||
types = [[NSMutableArray alloc] init];
|
||||
|
||||
[types addObjectsFromArray:exttypes];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
allowAll = true;
|
||||
[types release];
|
||||
types = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
[types autorelease];
|
||||
return types;
|
||||
}
|
||||
|
||||
void FileDialog::ShowWindowModal()
|
||||
{
|
||||
wxCFStringRef cf( m_message );
|
||||
wxCFStringRef dir( m_dir );
|
||||
wxCFStringRef file( m_fileName );
|
||||
|
||||
wxNonOwnedWindow* parentWindow = NULL;
|
||||
|
||||
m_modality = wxDIALOG_MODALITY_WINDOW_MODAL;
|
||||
|
||||
if (GetParent())
|
||||
parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
|
||||
|
||||
wxASSERT_MSG(parentWindow, "Window modal display requires parent.");
|
||||
|
||||
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions ) ;
|
||||
if ( HasFlag(wxFD_SAVE) )
|
||||
{
|
||||
NSSavePanel* sPanel = [NSSavePanel savePanel];
|
||||
|
||||
SetupExtraControls(sPanel);
|
||||
|
||||
// makes things more convenient:
|
||||
[sPanel setCanCreateDirectories:YES];
|
||||
[sPanel setMessage:cf.AsNSString()];
|
||||
// if we should be able to descend into pacakges we must somehow
|
||||
// be able to pass this in
|
||||
[sPanel setTreatsFilePackagesAsDirectories:NO];
|
||||
[sPanel setCanSelectHiddenExtension:YES];
|
||||
[sPanel setAllowedFileTypes:types];
|
||||
[sPanel setAllowsOtherFileTypes:NO];
|
||||
|
||||
NSWindow* nativeParent = parentWindow->GetWXWindow();
|
||||
[sPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
|
||||
modalForWindow: nativeParent modalDelegate: m_sheetDelegate
|
||||
didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
|
||||
contextInfo: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSOpenPanel* oPanel = [NSOpenPanel openPanel];
|
||||
|
||||
SetupExtraControls(oPanel);
|
||||
|
||||
[oPanel setTreatsFilePackagesAsDirectories:NO];
|
||||
[oPanel setCanChooseDirectories:NO];
|
||||
[oPanel setResolvesAliases:YES];
|
||||
[oPanel setCanChooseFiles:YES];
|
||||
[oPanel setMessage:cf.AsNSString()];
|
||||
[oPanel setAllowsMultipleSelection: (HasFlag(wxFD_MULTIPLE) ? YES : NO )];
|
||||
|
||||
NSWindow* nativeParent = parentWindow->GetWXWindow();
|
||||
[oPanel beginSheetForDirectory:dir.AsNSString() file:file.AsNSString()
|
||||
types: types modalForWindow: nativeParent
|
||||
modalDelegate: m_sheetDelegate
|
||||
didEndSelector: @selector(sheetDidEnd:returnCode:contextInfo:)
|
||||
contextInfo: nil];
|
||||
}
|
||||
}
|
||||
|
||||
// Create a panel with the file type drop down list
|
||||
// If extra controls need to be added (see FileDialog::SetExtraControlCreator), add
|
||||
// them to the panel as well
|
||||
// Returns the newly created wxPanel
|
||||
|
||||
wxWindow* FileDialog::CreateFilterPanel(wxWindow *extracontrol)
|
||||
{
|
||||
wxPanel *extrapanel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
wxBoxSizer *verticalSizer = new wxBoxSizer(wxVERTICAL);
|
||||
extrapanel->SetSizer(verticalSizer);
|
||||
|
||||
// the file type control
|
||||
{
|
||||
wxBoxSizer *horizontalSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
verticalSizer->Add(horizontalSizer, 0, wxEXPAND, 0);
|
||||
wxStaticText *stattext = new wxStaticText( extrapanel, wxID_ANY, _("File type:") );
|
||||
horizontalSizer->Add(stattext, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
m_filterChoice = new wxChoice(extrapanel, wxID_ANY);
|
||||
horizontalSizer->Add(m_filterChoice, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);
|
||||
m_filterChoice->Append(m_filterNames);
|
||||
if( m_filterNames.GetCount() > 0)
|
||||
{
|
||||
if ( m_firstFileTypeFilter >= 0 )
|
||||
m_filterChoice->SetSelection(m_firstFileTypeFilter);
|
||||
}
|
||||
m_filterChoice->Connect(wxEVT_CHOICE, wxCommandEventHandler(FileDialog::OnFilterSelected), NULL, this);
|
||||
}
|
||||
|
||||
if(extracontrol)
|
||||
{
|
||||
wxBoxSizer *horizontalSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
verticalSizer->Add(horizontalSizer, 0, wxEXPAND, 0);
|
||||
|
||||
extracontrol->Reparent(extrapanel);
|
||||
horizontalSizer->Add(extracontrol);
|
||||
}
|
||||
|
||||
verticalSizer->Layout();
|
||||
verticalSizer->SetSizeHints(extrapanel);
|
||||
return extrapanel;
|
||||
}
|
||||
|
||||
void FileDialog::DoOnFilterSelected(int index)
|
||||
{
|
||||
NSArray* types = GetTypesFromExtension(m_filterExtensions[index],m_currentExtensions);
|
||||
NSSavePanel* panel = (NSSavePanel*) GetWXWindow();
|
||||
if ( m_delegate )
|
||||
[panel validateVisibleColumns];
|
||||
else
|
||||
[panel setAllowedFileTypes:types];
|
||||
}
|
||||
|
||||
// An item has been selected in the file filter wxChoice:
|
||||
void FileDialog::OnFilterSelected( wxCommandEvent &WXUNUSED(event) )
|
||||
{
|
||||
DoOnFilterSelected( m_filterChoice->GetSelection() );
|
||||
}
|
||||
|
||||
bool FileDialog::CheckFile( const wxString& filename )
|
||||
{
|
||||
if ( m_currentExtensions.GetCount() == 0 )
|
||||
return true;
|
||||
|
||||
wxString ext = filename.AfterLast('.').Lower();
|
||||
|
||||
for ( size_t i = 0; i < m_currentExtensions.GetCount(); ++i )
|
||||
{
|
||||
if ( ext == m_currentExtensions[i] )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileDialog::SetupExtraControls(WXWindow nativeWindow)
|
||||
{
|
||||
NSSavePanel* panel = (NSSavePanel*) nativeWindow;
|
||||
// for sandboxed app we cannot access the outer structures
|
||||
// this leads to problems with extra controls, so as a temporary
|
||||
// workaround for crashes we don't support those yet
|
||||
if ( [panel contentView] == nil || getenv("APP_SANDBOX_CONTAINER_ID") != NULL )
|
||||
return;
|
||||
|
||||
wxNonOwnedWindow::Create( GetParent(), nativeWindow );
|
||||
wxWindow* extracontrol = NULL;
|
||||
if ( HasExtraControlCreator() )
|
||||
{
|
||||
CreateExtraControl();
|
||||
extracontrol = GetExtraControl();
|
||||
}
|
||||
|
||||
NSView* accView = nil;
|
||||
|
||||
if ( m_useFileTypeFilter )
|
||||
{
|
||||
m_filterPanel = CreateFilterPanel(extracontrol);
|
||||
accView = m_filterPanel->GetHandle();
|
||||
if( HasFlag(wxFD_OPEN) )
|
||||
{
|
||||
if ( UMAGetSystemVersion() < 0x1060 || !HasAppKit_10_6() )
|
||||
{
|
||||
OpenPanelDelegate* del = [[OpenPanelDelegate alloc]init];
|
||||
[del setFileDialog:this];
|
||||
[panel setDelegate:del];
|
||||
m_delegate = del;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_filterPanel = NULL;
|
||||
m_filterChoice = NULL;
|
||||
if ( extracontrol != nil )
|
||||
accView = extracontrol->GetHandle();
|
||||
}
|
||||
|
||||
if ( accView != nil )
|
||||
{
|
||||
[accView removeFromSuperview];
|
||||
[panel setAccessoryView:accView];
|
||||
}
|
||||
else
|
||||
{
|
||||
[panel setAccessoryView:nil];
|
||||
}
|
||||
}
|
||||
|
||||
int FileDialog::ShowModal()
|
||||
{
|
||||
WX_HOOK_MODAL_DIALOG();
|
||||
|
||||
wxCFEventLoopPauseIdleEvents pause;
|
||||
|
||||
wxMacAutoreleasePool autoreleasepool;
|
||||
|
||||
wxCFStringRef cf( m_message );
|
||||
|
||||
wxCFStringRef dir( m_dir );
|
||||
wxCFStringRef file( m_fileName );
|
||||
|
||||
m_path = wxEmptyString;
|
||||
m_fileNames.Clear();
|
||||
m_paths.Clear();
|
||||
|
||||
wxNonOwnedWindow* parentWindow = NULL;
|
||||
int returnCode = -1;
|
||||
|
||||
if (GetParent())
|
||||
{
|
||||
parentWindow = dynamic_cast<wxNonOwnedWindow*>(wxGetTopLevelParent(GetParent()));
|
||||
}
|
||||
|
||||
|
||||
NSArray* types = GetTypesFromFilter( m_wildCard, m_filterNames, m_filterExtensions ) ;
|
||||
|
||||
m_useFileTypeFilter = m_filterExtensions.GetCount() > 1;
|
||||
|
||||
if( HasFlag(wxFD_OPEN) )
|
||||
{
|
||||
if ( !(wxSystemOptions::HasOption( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES ) && (wxSystemOptions::GetOptionInt( wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES ) == 1)) )
|
||||
m_useFileTypeFilter = false;
|
||||
}
|
||||
|
||||
m_firstFileTypeFilter = -1;
|
||||
|
||||
if ( m_useFileTypeFilter
|
||||
&& m_filterIndex >= 0 && m_filterIndex < m_filterExtensions.GetCount() )
|
||||
{
|
||||
m_firstFileTypeFilter = m_filterIndex;
|
||||
}
|
||||
else if ( m_useFileTypeFilter )
|
||||
{
|
||||
types = nil;
|
||||
bool useDefault = true;
|
||||
for ( size_t i = 0; i < m_filterExtensions.GetCount(); ++i )
|
||||
{
|
||||
types = GetTypesFromExtension(m_filterExtensions[i], m_currentExtensions);
|
||||
if ( m_currentExtensions.GetCount() == 0 )
|
||||
{
|
||||
useDefault = false;
|
||||
m_firstFileTypeFilter = i;
|
||||
break;
|
||||
}
|
||||
|
||||
for ( size_t j = 0; j < m_currentExtensions.GetCount(); ++j )
|
||||
{
|
||||
if ( m_fileName.EndsWith(m_currentExtensions[j]) )
|
||||
{
|
||||
m_firstFileTypeFilter = i;
|
||||
useDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !useDefault )
|
||||
break;
|
||||
}
|
||||
if ( useDefault )
|
||||
{
|
||||
types = GetTypesFromExtension(m_filterExtensions[0], m_currentExtensions);
|
||||
m_firstFileTypeFilter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( HasFlag(wxFD_SAVE) )
|
||||
{
|
||||
NSSavePanel* sPanel = [NSSavePanel savePanel];
|
||||
|
||||
SetupExtraControls(sPanel);
|
||||
|
||||
// makes things more convenient:
|
||||
[sPanel setCanCreateDirectories:YES];
|
||||
[sPanel setMessage:cf.AsNSString()];
|
||||
// if we should be able to descend into pacakges we must somehow
|
||||
// be able to pass this in
|
||||
[sPanel setTreatsFilePackagesAsDirectories:NO];
|
||||
[sPanel setCanSelectHiddenExtension:YES];
|
||||
[sPanel setAllowedFileTypes:types];
|
||||
[sPanel setAllowsOtherFileTypes:NO];
|
||||
|
||||
if ( HasFlag(wxFD_OVERWRITE_PROMPT) )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
Let the file dialog know what file type should be used initially.
|
||||
If this is not done then when setting the filter index
|
||||
programmatically to 1 the file will still have the extension
|
||||
of the first file type instead of the second one. E.g. when file
|
||||
types are foo and bar, a filename "myletter" with SetDialogIndex(1)
|
||||
would result in saving as myletter.foo, while we want myletter.bar.
|
||||
*/
|
||||
if(m_firstFileTypeFilter > 0)
|
||||
{
|
||||
DoOnFilterSelected(m_firstFileTypeFilter);
|
||||
}
|
||||
|
||||
returnCode = [sPanel runModalForDirectory: m_dir.IsEmpty() ? nil : dir.AsNSString() file:file.AsNSString() ];
|
||||
ModalFinishedCallback(sPanel, returnCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSOpenPanel* oPanel = [NSOpenPanel openPanel];
|
||||
|
||||
SetupExtraControls(oPanel);
|
||||
|
||||
[oPanel setTreatsFilePackagesAsDirectories:NO];
|
||||
[oPanel setCanChooseDirectories:NO];
|
||||
[oPanel setResolvesAliases:YES];
|
||||
[oPanel setCanChooseFiles:YES];
|
||||
[oPanel setMessage:cf.AsNSString()];
|
||||
[oPanel setAllowsMultipleSelection: (HasFlag(wxFD_MULTIPLE) ? YES : NO )];
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
if ( UMAGetSystemVersion() >= 0x1060 && HasAppKit_10_6() )
|
||||
{
|
||||
[oPanel setAllowedFileTypes: (m_delegate == nil ? types : nil)];
|
||||
if ( !m_dir.IsEmpty() )
|
||||
[oPanel setDirectoryURL:[NSURL fileURLWithPath:dir.AsNSString()
|
||||
isDirectory:YES]];
|
||||
returnCode = [oPanel runModal];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
returnCode = [oPanel runModalForDirectory:m_dir.IsEmpty() ? nil : dir.AsNSString()
|
||||
file:file.AsNSString() types:(m_delegate == nil ? types : nil)];
|
||||
}
|
||||
|
||||
ModalFinishedCallback(oPanel, returnCode);
|
||||
}
|
||||
|
||||
return GetReturnCode();
|
||||
}
|
||||
|
||||
void FileDialog::ModalFinishedCallback(void* panel, int returnCode)
|
||||
{
|
||||
int result = wxID_CANCEL;
|
||||
if (HasFlag(wxFD_SAVE))
|
||||
{
|
||||
if (returnCode == NSOKButton )
|
||||
{
|
||||
NSSavePanel* sPanel = (NSSavePanel*)panel;
|
||||
result = wxID_OK;
|
||||
|
||||
m_path = wxCFStringRef::AsStringWithNormalizationFormC([sPanel filename]);
|
||||
m_fileName = wxFileNameFromPath(m_path);
|
||||
m_dir = wxPathOnly( m_path );
|
||||
if (m_filterChoice)
|
||||
{
|
||||
m_filterIndex = m_filterChoice->GetSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSOpenPanel* oPanel = (NSOpenPanel*)panel;
|
||||
if (returnCode == NSOKButton )
|
||||
{
|
||||
panel = oPanel;
|
||||
result = wxID_OK;
|
||||
NSArray* filenames = [oPanel filenames];
|
||||
for ( size_t i = 0 ; i < [filenames count] ; ++ i )
|
||||
{
|
||||
wxString fnstr = wxCFStringRef::AsStringWithNormalizationFormC([filenames objectAtIndex:i]);
|
||||
m_paths.Add( fnstr );
|
||||
m_fileNames.Add( wxFileNameFromPath(fnstr) );
|
||||
if ( i == 0 )
|
||||
{
|
||||
m_path = fnstr;
|
||||
m_fileName = wxFileNameFromPath(fnstr);
|
||||
m_dir = wxPathOnly( fnstr );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_delegate )
|
||||
{
|
||||
[oPanel setDelegate:nil];
|
||||
[m_delegate release];
|
||||
m_delegate = nil;
|
||||
}
|
||||
}
|
||||
SetReturnCode(result);
|
||||
|
||||
if (GetModality() == wxDIALOG_MODALITY_WINDOW_MODAL)
|
||||
SendWindowModalDialogEvent ( wxEVT_WINDOW_MODAL_DIALOG_CLOSED );
|
||||
|
||||
// workaround for sandboxed app, see above
|
||||
if ( m_isNativeWindowWrapper )
|
||||
UnsubclassWin();
|
||||
[(NSSavePanel*) panel setAccessoryView:nil];
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -178,7 +178,7 @@
|
|||
#define USE_VAMP 1
|
||||
|
||||
/* Define if VST plug-in support is enabled */
|
||||
#define USE_VST 1
|
||||
#define USE_VST 0
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.0.6"
|
||||
|
|
|
@ -1,13 +1,3 @@
|
|||
// Macintosh-specific include file
|
||||
|
||||
// Audacity's four-character "creator" code and project type code
|
||||
#define AUDACITY_CREATOR 'auDy'
|
||||
#define AUDACITY_PROJECT_TYPE 'auDp'
|
||||
|
||||
#include <wx/defs.h>
|
||||
#include "../src/configunix.h"
|
||||
#define USE_AQUA_THEME 1
|
||||
#define USE_VST 1
|
||||
|
||||
// arch-tag: 1f1d80ef-d1b4-4c9e-8226-ec3b93dcb46c
|
||||
|
||||
|
|
|
@ -542,8 +542,10 @@ void AboutDialog::PopulateInformationPage( ShuttleGui & S )
|
|||
|
||||
// Install prefix
|
||||
/* i18n-hint: The directory audacity is installed into (on *nix systems) */
|
||||
#ifdef __WXGTK__
|
||||
AddBuildinfoRow(&informationStr, _("Installation Prefix: "), \
|
||||
wxT(INSTALL_PREFIX));
|
||||
#endif
|
||||
|
||||
// Location of settings
|
||||
AddBuildinfoRow(&informationStr,_("Settings folder: "), \
|
||||
|
|
|
@ -674,6 +674,9 @@ int main(int argc, char *argv[])
|
|||
unsetenv("DYLD_LIBRARY_PATH");
|
||||
execve(argv[0], argv, environ);
|
||||
}
|
||||
|
||||
wxDISABLE_DEBUG_SUPPORT();
|
||||
|
||||
return wxEntry(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
@ -1290,64 +1293,6 @@ bool AudacityApp::OnInit()
|
|||
// Initialize the ModuleManager, including loading found modules
|
||||
ModuleManager::Get().Initialize(*mCmdHandler);
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
FinishInits();
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if wxCHECK_VERSION(3, 0, 0)
|
||||
#include <wx/evtloop.h>
|
||||
static bool bInitsDone = false;
|
||||
void AudacityApp::OnEventLoopEnter(wxEventLoopBase * pLoop)
|
||||
{
|
||||
if( !pLoop->IsMain() )
|
||||
return;
|
||||
if (bInitsDone)
|
||||
return;
|
||||
bInitsDone = true;
|
||||
FinishInits();
|
||||
}
|
||||
#endif
|
||||
|
||||
// JKC: I've split 'FinishInits()' from 'OnInit()', so that
|
||||
// we can have a real event loop running. We could (I think)
|
||||
// put everything that is in OnInit() in here.
|
||||
// This change was to support wxWidgets 3.0.0 and allow us
|
||||
// to show a dialog (for module loading) during initialisation.
|
||||
// without it messing up the splash screen.
|
||||
// Hasn't actually fixed that yet, but is addressing the point
|
||||
// they make in their release notes.
|
||||
void AudacityApp::FinishInits()
|
||||
{
|
||||
|
||||
// Until we are ready for wxWidgets 3.x, put a warning dialog up.
|
||||
// Our problem is that distros may ship with 3.x builds as default.
|
||||
// We are saying, don't.
|
||||
//
|
||||
// wx3 is Ok for experimental builds.
|
||||
//
|
||||
// Deliberately not translated. People can search for the english error
|
||||
// text for more details. This error will only show in versions
|
||||
// of Audacity that were incorrectly built.
|
||||
//
|
||||
// The intention was to do this, if needed, as part of the splash screen.
|
||||
// However the splash screen is one of the things broken by wx3.0
|
||||
// changes in OnInit handling. We also can't put this dialog earlier.
|
||||
#if wxCHECK_VERSION(3, 0, 0)
|
||||
ShowErrorDialog( NULL,
|
||||
wxT("Bad Version"),
|
||||
wxT(
|
||||
"Audacity should be built with wxWidgets 2.8.12.\n\n This version \
|
||||
of Audacity (") AUDACITY_VERSION_STRING wxT(") is using ") wxVERSION_STRING \
|
||||
wxT( ".\n We're not ready for that version of wxWidgets yet.\n\n \
|
||||
Click the 'Help' button for known issues."),
|
||||
wxT("http://wiki.audacityteam.org/wiki/Incorrect_wxWidgets_Version"),
|
||||
true);
|
||||
#endif
|
||||
|
||||
|
||||
// Parse command line and handle options that might require
|
||||
// immediate exit...no need to initialize all of the audio
|
||||
// stuff to display the version string.
|
||||
|
@ -1530,6 +1475,8 @@ Click the 'Help' button for known issues."),
|
|||
|
||||
mTimer.SetOwner(this, kAudacityAppTimerID);
|
||||
mTimer.Start(200);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void AudacityApp::InitCommandHandler()
|
||||
|
|
|
@ -105,10 +105,6 @@ class AudacityApp:public wxApp {
|
|||
public:
|
||||
AudacityApp();
|
||||
virtual bool OnInit(void);
|
||||
void FinishInits();
|
||||
#if wxCHECK_VERSION(3, 0, 0)
|
||||
virtual void OnEventLoopEnter(wxEventLoopBase * pLoop);
|
||||
#endif
|
||||
virtual int OnExit(void);
|
||||
virtual void OnFatalException();
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ void AudacityLogger::Flush()
|
|||
}
|
||||
}
|
||||
|
||||
void AudacityLogger::DoLogString(const wxChar *str, time_t WXUNUSED(t))
|
||||
void AudacityLogger::DoLogText(const wxString & str)
|
||||
{
|
||||
if (!wxIsMainThread()) {
|
||||
wxMutexGuiEnter();
|
||||
|
@ -288,7 +288,7 @@ void AudacityLogger::OnClose(wxCommandEvent & WXUNUSED(e))
|
|||
void AudacityLogger::OnClear(wxCommandEvent & WXUNUSED(e))
|
||||
{
|
||||
mBuffer = wxEmptyString;
|
||||
DoLogString(wxT("Log Cleared."), 0);
|
||||
DoLogText(wxT("Log Cleared."));
|
||||
}
|
||||
|
||||
void AudacityLogger::OnSave(wxCommandEvent & WXUNUSED(e))
|
||||
|
|
|
@ -38,7 +38,7 @@ class AudacityLogger:public wxEvtHandler, public wxLog {
|
|||
|
||||
protected:
|
||||
virtual void Flush();
|
||||
virtual void DoLogString(const wxChar *szString, time_t t);
|
||||
virtual void DoLogText(const wxString & msg);
|
||||
|
||||
private:
|
||||
void OnCloseWindow(wxCloseEvent & e);
|
||||
|
|
|
@ -275,10 +275,10 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag,
|
|||
|
||||
// We need to find the track and sequence where the blockfile belongs
|
||||
WaveTrackArray tracks = mProject->GetTracks()->GetWaveTrackArray(false);
|
||||
size_t index;
|
||||
int index;
|
||||
if (mAutoSaveIdent)
|
||||
{
|
||||
for (index = 0; index < tracks.GetCount(); index++)
|
||||
for (index = 0; index < (int) tracks.GetCount(); index++)
|
||||
{
|
||||
if (tracks[index]->GetAutoSaveIdent() == mAutoSaveIdent)
|
||||
{
|
||||
|
@ -291,7 +291,7 @@ bool RecordingRecoveryHandler::HandleXMLTag(const wxChar *tag,
|
|||
index = tracks.GetCount() - mNumChannels + mChannel;
|
||||
}
|
||||
|
||||
if (index < 0 || index >= tracks.GetCount())
|
||||
if (index < 0 || index >= (int) tracks.GetCount())
|
||||
{
|
||||
// This should only happen if there is a bug
|
||||
wxASSERT(false);
|
||||
|
@ -460,7 +460,7 @@ void AutoSaveFile::WriteAttr(const wxString & name, const wxString & value)
|
|||
short len = value.Length() * sizeof(wxChar);
|
||||
|
||||
mBuffer.Write(&len, sizeof(len));
|
||||
mBuffer.Write(value.c_str(), len);
|
||||
mBuffer.Write(value.wx_str(), len);
|
||||
}
|
||||
|
||||
void AutoSaveFile::WriteAttr(const wxString & name, int value)
|
||||
|
@ -528,7 +528,7 @@ void AutoSaveFile::WriteData(const wxString & value)
|
|||
short len = value.Length() * sizeof(wxChar);
|
||||
|
||||
mBuffer.Write(&len, sizeof(len));
|
||||
mBuffer.Write(value.c_str(), len);
|
||||
mBuffer.Write(value.wx_str(), len);
|
||||
}
|
||||
|
||||
void AutoSaveFile::Write(const wxString & value)
|
||||
|
@ -538,7 +538,7 @@ void AutoSaveFile::Write(const wxString & value)
|
|||
short len = value.Length() * sizeof(wxChar);
|
||||
|
||||
mBuffer.Write(&len, sizeof(len));
|
||||
mBuffer.Write(value.c_str(), len);
|
||||
mBuffer.Write(value.wx_str(), len);
|
||||
}
|
||||
|
||||
void AutoSaveFile::WriteSubTree(const AutoSaveFile & value)
|
||||
|
@ -611,7 +611,7 @@ void AutoSaveFile::WriteName(const wxString & name)
|
|||
mDict.PutC(FT_Name);
|
||||
mDict.Write(&id, sizeof(id));
|
||||
mDict.Write(&len, sizeof(len));
|
||||
mDict.Write(name.c_str(), len);
|
||||
mDict.Write(name.wx_str(), len);
|
||||
}
|
||||
|
||||
CheckSpace(mBuffer);
|
||||
|
@ -692,8 +692,7 @@ bool AutoSaveFile::Decode(const wxString & fileName)
|
|||
file.Close();
|
||||
|
||||
// Decode to a temporary file to preserve the orignal.
|
||||
wxString tempName = fn.CreateTempFileName(fn.GetPath());
|
||||
|
||||
wxString tempName = fn.CreateTempFileName(fn.GetFullPath());
|
||||
bool opened = false;
|
||||
|
||||
XMLFileWriter out;
|
||||
|
|
|
@ -68,59 +68,9 @@ void FileIO::Close()
|
|||
mInputStream = NULL;
|
||||
}
|
||||
|
||||
SetCatalogInfo();
|
||||
|
||||
mOpen = false;
|
||||
}
|
||||
|
||||
// MacOS: set the file type/creator so that the OS knows it's an MP3
|
||||
// file which was created by Audacity
|
||||
|
||||
void FileIO::SetCatalogInfo()
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
if (!mOpen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wxUint32 type;
|
||||
wxFileName fn(mName);
|
||||
wxString ext = fn.GetExt().MakeUpper() + wxT(" ");
|
||||
|
||||
type = (ext[0] & 0xff) << 24 |
|
||||
(ext[1] & 0xff) << 16 |
|
||||
(ext[2] & 0xff) << 8 |
|
||||
(ext[3] & 0xff);
|
||||
|
||||
SetCatalogInfo(type);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
void FileIO::SetCatalogInfo(wxUint32 type)
|
||||
#else
|
||||
void FileIO::SetCatalogInfo(wxUint32 WXUNUSED(type))
|
||||
#endif
|
||||
{
|
||||
#ifdef __WXMAC__
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
if (!mOpen ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wxFileName fn(mName);
|
||||
|
||||
fn.MacSetTypeAndCreator(type, AUDACITY_CREATOR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
wxInputStream & FileIO::Read(void *buf, size_t size)
|
||||
{
|
||||
if (mInputStream == NULL) {
|
||||
|
|
|
@ -34,11 +34,6 @@ class FileIO
|
|||
wxInputStream & Read(void *buffer, size_t size);
|
||||
wxOutputStream & Write(const void *buffer, size_t size);
|
||||
|
||||
// On the Mac, this sets the file type and creator. It does nothing on
|
||||
// other platforms.
|
||||
void SetCatalogInfo();
|
||||
void SetCatalogInfo(wxUint32 type);
|
||||
|
||||
private:
|
||||
wxString mName;
|
||||
FileIOMode mMode;
|
||||
|
|
|
@ -742,11 +742,7 @@ void LabelTrack::Draw(wxDC & dc, const wxRect & r, double h, double pps,
|
|||
|
||||
int i;
|
||||
|
||||
#ifdef __WXMAC__
|
||||
long textWidth, textHeight;
|
||||
#else
|
||||
int textWidth, textHeight;
|
||||
#endif
|
||||
wxCoord textWidth, textHeight;
|
||||
|
||||
// Get the text widths.
|
||||
// TODO: Make more efficient by only re-computing when a
|
||||
|
|
|
@ -160,9 +160,12 @@ void GetLanguages(wxArrayString &langCodes, wxArrayString &langNames)
|
|||
localLanguageName[wxT("zh_TW")] = wxT("Chinese (Traditional)");
|
||||
|
||||
wxArrayString audacityPathList = wxGetApp().audacityPathList;
|
||||
|
||||
#if defined(__WXGTK__)
|
||||
wxGetApp().AddUniquePathToPathList(wxString::Format(wxT("%s/share/locale"),
|
||||
wxT(INSTALL_PREFIX)),
|
||||
audacityPathList);
|
||||
#endif
|
||||
|
||||
for (LangHash::iterator i = localLanguageName.begin();
|
||||
i != localLanguageName.end();
|
||||
|
|
|
@ -49,7 +49,7 @@ LyricsWindow::LyricsWindow(AudacityProject *parent):
|
|||
wxT("") :
|
||||
wxString::Format(
|
||||
wxT(" - %s"),
|
||||
parent->GetName().c_str()).c_str())),
|
||||
parent->GetName()))),
|
||||
wxPoint(100, 300), gSize,
|
||||
//v Bug in wxFRAME_FLOAT_ON_PARENT:
|
||||
// If both the project frame and LyricsWindow are minimized and you restore LyricsWindow,
|
||||
|
|
|
@ -1707,11 +1707,11 @@ const wxSize kDefaultSize =
|
|||
|
||||
MixerBoardFrame::MixerBoardFrame(AudacityProject* parent)
|
||||
: wxFrame(parent, -1,
|
||||
wxString::Format(_("Audacity Mixer Board%s"),
|
||||
((parent->GetName() == wxEmptyString) ?
|
||||
wxT("") :
|
||||
wxString::Format(wxT(" - %s"),
|
||||
parent->GetName().c_str()).c_str())),
|
||||
wxString::Format(_("Audacity Mixer Board%s"),
|
||||
((parent->GetName() == wxEmptyString) ?
|
||||
wxT("") :
|
||||
wxString::Format(wxT(" - %s"),
|
||||
parent->GetName()))),
|
||||
wxDefaultPosition, kDefaultSize,
|
||||
//vvv Bug in wxFRAME_FLOAT_ON_PARENT:
|
||||
// If both the project frame and MixerBoardFrame are minimized and you restore MixerBoardFrame,
|
||||
|
|
|
@ -487,6 +487,8 @@ AudacityProject *CreateNewAudacityProject()
|
|||
bool bIconized;
|
||||
GetNextWindowPlacement(&wndRect, &bMaximized, &bIconized);
|
||||
|
||||
wndRect.width = 500;
|
||||
wndRect.height = 500;
|
||||
//Create and show a new project
|
||||
AudacityProject *p = new AudacityProject(NULL, -1,
|
||||
wxPoint(wndRect.x, wndRect.y),
|
||||
|
@ -3467,13 +3469,6 @@ bool AudacityProject::Save(bool overwrite /* = true */ ,
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef __WXMAC__
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
wxFileName fn(mFileName);
|
||||
fn.MacSetTypeAndCreator(AUDACITY_PROJECT_TYPE, AUDACITY_CREATOR);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (bWantSaveCompressed)
|
||||
mWantSaveCompressed = false; // Don't want this mode for AudacityProject::WriteXML() any more.
|
||||
else
|
||||
|
|
|
@ -1503,10 +1503,8 @@ struct ClipParameters
|
|||
// Do a bunch of calculations common to waveform and spectrum drawing.
|
||||
ClipParameters
|
||||
(bool spectrum, const WaveTrack *track, const WaveClip *clip, const wxRect &r,
|
||||
const SelectedRegion &selectedRegion, const ViewInfo &viewInfo)
|
||||
const SelectedRegion &WXUNUSED(selectedRegion), const ViewInfo &viewInfo)
|
||||
{
|
||||
selectedRegion;
|
||||
|
||||
tOffset = clip->GetOffset();
|
||||
rate = clip->GetRate();
|
||||
|
||||
|
@ -1849,7 +1847,7 @@ static inline float findValue
|
|||
value /= binwidth;
|
||||
}
|
||||
#else
|
||||
half;
|
||||
wxUnusedVar(half);
|
||||
// Maximum method, and no apportionment of any single bins over multiple pixel rows
|
||||
// See Bug971
|
||||
int bin = std::min(half - 1, int(floor(0.5 + bin0)));
|
||||
|
@ -2954,12 +2952,8 @@ void TrackArtist::DrawNoteTrack(NoteTrack *track,
|
|||
|
||||
// now do justification
|
||||
const char *s = LookupStringAttribute(note, texts, "");
|
||||
#ifdef __WXMAC__
|
||||
long textWidth, textHeight;
|
||||
#else
|
||||
int textWidth, textHeight;
|
||||
#endif
|
||||
dc.GetTextExtent(LAT1CTOWX(s), &textWidth, &textHeight);
|
||||
wxCoord textWidth, textHeight;
|
||||
dc.GetTextExtent(wxString::FromUTF8(s), &textWidth, &textHeight);
|
||||
long hoffset = 0;
|
||||
long voffset = -textHeight; // default should be baseline of text
|
||||
|
||||
|
@ -3074,7 +3068,7 @@ int TrackArtist::GetSpectrumLogMaxFreq(int deffreq)
|
|||
|
||||
int TrackArtist::GetSpectrumWindowSize(bool includeZeroPadding)
|
||||
{
|
||||
includeZeroPadding;
|
||||
wxUnusedVar(includeZeroPadding);
|
||||
const int &windowSize = SpectrogramSettings::defaults().windowSize;
|
||||
#ifdef EXPERIMENTAL_ZERO_PADDED_SPECTROGRAMS
|
||||
if (includeZeroPadding) {
|
||||
|
|
|
@ -149,7 +149,7 @@ sampleCount VoiceKey::OnForward (WaveTrack & t, sampleCount start, sampleCount l
|
|||
|
||||
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
|
||||
//Only go through the first SignalWindowSizeInt samples, and choose the first that trips the key.
|
||||
sampleFormat *buffer = new sampleFormat[samplesleft];
|
||||
float *buffer = new float[samplesleft];
|
||||
t.Get((samplePtr)buffer, floatSample,lastsubthresholdsample,samplesleft);
|
||||
|
||||
|
||||
|
@ -300,7 +300,7 @@ sampleCount VoiceKey::OnBackward (WaveTrack & t, sampleCount end, sampleCount le
|
|||
|
||||
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
|
||||
//Only go through the first mSilentWindowSizeInt samples, and choose the first that trips the key.
|
||||
sampleFormat *buffer = new sampleFormat[samplesleft];
|
||||
float *buffer = new float[samplesleft];
|
||||
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample-samplesleft,samplesleft);
|
||||
|
||||
//Initialize these trend markers atrend and ztrend. They keep track of the
|
||||
|
@ -438,7 +438,7 @@ sampleCount VoiceKey::OffForward (WaveTrack & t, sampleCount start, sampleCount
|
|||
|
||||
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
|
||||
//Only go through the first SilentWindowSizeInt samples, and choose the first that trips the key.
|
||||
sampleFormat *buffer = new sampleFormat[samplesleft];
|
||||
float *buffer = new float[samplesleft];
|
||||
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample,samplesleft);
|
||||
|
||||
//Initialize these trend markers atrend and ztrend. They keep track of the
|
||||
|
@ -578,7 +578,7 @@ sampleCount VoiceKey::OffBackward (WaveTrack & t, sampleCount end, sampleCount l
|
|||
|
||||
//To speed things up, create a local buffer to store things in, to avoid the costly t.Get();
|
||||
//Only go through the first SilentWindowSizeInt samples, and choose the first that trips the key.
|
||||
sampleFormat *buffer = new sampleFormat[samplesleft];
|
||||
float *buffer = new float[samplesleft];
|
||||
t.Get((samplePtr)buffer, floatSample, lastsubthresholdsample-samplesleft,samplesleft);
|
||||
|
||||
//Initialize these trend markers atrend and ztrend. They keep track of the
|
||||
|
@ -885,10 +885,10 @@ double VoiceKey::TestEnergy (WaveTrack & t, sampleCount start, sampleCount len)
|
|||
|
||||
|
||||
//This will update RMSE by adding one element and subtracting another
|
||||
void VoiceKey::TestEnergyUpdate (double & prevErg, int len, const sampleFormat & drop, const sampleFormat & add)
|
||||
void VoiceKey::TestEnergyUpdate (double & prevErg, int len, const float & drop, const float & add)
|
||||
{
|
||||
//This is an updating formula for RMSE. It will only recalculate what's changed.
|
||||
prevErg = prevErg + (double)(abs(add) - abs(drop))/len;
|
||||
prevErg = prevErg + (double)(fabs(add) - fabs(drop))/len;
|
||||
|
||||
}
|
||||
|
||||
|
@ -906,7 +906,7 @@ double VoiceKey::TestSignChanges(WaveTrack & t, sampleCount start, sampleCount l
|
|||
|
||||
if( blockSize > len)
|
||||
blockSize = len;
|
||||
sampleFormat *buffer = new sampleFormat[blockSize]; //Get a sampling buffer
|
||||
float *buffer = new float[blockSize]; //Get a sampling buffer
|
||||
|
||||
while(len > 0) {
|
||||
|
||||
|
@ -940,10 +940,10 @@ double VoiceKey::TestSignChanges(WaveTrack & t, sampleCount start, sampleCount l
|
|||
}
|
||||
|
||||
void VoiceKey::TestSignChangesUpdate(double & currentsignchanges, int len,
|
||||
const sampleFormat & a1,
|
||||
const sampleFormat & a2,
|
||||
const sampleFormat & z1,
|
||||
const sampleFormat & z2)
|
||||
const float & a1,
|
||||
const float & a2,
|
||||
const float & z1,
|
||||
const float & z2)
|
||||
{
|
||||
|
||||
if(sgn(a1)!=sgn(a2)) currentsignchanges -= 1.0/len;
|
||||
|
@ -960,12 +960,12 @@ double VoiceKey::TestDirectionChanges(WaveTrack & t, sampleCount start, sampleCo
|
|||
sampleCount originalLen = len; //Keep track of the length of block to process (its not the length of t)
|
||||
sampleCount blockSize = t.GetMaxBlockSize(); //Determine size of sampling buffer
|
||||
unsigned long directionchanges = 1;
|
||||
sampleFormat lastval=sampleFormat(0);
|
||||
float lastval=float(0);
|
||||
int lastdirection=1;
|
||||
|
||||
if( blockSize > len)
|
||||
blockSize = len;
|
||||
sampleFormat *buffer = new sampleFormat[blockSize]; //Get a sampling buffer
|
||||
float *buffer = new float[blockSize]; //Get a sampling buffer
|
||||
|
||||
while(len > 0) {
|
||||
|
||||
|
@ -1004,8 +1004,8 @@ double VoiceKey::TestDirectionChanges(WaveTrack & t, sampleCount start, sampleCo
|
|||
// This method does an updating by looking at the trends
|
||||
// This will change currentdirections and atrend/trend, so be warned.
|
||||
void VoiceKey::TestDirectionChangesUpdate(double & currentdirectionchanges, int len,
|
||||
int & atrend, const sampleFormat & a1, const sampleFormat & a2,
|
||||
int & ztrend, const sampleFormat & z1, const sampleFormat & z2)
|
||||
int & atrend, const float & a1, const float & a2,
|
||||
int & ztrend, const float & z1, const float & z2)
|
||||
{
|
||||
|
||||
if(sgn(a2 - a1)!= atrend ) {
|
||||
|
|
|
@ -81,12 +81,12 @@ class VoiceKey {
|
|||
double TestSignChanges (WaveTrack & t, sampleCount start, sampleCount len);
|
||||
double TestDirectionChanges(WaveTrack & t, sampleCount start, sampleCount len);
|
||||
|
||||
void TestEnergyUpdate (double & prevErg, int length, const sampleFormat & drop, const sampleFormat & add);
|
||||
void TestSignChangesUpdate(double & currentsignchanges,int length, const sampleFormat & a1,
|
||||
const sampleFormat & a2, const sampleFormat & z1, const sampleFormat & z2);
|
||||
void TestEnergyUpdate (double & prevErg, int length, const float & drop, const float & add);
|
||||
void TestSignChangesUpdate(double & currentsignchanges,int length, const float & a1,
|
||||
const float & a2, const float & z1, const float & z2);
|
||||
void TestDirectionChangesUpdate(double & currentdirectionchanges,int length,
|
||||
int & atrend, const sampleFormat & a1, const sampleFormat & a2,
|
||||
int & ztrend, const sampleFormat & z1, const sampleFormat & z2);
|
||||
int & atrend, const float & a1, const float & a2,
|
||||
int & ztrend, const float & z1, const float & z2);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -134,8 +134,12 @@ int WrappedType::ReadAsInt()
|
|||
switch( eWrappedType )
|
||||
{
|
||||
case eWrappedString:
|
||||
return wxAtoi( *mpStr );
|
||||
{
|
||||
long l;
|
||||
mpStr->ToLong(&l);
|
||||
return (int) l;
|
||||
break;
|
||||
}
|
||||
case eWrappedInt:
|
||||
return *mpInt;
|
||||
break;
|
||||
|
@ -217,8 +221,12 @@ void WrappedType::WriteToAsString( const wxString & InStr)
|
|||
*mpStr = InStr;
|
||||
break;
|
||||
case eWrappedInt:
|
||||
*mpInt = wxAtoi( InStr );
|
||||
{
|
||||
long l;
|
||||
InStr.ToLong(&l);
|
||||
*mpInt = (int) l;
|
||||
break;
|
||||
}
|
||||
case eWrappedDouble:
|
||||
*mpDouble = Internat::CompatibleToDouble( InStr );
|
||||
break;
|
||||
|
|
|
@ -49,10 +49,6 @@ greater use in future.
|
|||
#include "TimeWarper.h"
|
||||
#include "nyquist/Nyquist.h"
|
||||
|
||||
#if defined(__WXMAC__)
|
||||
#include <wx/mac/private.h>
|
||||
#endif
|
||||
|
||||
static const int kDummyID = 30000;
|
||||
static const int kSaveAsID = 30001;
|
||||
static const int kImportID = 30002;
|
||||
|
@ -2810,6 +2806,7 @@ bool EffectUIHost::Show(bool show)
|
|||
{
|
||||
if (!mIsModal)
|
||||
{
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
// We want the effects windows on the Mac to float above the project window
|
||||
// but still have normal modal dialogs appear above the effects windows and
|
||||
// not let the effect windows fall behind the project window.
|
||||
|
@ -2819,6 +2816,7 @@ bool EffectUIHost::Show(bool show)
|
|||
WindowGroupRef parentGroup = GetWindowGroup((WindowRef) ((wxFrame *)wxGetTopLevelParent(mParent))->MacGetWindowRef());
|
||||
ChangeWindowGroupAttributes(parentGroup, kWindowGroupAttrSharedActivation, kWindowGroupAttrMoveTogether);
|
||||
SetWindowGroup(windowRef, parentGroup);
|
||||
#endif
|
||||
}
|
||||
mIsModal = false;
|
||||
|
||||
|
@ -3051,6 +3049,7 @@ bool EffectUIHost::Initialize()
|
|||
|
||||
InitializeRealtime();
|
||||
|
||||
SetMinSize(GetSize());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
VSTControl.h
|
||||
|
||||
Leland Lucius
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef AUDACITY_AUCONTROL_H
|
||||
#define AUDACITY_AUCONTROL_H
|
||||
|
||||
#if !defined(_LP64)
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include <wx/osx/private.h>
|
||||
#include <wx/control.h>
|
||||
|
||||
//#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
//#include <AudioUnit/AudioUnitProperties.h>
|
||||
|
||||
class VSTControlImpl : public wxWidgetCocoaImpl
|
||||
{
|
||||
public :
|
||||
VSTControlImpl(wxWindowMac *peer, NSView *view);
|
||||
~VSTControlImpl();
|
||||
};
|
||||
|
||||
class VSTControl : public wxControl
|
||||
{
|
||||
public:
|
||||
VSTControl();
|
||||
~VSTControl();
|
||||
|
||||
bool Create(wxWindow *parent, AudioComponent comp, AudioUnit unit, bool custom);
|
||||
void CreateCocoa();
|
||||
void CreateGeneric();
|
||||
void CocoaViewResized();
|
||||
|
||||
void OnSize(wxSizeEvent & evt);
|
||||
|
||||
#if !defined(_LP64)
|
||||
void CreateCarbon();
|
||||
void CreateCarbonOverlay();
|
||||
void CarbonViewResized();
|
||||
static pascal OSStatus ControlEventHandlerCallback(EventHandlerCallRef handler,
|
||||
EventRef event,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
private:
|
||||
AudioComponent mComponent;
|
||||
AudioUnit mUnit;
|
||||
|
||||
NSView *mAUView;
|
||||
NSView *mView;
|
||||
|
||||
wxSize mLastMin;
|
||||
bool mSettingSize;
|
||||
|
||||
#if !defined(_LP64)
|
||||
AudioComponentInstance mInstance;
|
||||
WindowRef mWindowRef;
|
||||
HIViewRef mHIView;
|
||||
#endif
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,658 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
VSTControl.mm
|
||||
|
||||
Leland Lucius
|
||||
|
||||
Several ideas and code snippets taken from HairerSoft's HSAUView class:
|
||||
|
||||
http://www.hairersoft.com/Downloads/HSAUView.zip
|
||||
|
||||
Created by Martin on 02/06/2007.
|
||||
Copyright 2010 by HairerSoft.
|
||||
|
||||
You are most welcome to use this code in your own (open source or not)
|
||||
project. Use at your own risk of course, etc. Please acknowledge at an
|
||||
appropriate location (manual or about box for example).
|
||||
|
||||
Bug reports most welcome: Martin@HairerSoft.com
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
#include <AudioUnit/AudioUnitProperties.h>
|
||||
#include <AudioUnit/AUCocoaUIView.h>
|
||||
#include <CoreAudioKit/CoreAudioKit.h>
|
||||
|
||||
#if !defined(_LP64)
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
#endif
|
||||
|
||||
#include "VSTControl.h"
|
||||
|
||||
@interface AUView : NSView
|
||||
{
|
||||
VSTControl *mControl;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AUView
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
static BOOL initialized = NO;
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = YES;
|
||||
wxOSXCocoaClassAddWXMethods(self);
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithControl:(VSTControl *)control
|
||||
{
|
||||
// Make sure a parameters were provided
|
||||
NSParameterAssert(control);
|
||||
|
||||
mControl = control;
|
||||
|
||||
[super init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)autoresizesSubviews
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)cocoaViewResized:(NSNotification *)notification
|
||||
{
|
||||
mControl->CocoaViewResized();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
VSTControlImpl::VSTControlImpl(wxWindowMac *peer, NSView *view)
|
||||
: wxWidgetCocoaImpl(peer, view, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
VSTControlImpl::~VSTControlImpl()
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(VSTControl, wxControl)
|
||||
EVT_SIZE(VSTControl::OnSize)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
VSTControl::VSTControl()
|
||||
{
|
||||
mComponent = NULL;
|
||||
mUnit = NULL;
|
||||
|
||||
mAUView = nil;
|
||||
mView = nil;
|
||||
|
||||
mSettingSize = false;
|
||||
|
||||
#if !defined(_LP64)
|
||||
mHIView = NULL;
|
||||
mWindowRef = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
VSTControl::~VSTControl()
|
||||
{
|
||||
#if !defined(_LP64)
|
||||
if (mHIView)
|
||||
{
|
||||
}
|
||||
|
||||
if (mInstance)
|
||||
{
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (mView)
|
||||
{
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center removeObserver:mAUView
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mView release];
|
||||
}
|
||||
|
||||
if (mAUView)
|
||||
{
|
||||
[mAUView release];
|
||||
}
|
||||
}
|
||||
|
||||
bool VSTControl::Create(wxWindow *parent, AudioComponent comp, AudioUnit unit, bool custom)
|
||||
{
|
||||
mComponent = comp;
|
||||
mUnit = unit;
|
||||
|
||||
DontCreatePeer();
|
||||
|
||||
if (!wxControl::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxEmptyString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mAUView = [AUView alloc];
|
||||
if (!mAUView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
[(AUView *)mAUView initWithControl:this];
|
||||
[mAUView retain];
|
||||
|
||||
if (custom)
|
||||
{
|
||||
CreateCocoa();
|
||||
|
||||
#if !defined(_LP64)
|
||||
if (!mView)
|
||||
{
|
||||
CreateCarbon();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!mView && !mHIView)
|
||||
{
|
||||
CreateGeneric();
|
||||
}
|
||||
|
||||
if (!mView && !mHIView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetPeer(new VSTControlImpl(this, mAUView));
|
||||
|
||||
if (mHIView)
|
||||
{
|
||||
CreateCarbonOverlay();
|
||||
}
|
||||
|
||||
// Must get the size again since SetPeer() could cause it to change
|
||||
SetInitialSize(GetMinSize());
|
||||
|
||||
MacPostControlCreate(wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VSTControl::OnSize(wxSizeEvent & evt)
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mSettingSize = true;
|
||||
|
||||
wxSize sz = GetSize();
|
||||
|
||||
if (mView)
|
||||
{
|
||||
int mask = [mView autoresizingMask];
|
||||
|
||||
NSRect viewFrame = [mAUView frame];
|
||||
NSRect viewRect = [mView frame];
|
||||
|
||||
if (mask & NSViewWidthSizable)
|
||||
{
|
||||
viewRect.size.width = sz.GetWidth();
|
||||
}
|
||||
|
||||
if (mask & NSViewHeightSizable)
|
||||
{
|
||||
viewRect.size.height = sz.GetHeight();
|
||||
}
|
||||
|
||||
viewRect.origin.x = (viewFrame.size.width - viewRect.size.width) / 2;
|
||||
viewRect.origin.y = (viewFrame.size.height - viewRect.size.height) / 2;
|
||||
|
||||
[mView setFrame:viewRect];
|
||||
}
|
||||
|
||||
#if !defined(_LP64)
|
||||
else if (mHIView)
|
||||
{
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
|
||||
CGFloat x = (sz.x - rect.size.width) / 2;
|
||||
CGFloat y = (sz.y - rect.size.height) / 2;
|
||||
|
||||
SizeWindow(mWindowRef, sz.x, sz.y, true);
|
||||
HIViewPlaceInSuperviewAt(mHIView, x, y);
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
|
||||
wxSize min = w->GetMinSize();
|
||||
min.x += (rect.size.width - mLastMin.GetWidth());
|
||||
min.y += (rect.size.height - mLastMin.GetHeight());
|
||||
w->SetMinSize(min);
|
||||
w->SetMaxSize(min);
|
||||
|
||||
mLastMin = wxSize(rect.size.width, rect.size.height);
|
||||
}
|
||||
#endif
|
||||
|
||||
mSettingSize = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VSTControl::CreateCocoa()
|
||||
{
|
||||
OSStatus result;
|
||||
UInt32 dataSize;
|
||||
|
||||
result = AudioUnitGetPropertyInfo(mUnit,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&dataSize,
|
||||
NULL);
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int cnt = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
|
||||
if (cnt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioUnitCocoaViewInfo *viewInfo = (AudioUnitCocoaViewInfo *) malloc(dataSize);
|
||||
if (viewInfo == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the view info
|
||||
result = AudioUnitGetProperty(mUnit,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
viewInfo,
|
||||
&dataSize);
|
||||
if (result == noErr)
|
||||
{
|
||||
// Looks like the AU has a Cocoa UI, so load the factory class
|
||||
NSURL *bundleLoc = (NSURL *) viewInfo->mCocoaAUViewBundleLocation;
|
||||
NSString *viewClass = (NSString *) viewInfo->mCocoaAUViewClass[0];
|
||||
|
||||
if (bundleLoc != nil && viewClass != nil)
|
||||
{
|
||||
// Load the bundle
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:[bundleLoc path]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
// Load the class from the bundle
|
||||
Class factoryClass = [bundle classNamed:viewClass];
|
||||
if (factoryClass != nil)
|
||||
{
|
||||
// Create an instance of the class
|
||||
id factoryInst = [[[factoryClass alloc] init] autorelease];
|
||||
if (factoryInst != nil)
|
||||
{
|
||||
// Suggest a reasonable size
|
||||
NSSize size = {800, 600};
|
||||
|
||||
// Create the view
|
||||
mView = [factoryInst uiViewForAudioUnit:mUnit withSize:size];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (viewInfo->mCocoaAUViewBundleLocation != nil)
|
||||
{
|
||||
CFRelease(viewInfo->mCocoaAUViewBundleLocation);
|
||||
}
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
CFRelease(viewInfo->mCocoaAUViewClass[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(viewInfo);
|
||||
|
||||
if (!mView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[mView retain];
|
||||
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:mAUView
|
||||
selector:@selector(cocoaViewResized:)
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mAUView addSubview:mView];
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);
|
||||
|
||||
SetMinSize(mLastMin);
|
||||
|
||||
[mAUView setAutoresizingMask:[mView autoresizingMask]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VSTControl::CreateGeneric()
|
||||
{
|
||||
OSStatus result;
|
||||
AudioComponentDescription desc;
|
||||
|
||||
result = AudioComponentGetDescription(mComponent, &desc);
|
||||
if (result == noErr && desc.componentType == kAudioUnitType_Panner)
|
||||
{
|
||||
mView = [AUPannerView AUPannerViewWithAudioUnit:mUnit];
|
||||
if (mView == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a generic AU view
|
||||
AUGenericView *view = [AUGenericView alloc];
|
||||
if (view == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = AUViewPropertiesDisplayFlag |
|
||||
AUViewParametersDisplayFlag;
|
||||
|
||||
[view initWithAudioUnit:mUnit displayFlags:flags];
|
||||
|
||||
[view setShowsExpertParameters:YES];
|
||||
|
||||
mView = view;
|
||||
}
|
||||
|
||||
[mView retain];
|
||||
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:mAUView
|
||||
selector:@selector(cocoaViewResized:)
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mAUView addSubview:mView];
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);
|
||||
|
||||
SetMinSize(mLastMin);
|
||||
|
||||
[mAUView setAutoresizingMask:[mView autoresizingMask]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VSTControl::CocoaViewResized()
|
||||
{
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
NSSize frameSize = [mAUView frame].size;
|
||||
|
||||
[mAUView setFrameSize:viewSize];
|
||||
|
||||
int diffW = (viewSize.width - frameSize.width);
|
||||
int diffH = (viewSize.height - frameSize.height);
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
|
||||
wxSize min = w->GetMinSize();
|
||||
if ([mView autoresizingMask] == NSViewNotSizable)
|
||||
{
|
||||
min.x += (viewSize.width - mLastMin.GetWidth());
|
||||
min.y += (viewSize.height - mLastMin.GetHeight());
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);;
|
||||
}
|
||||
else
|
||||
{
|
||||
min.x += diffW;
|
||||
min.y += diffH;
|
||||
}
|
||||
w->SetMinSize(min);
|
||||
|
||||
wxSize size = w->GetSize();
|
||||
size.x += diffW;
|
||||
size.y += diffH;
|
||||
w->SetSize(size);
|
||||
}
|
||||
|
||||
#if !defined(_LP64)
|
||||
|
||||
void VSTControl::CreateCarbon()
|
||||
{
|
||||
OSStatus result;
|
||||
UInt32 dataSize;
|
||||
|
||||
result = AudioUnitGetPropertyInfo(mUnit,
|
||||
kAudioUnitProperty_GetUIComponentList,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&dataSize,
|
||||
NULL);
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int cnt = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
|
||||
if (cnt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioComponentDescription *compList = (AudioComponentDescription *) malloc(dataSize);
|
||||
if (compList == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the view info
|
||||
result = AudioUnitGetProperty(mUnit,
|
||||
kAudioUnitProperty_GetUIComponentList,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
compList,
|
||||
&dataSize);
|
||||
if (result != noErr)
|
||||
{
|
||||
free(compList);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the component
|
||||
AudioComponent comp = AudioComponentFindNext(NULL, &compList[0]);
|
||||
|
||||
// Try to create an instance
|
||||
result = AudioComponentInstanceNew(comp, &mInstance);
|
||||
|
||||
// Done with the list
|
||||
free(compList);
|
||||
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect bounds = { 100, 100, 200, 200 };
|
||||
|
||||
result = CreateNewWindow(kOverlayWindowClass,
|
||||
kWindowStandardHandlerAttribute |
|
||||
kWindowCompositingAttribute |
|
||||
kWindowOpaqueForEventsAttribute,
|
||||
&bounds,
|
||||
&mWindowRef);
|
||||
if (result != noErr)
|
||||
{
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the root control
|
||||
ControlRef root = HIViewGetRoot(mWindowRef);
|
||||
|
||||
// Find the content view within our window
|
||||
HIViewRef content;
|
||||
result = HIViewFindByID(root, kHIViewWindowContentID, &content);
|
||||
if (result != noErr)
|
||||
{
|
||||
DisposeWindow(mWindowRef);
|
||||
mWindowRef = NULL;
|
||||
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
SetWindowActivationScope(mWindowRef, kWindowActivationScopeIndependent);
|
||||
|
||||
// Suggest a reasonable size
|
||||
Float32Point loc = {0.0, 0.0};
|
||||
Float32Point size = {800.0, 600.0};
|
||||
|
||||
// And create it
|
||||
result = AudioUnitCarbonViewCreate(mInstance,
|
||||
mUnit,
|
||||
mWindowRef,
|
||||
root,
|
||||
&loc,
|
||||
&size,
|
||||
&mHIView);
|
||||
if (result != noErr)
|
||||
{
|
||||
DisposeWindow(mWindowRef);
|
||||
mWindowRef = NULL;
|
||||
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HIViewAddSubview(root, mHIView);
|
||||
HIViewPlaceInSuperviewAt(mHIView, 0, 0);
|
||||
HIViewSetVisible(mHIView, TRUE);
|
||||
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
SetMinSize(wxSize(rect.size.width, rect.size.height));
|
||||
|
||||
mLastMin = GetMinSize();
|
||||
|
||||
EventTypeSpec controlEventList[] =
|
||||
{
|
||||
{kEventClassControl, kEventControlBoundsChanged},
|
||||
};
|
||||
|
||||
InstallControlEventHandler(mHIView,
|
||||
ControlEventHandlerCallback,
|
||||
GetEventTypeCount(controlEventList),
|
||||
controlEventList,
|
||||
(void *) this,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void VSTControl::CreateCarbonOverlay()
|
||||
{
|
||||
NSWindow *parent = [mAUView window];
|
||||
WindowRef parentRef = (WindowRef)[parent windowRef];
|
||||
|
||||
NSWindow *host = [[[NSWindow alloc] initWithWindowRef:mWindowRef] autorelease];
|
||||
[parent addChildWindow:host ordered:NSWindowAbove];
|
||||
|
||||
WindowGroupRef group;
|
||||
|
||||
CreateWindowGroup(0, &group);
|
||||
SetWindowGroupParent(group, GetWindowGroup(parentRef));
|
||||
ChangeWindowGroupAttributes(group,
|
||||
kWindowGroupAttrLayerTogether |
|
||||
kWindowGroupAttrSharedActivation |
|
||||
kWindowGroupAttrHideOnCollapse,
|
||||
0);
|
||||
SetWindowGroup(parentRef, group);
|
||||
SetWindowGroup(mWindowRef, group);
|
||||
|
||||
Rect location;
|
||||
GetWindowBounds(parentRef, kWindowContentRgn, &location);
|
||||
MoveWindow(mWindowRef, location.left, location.top, true);
|
||||
ShowWindow(mWindowRef);
|
||||
}
|
||||
|
||||
pascal OSStatus
|
||||
VSTControl::ControlEventHandlerCallback(EventHandlerCallRef handler, EventRef event, void *data)
|
||||
{
|
||||
((VSTControl *) data)->CarbonViewResized();
|
||||
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
|
||||
void VSTControl::CarbonViewResized()
|
||||
{
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// resize and move window
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
|
||||
HIViewPlaceInSuperviewAt(mHIView, 0, 0);
|
||||
SizeWindow(mWindowRef, rect.size.width, rect.size.height, true);
|
||||
|
||||
[mAUView setFrameSize:NSMakeSize(rect.size.width, rect.size.height)];
|
||||
|
||||
NSSize frameSize = [mAUView frame].size;
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
wxSize size = w->GetSize();
|
||||
size.x += (rect.size.width - frameSize.width);
|
||||
size.y += (rect.size.height - frameSize.height);
|
||||
|
||||
w->SetMinSize(wxDefaultSize);
|
||||
w->SetMaxSize(wxDefaultSize);
|
||||
w->SetSize(size);
|
||||
w->SetMinSize(size);
|
||||
w->SetMaxSize(size);
|
||||
mLastMin = size;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -19,6 +19,9 @@
|
|||
// WARNING: This is NOT 64-bit safe
|
||||
// *******************************************************************
|
||||
|
||||
#include "../../Audacity.h"
|
||||
|
||||
#if 0
|
||||
#if defined(BUILDING_AUDACITY)
|
||||
#include "../../Audacity.h"
|
||||
#include "../../PlatformCompatibility.h"
|
||||
|
@ -29,6 +32,7 @@
|
|||
#define MODULEMAIN_SCOPE
|
||||
#define USE_VST 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_VST
|
||||
|
||||
|
@ -66,7 +70,7 @@
|
|||
|
||||
#if defined(__WXMAC__)
|
||||
#include <dlfcn.h>
|
||||
#include <wx/mac/private.h>
|
||||
#include <wx/osx/core/private.h>
|
||||
#elif defined(__WXMSW__)
|
||||
#include <wx/dynlib.h>
|
||||
#include <wx/msw/seh.h>
|
||||
|
@ -117,14 +121,12 @@
|
|||
// declared static so as not to clash with other builtin modules.
|
||||
//
|
||||
// ============================================================================
|
||||
MODULEMAIN_SCOPE ModuleInterface *AudacityModule(ModuleManagerInterface *moduleManager,
|
||||
const wxString *path)
|
||||
DECLARE_MODULE_ENTRY(AudacityModule)
|
||||
{
|
||||
// Create our effects module and register
|
||||
return new VSTEffectsModule(moduleManager, path);
|
||||
}
|
||||
|
||||
#if defined(BUILDING_AUDACITY)
|
||||
// ============================================================================
|
||||
//
|
||||
// Register this as a builtin module
|
||||
|
@ -167,8 +169,6 @@ public:
|
|||
};
|
||||
IMPLEMENT_DYNAMIC_CLASS(VSTSubEntry, wxModule);
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// VSTSubProcess
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AUControl.h
|
||||
|
||||
Leland Lucius
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef AUDACITY_AUCONTROL_H
|
||||
#define AUDACITY_AUCONTROL_H
|
||||
|
||||
#if !defined(_LP64)
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
|
||||
#include <wx/osx/private.h>
|
||||
#include <wx/control.h>
|
||||
|
||||
//#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
//#include <AudioUnit/AudioUnitProperties.h>
|
||||
|
||||
class AUControlImpl : public wxWidgetCocoaImpl
|
||||
{
|
||||
public :
|
||||
AUControlImpl(wxWindowMac *peer, NSView *view);
|
||||
~AUControlImpl();
|
||||
};
|
||||
|
||||
class AUControl : public wxControl
|
||||
{
|
||||
public:
|
||||
AUControl();
|
||||
~AUControl();
|
||||
|
||||
bool Create(wxWindow *parent, AudioComponent comp, AudioUnit unit, bool custom);
|
||||
void CreateCocoa();
|
||||
void CreateGeneric();
|
||||
void CocoaViewResized();
|
||||
|
||||
void OnSize(wxSizeEvent & evt);
|
||||
|
||||
#if !defined(_LP64)
|
||||
void CreateCarbon();
|
||||
void CreateCarbonOverlay();
|
||||
void CarbonViewResized();
|
||||
static pascal OSStatus ControlEventHandlerCallback(EventHandlerCallRef handler,
|
||||
EventRef event,
|
||||
void *data);
|
||||
#endif
|
||||
|
||||
private:
|
||||
AudioComponent mComponent;
|
||||
AudioUnit mUnit;
|
||||
|
||||
NSView *mAUView;
|
||||
NSView *mView;
|
||||
|
||||
wxSize mLastMin;
|
||||
bool mSettingSize;
|
||||
|
||||
#if !defined(_LP64)
|
||||
AudioComponentInstance mInstance;
|
||||
WindowRef mWindowRef;
|
||||
HIViewRef mHIView;
|
||||
#endif
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,658 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AUControl.mm
|
||||
|
||||
Leland Lucius
|
||||
|
||||
Several ideas and code snippets taken from HairerSoft's HSAUView class:
|
||||
|
||||
http://www.hairersoft.com/Downloads/HSAUView.zip
|
||||
|
||||
Created by Martin on 02/06/2007.
|
||||
Copyright 2010 by HairerSoft.
|
||||
|
||||
You are most welcome to use this code in your own (open source or not)
|
||||
project. Use at your own risk of course, etc. Please acknowledge at an
|
||||
appropriate location (manual or about box for example).
|
||||
|
||||
Bug reports most welcome: Martin@HairerSoft.com
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioComponent.h>
|
||||
#include <AudioUnit/AudioUnitProperties.h>
|
||||
#include <AudioUnit/AUCocoaUIView.h>
|
||||
#include <CoreAudioKit/CoreAudioKit.h>
|
||||
|
||||
#if !defined(_LP64)
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
#endif
|
||||
|
||||
#include "AUControl.h"
|
||||
|
||||
@interface AUView : NSView
|
||||
{
|
||||
AUControl *mControl;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AUView
|
||||
|
||||
+ (void)initialize
|
||||
{
|
||||
static BOOL initialized = NO;
|
||||
if (!initialized)
|
||||
{
|
||||
initialized = YES;
|
||||
wxOSXCocoaClassAddWXMethods(self);
|
||||
}
|
||||
}
|
||||
|
||||
- (instancetype)initWithControl:(AUControl *)control
|
||||
{
|
||||
// Make sure a parameters were provided
|
||||
NSParameterAssert(control);
|
||||
|
||||
mControl = control;
|
||||
|
||||
[super init];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)autoresizesSubviews
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)cocoaViewResized:(NSNotification *)notification
|
||||
{
|
||||
mControl->CocoaViewResized();
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
AUControlImpl::AUControlImpl(wxWindowMac *peer, NSView *view)
|
||||
: wxWidgetCocoaImpl(peer, view, false, false)
|
||||
{
|
||||
}
|
||||
|
||||
AUControlImpl::~AUControlImpl()
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(AUControl, wxControl)
|
||||
EVT_SIZE(AUControl::OnSize)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
AUControl::AUControl()
|
||||
{
|
||||
mComponent = NULL;
|
||||
mUnit = NULL;
|
||||
|
||||
mAUView = nil;
|
||||
mView = nil;
|
||||
|
||||
mSettingSize = false;
|
||||
|
||||
#if !defined(_LP64)
|
||||
mHIView = NULL;
|
||||
mWindowRef = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
AUControl::~AUControl()
|
||||
{
|
||||
#if !defined(_LP64)
|
||||
if (mHIView)
|
||||
{
|
||||
}
|
||||
|
||||
if (mInstance)
|
||||
{
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (mView)
|
||||
{
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center removeObserver:mAUView
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mView release];
|
||||
}
|
||||
|
||||
if (mAUView)
|
||||
{
|
||||
[mAUView release];
|
||||
}
|
||||
}
|
||||
|
||||
bool AUControl::Create(wxWindow *parent, AudioComponent comp, AudioUnit unit, bool custom)
|
||||
{
|
||||
mComponent = comp;
|
||||
mUnit = unit;
|
||||
|
||||
DontCreatePeer();
|
||||
|
||||
if (!wxControl::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, wxEmptyString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mAUView = [AUView alloc];
|
||||
if (!mAUView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
[(AUView *)mAUView initWithControl:this];
|
||||
[mAUView retain];
|
||||
|
||||
if (custom)
|
||||
{
|
||||
CreateCocoa();
|
||||
|
||||
#if !defined(_LP64)
|
||||
if (!mView)
|
||||
{
|
||||
CreateCarbon();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!mView && !mHIView)
|
||||
{
|
||||
CreateGeneric();
|
||||
}
|
||||
|
||||
if (!mView && !mHIView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetPeer(new AUControlImpl(this, mAUView));
|
||||
|
||||
if (mHIView)
|
||||
{
|
||||
CreateCarbonOverlay();
|
||||
}
|
||||
|
||||
// Must get the size again since SetPeer() could cause it to change
|
||||
SetInitialSize(GetMinSize());
|
||||
|
||||
MacPostControlCreate(wxDefaultPosition, wxDefaultSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AUControl::OnSize(wxSizeEvent & evt)
|
||||
{
|
||||
evt.Skip();
|
||||
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mSettingSize = true;
|
||||
|
||||
wxSize sz = GetSize();
|
||||
|
||||
if (mView)
|
||||
{
|
||||
int mask = [mView autoresizingMask];
|
||||
|
||||
NSRect viewFrame = [mAUView frame];
|
||||
NSRect viewRect = [mView frame];
|
||||
|
||||
if (mask & NSViewWidthSizable)
|
||||
{
|
||||
viewRect.size.width = sz.GetWidth();
|
||||
}
|
||||
|
||||
if (mask & NSViewHeightSizable)
|
||||
{
|
||||
viewRect.size.height = sz.GetHeight();
|
||||
}
|
||||
|
||||
viewRect.origin.x = (viewFrame.size.width - viewRect.size.width) / 2;
|
||||
viewRect.origin.y = (viewFrame.size.height - viewRect.size.height) / 2;
|
||||
|
||||
[mView setFrame:viewRect];
|
||||
}
|
||||
|
||||
#if !defined(_LP64)
|
||||
else if (mHIView)
|
||||
{
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
|
||||
CGFloat x = (sz.x - rect.size.width) / 2;
|
||||
CGFloat y = (sz.y - rect.size.height) / 2;
|
||||
|
||||
SizeWindow(mWindowRef, sz.x, sz.y, true);
|
||||
HIViewPlaceInSuperviewAt(mHIView, x, y);
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
|
||||
wxSize min = w->GetMinSize();
|
||||
min.x += (rect.size.width - mLastMin.GetWidth());
|
||||
min.y += (rect.size.height - mLastMin.GetHeight());
|
||||
w->SetMinSize(min);
|
||||
w->SetMaxSize(min);
|
||||
|
||||
mLastMin = wxSize(rect.size.width, rect.size.height);
|
||||
}
|
||||
#endif
|
||||
|
||||
mSettingSize = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AUControl::CreateCocoa()
|
||||
{
|
||||
OSStatus result;
|
||||
UInt32 dataSize;
|
||||
|
||||
result = AudioUnitGetPropertyInfo(mUnit,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&dataSize,
|
||||
NULL);
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int cnt = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
|
||||
if (cnt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioUnitCocoaViewInfo *viewInfo = (AudioUnitCocoaViewInfo *) malloc(dataSize);
|
||||
if (viewInfo == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the view info
|
||||
result = AudioUnitGetProperty(mUnit,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
viewInfo,
|
||||
&dataSize);
|
||||
if (result == noErr)
|
||||
{
|
||||
// Looks like the AU has a Cocoa UI, so load the factory class
|
||||
NSURL *bundleLoc = (NSURL *) viewInfo->mCocoaAUViewBundleLocation;
|
||||
NSString *viewClass = (NSString *) viewInfo->mCocoaAUViewClass[0];
|
||||
|
||||
if (bundleLoc != nil && viewClass != nil)
|
||||
{
|
||||
// Load the bundle
|
||||
NSBundle *bundle = [NSBundle bundleWithPath:[bundleLoc path]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
// Load the class from the bundle
|
||||
Class factoryClass = [bundle classNamed:viewClass];
|
||||
if (factoryClass != nil)
|
||||
{
|
||||
// Create an instance of the class
|
||||
id factoryInst = [[[factoryClass alloc] init] autorelease];
|
||||
if (factoryInst != nil)
|
||||
{
|
||||
// Suggest a reasonable size
|
||||
NSSize size = {800, 600};
|
||||
|
||||
// Create the view
|
||||
mView = [factoryInst uiViewForAudioUnit:mUnit withSize:size];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (viewInfo->mCocoaAUViewBundleLocation != nil)
|
||||
{
|
||||
CFRelease(viewInfo->mCocoaAUViewBundleLocation);
|
||||
}
|
||||
|
||||
for (int i = 0; i < cnt; i++)
|
||||
{
|
||||
CFRelease(viewInfo->mCocoaAUViewClass[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(viewInfo);
|
||||
|
||||
if (!mView)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[mView retain];
|
||||
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:mAUView
|
||||
selector:@selector(cocoaViewResized:)
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mAUView addSubview:mView];
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);
|
||||
|
||||
SetMinSize(mLastMin);
|
||||
|
||||
[mAUView setAutoresizingMask:[mView autoresizingMask]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AUControl::CreateGeneric()
|
||||
{
|
||||
OSStatus result;
|
||||
AudioComponentDescription desc;
|
||||
|
||||
result = AudioComponentGetDescription(mComponent, &desc);
|
||||
if (result == noErr && desc.componentType == kAudioUnitType_Panner)
|
||||
{
|
||||
mView = [AUPannerView AUPannerViewWithAudioUnit:mUnit];
|
||||
if (mView == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Create a generic AU view
|
||||
AUGenericView *view = [AUGenericView alloc];
|
||||
if (view == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int flags = AUViewPropertiesDisplayFlag |
|
||||
AUViewParametersDisplayFlag;
|
||||
|
||||
[view initWithAudioUnit:mUnit displayFlags:flags];
|
||||
|
||||
[view setShowsExpertParameters:YES];
|
||||
|
||||
mView = view;
|
||||
}
|
||||
|
||||
[mView retain];
|
||||
|
||||
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:mAUView
|
||||
selector:@selector(cocoaViewResized:)
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:mView];
|
||||
|
||||
[mAUView addSubview:mView];
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);
|
||||
|
||||
SetMinSize(mLastMin);
|
||||
|
||||
[mAUView setAutoresizingMask:[mView autoresizingMask]];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AUControl::CocoaViewResized()
|
||||
{
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSSize viewSize = [mView frame].size;
|
||||
NSSize frameSize = [mAUView frame].size;
|
||||
|
||||
[mAUView setFrameSize:viewSize];
|
||||
|
||||
int diffW = (viewSize.width - frameSize.width);
|
||||
int diffH = (viewSize.height - frameSize.height);
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
|
||||
wxSize min = w->GetMinSize();
|
||||
if ([mView autoresizingMask] == NSViewNotSizable)
|
||||
{
|
||||
min.x += (viewSize.width - mLastMin.GetWidth());
|
||||
min.y += (viewSize.height - mLastMin.GetHeight());
|
||||
mLastMin = wxSize(viewSize.width, viewSize.height);;
|
||||
}
|
||||
else
|
||||
{
|
||||
min.x += diffW;
|
||||
min.y += diffH;
|
||||
}
|
||||
w->SetMinSize(min);
|
||||
|
||||
wxSize size = w->GetSize();
|
||||
size.x += diffW;
|
||||
size.y += diffH;
|
||||
w->SetSize(size);
|
||||
}
|
||||
|
||||
#if !defined(_LP64)
|
||||
|
||||
void AUControl::CreateCarbon()
|
||||
{
|
||||
OSStatus result;
|
||||
UInt32 dataSize;
|
||||
|
||||
result = AudioUnitGetPropertyInfo(mUnit,
|
||||
kAudioUnitProperty_GetUIComponentList,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&dataSize,
|
||||
NULL);
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int cnt = (dataSize - sizeof(CFURLRef)) / sizeof(CFStringRef);
|
||||
if (cnt == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioComponentDescription *compList = (AudioComponentDescription *) malloc(dataSize);
|
||||
if (compList == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the view info
|
||||
result = AudioUnitGetProperty(mUnit,
|
||||
kAudioUnitProperty_GetUIComponentList,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
compList,
|
||||
&dataSize);
|
||||
if (result != noErr)
|
||||
{
|
||||
free(compList);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the component
|
||||
AudioComponent comp = AudioComponentFindNext(NULL, &compList[0]);
|
||||
|
||||
// Try to create an instance
|
||||
result = AudioComponentInstanceNew(comp, &mInstance);
|
||||
|
||||
// Done with the list
|
||||
free(compList);
|
||||
|
||||
if (result != noErr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect bounds = { 100, 100, 200, 200 };
|
||||
|
||||
result = CreateNewWindow(kOverlayWindowClass,
|
||||
kWindowStandardHandlerAttribute |
|
||||
kWindowCompositingAttribute |
|
||||
kWindowOpaqueForEventsAttribute,
|
||||
&bounds,
|
||||
&mWindowRef);
|
||||
if (result != noErr)
|
||||
{
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the root control
|
||||
ControlRef root = HIViewGetRoot(mWindowRef);
|
||||
|
||||
// Find the content view within our window
|
||||
HIViewRef content;
|
||||
result = HIViewFindByID(root, kHIViewWindowContentID, &content);
|
||||
if (result != noErr)
|
||||
{
|
||||
DisposeWindow(mWindowRef);
|
||||
mWindowRef = NULL;
|
||||
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
SetWindowActivationScope(mWindowRef, kWindowActivationScopeIndependent);
|
||||
|
||||
// Suggest a reasonable size
|
||||
Float32Point loc = {0.0, 0.0};
|
||||
Float32Point size = {800.0, 600.0};
|
||||
|
||||
// And create it
|
||||
result = AudioUnitCarbonViewCreate(mInstance,
|
||||
mUnit,
|
||||
mWindowRef,
|
||||
root,
|
||||
&loc,
|
||||
&size,
|
||||
&mHIView);
|
||||
if (result != noErr)
|
||||
{
|
||||
DisposeWindow(mWindowRef);
|
||||
mWindowRef = NULL;
|
||||
|
||||
AudioComponentInstanceDispose(mInstance);
|
||||
mInstance = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
HIViewAddSubview(root, mHIView);
|
||||
HIViewPlaceInSuperviewAt(mHIView, 0, 0);
|
||||
HIViewSetVisible(mHIView, TRUE);
|
||||
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
SetMinSize(wxSize(rect.size.width, rect.size.height));
|
||||
|
||||
mLastMin = GetMinSize();
|
||||
|
||||
EventTypeSpec controlEventList[] =
|
||||
{
|
||||
{kEventClassControl, kEventControlBoundsChanged},
|
||||
};
|
||||
|
||||
InstallControlEventHandler(mHIView,
|
||||
ControlEventHandlerCallback,
|
||||
GetEventTypeCount(controlEventList),
|
||||
controlEventList,
|
||||
(void *) this,
|
||||
NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AUControl::CreateCarbonOverlay()
|
||||
{
|
||||
NSWindow *parent = [mAUView window];
|
||||
WindowRef parentRef = (WindowRef)[parent windowRef];
|
||||
|
||||
NSWindow *host = [[[NSWindow alloc] initWithWindowRef:mWindowRef] autorelease];
|
||||
[parent addChildWindow:host ordered:NSWindowAbove];
|
||||
|
||||
WindowGroupRef group;
|
||||
|
||||
CreateWindowGroup(0, &group);
|
||||
SetWindowGroupParent(group, GetWindowGroup(parentRef));
|
||||
ChangeWindowGroupAttributes(group,
|
||||
kWindowGroupAttrLayerTogether |
|
||||
kWindowGroupAttrSharedActivation |
|
||||
kWindowGroupAttrHideOnCollapse,
|
||||
0);
|
||||
SetWindowGroup(parentRef, group);
|
||||
SetWindowGroup(mWindowRef, group);
|
||||
|
||||
Rect location;
|
||||
GetWindowBounds(parentRef, kWindowContentRgn, &location);
|
||||
MoveWindow(mWindowRef, location.left, location.top, true);
|
||||
ShowWindow(mWindowRef);
|
||||
}
|
||||
|
||||
pascal OSStatus
|
||||
AUControl::ControlEventHandlerCallback(EventHandlerCallRef handler, EventRef event, void *data)
|
||||
{
|
||||
((AUControl *) data)->CarbonViewResized();
|
||||
|
||||
return eventNotHandledErr;
|
||||
}
|
||||
|
||||
void AUControl::CarbonViewResized()
|
||||
{
|
||||
if (mSettingSize)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// resize and move window
|
||||
HIRect rect;
|
||||
HIViewGetFrame(mHIView, &rect);
|
||||
|
||||
HIViewPlaceInSuperviewAt(mHIView, 0, 0);
|
||||
SizeWindow(mWindowRef, rect.size.width, rect.size.height, true);
|
||||
|
||||
[mAUView setFrameSize:NSMakeSize(rect.size.width, rect.size.height)];
|
||||
|
||||
NSSize frameSize = [mAUView frame].size;
|
||||
|
||||
wxWindow *w = wxGetTopLevelParent(this);
|
||||
wxSize size = w->GetSize();
|
||||
size.x += (rect.size.width - frameSize.width);
|
||||
size.y += (rect.size.height - frameSize.height);
|
||||
|
||||
w->SetMinSize(wxDefaultSize);
|
||||
w->SetMaxSize(wxDefaultSize);
|
||||
w->SetSize(size);
|
||||
w->SetMinSize(size);
|
||||
w->SetMaxSize(size);
|
||||
mLastMin = size;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,29 +0,0 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AudioUnitCocoaHelper.h
|
||||
|
||||
Leland Lucius
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef AUDACITY_AUDIOUNIT_COCOA_HELPER_H
|
||||
#define AUDACITY_AUDIOUNIT_COCOA_HELPER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
|
||||
HIViewRef createGeneric(AudioUnit unit);
|
||||
HIViewRef createPanner(AudioUnit unit);
|
||||
HIViewRef createCocoa(AudioUnit unit);
|
||||
HIViewRef createCarbon(AudioUnit unit, WindowRef window, AudioUnitCarbonView *carbonView);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,350 +0,0 @@
|
|||
/**********************************************************************
|
||||
|
||||
Audacity: A Digital Audio Editor
|
||||
|
||||
AudioUnitCocoaHelper.m
|
||||
|
||||
Leland Lucius
|
||||
|
||||
*******************************************************************//**
|
||||
|
||||
\class AUScrollView
|
||||
\brief An NSScrollView subclass that hosts AUs
|
||||
|
||||
NOTE: I do NOT to Objective-C(++), so if you see ANYTHING wrong do
|
||||
not hesitate to let me know. -Leland
|
||||
|
||||
*//*******************************************************************/
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <AudioUnit/AudioUnit.h>
|
||||
#import <AudioUnit/AUCocoaUIView.h>
|
||||
#import <CoreAudioKit/CoreAudioKit.h>
|
||||
#import <AppKit/NSScrollView.h>
|
||||
|
||||
#import "AudioUnitCocoaHelper.h"
|
||||
|
||||
@interface AUScrollView: NSScrollView
|
||||
{
|
||||
NSView *auView;
|
||||
HIViewRef hiViewRef;
|
||||
}
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect;
|
||||
|
||||
/* Might be useful for improved resizing
|
||||
- (void)auResized:(NSNotification *)notification;
|
||||
- (void)myResized:(NSNotification *)notification;
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
@implementation AUScrollView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
self = [super initWithFrame:frameRect];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)reflectScrolledClipView:(NSClipView *)aClipView
|
||||
{
|
||||
[super reflectScrolledClipView:aClipView];
|
||||
|
||||
// Force a full refresh as some effects seem to need it
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (BOOL)autoresizesSubviews
|
||||
{
|
||||
// Let NSView automatically resize our children
|
||||
return YES;
|
||||
}
|
||||
@end
|
||||
|
||||
/* Might be useful for improved resizing. I'd worked up this
|
||||
really elaborate resizing stuff that "almost" worked. Rather
|
||||
than spend even more time, I decided to get rid of it all and
|
||||
let resizing happen as it will. This code should be short
|
||||
lived anyway as it will probably not be needed once we convert
|
||||
to wxWidgets 3+.
|
||||
|
||||
-(void) setViews:(NSView *)aView hiViewRef:(HIViewRef)hView
|
||||
{
|
||||
auView = aView;
|
||||
hiViewRef = hView;
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(myResized:) name:NSViewFrameDidChangeNotification object:self];
|
||||
|
||||
[[NSNotificationCenter defaultCenter]
|
||||
addObserver:self
|
||||
selector:@selector(auResized:) name:NSViewFrameDidChangeNotification object:auView];
|
||||
|
||||
}
|
||||
|
||||
- (void)myResized:(NSNotification *)notification
|
||||
{
|
||||
}
|
||||
|
||||
- (void)auResized:(NSNotification *)notification
|
||||
{
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Create a Cocoa based generic AU view wrapped in a Carbon view
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
HIViewRef createGeneric(AudioUnit unit)
|
||||
{
|
||||
HIViewRef hiView = NULL;
|
||||
OSStatus result;
|
||||
|
||||
// Create a generic AU view
|
||||
NSView *auView = [[[AUGenericView alloc] initWithAudioUnit: unit] retain];
|
||||
if (auView != nil)
|
||||
{
|
||||
// Allow expert parameters to be used
|
||||
[(AUGenericView *) auView setShowsExpertParameters:YES];
|
||||
|
||||
// Get the AU view's frame for later
|
||||
NSRect viewFrame = [auView frame];
|
||||
|
||||
// Create the view that will host the AU view
|
||||
AUScrollView *scrollView =
|
||||
[[[AUScrollView alloc] initWithFrame:viewFrame] autorelease];
|
||||
|
||||
// Not sure if this is necessary, but crashes seemed to occur
|
||||
// without it.
|
||||
[scrollView retain];
|
||||
|
||||
// Set the scroller options
|
||||
[scrollView setDrawsBackground:YES];
|
||||
[scrollView setAutohidesScrollers:YES];
|
||||
[scrollView setHasHorizontalScroller:YES];
|
||||
[scrollView setHasVerticalScroller:YES];
|
||||
[scrollView setBorderType:NSNoBorder];
|
||||
[scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
|
||||
|
||||
// Let the scrollview know about the AU view
|
||||
//
|
||||
// Should the AU view be released after this???
|
||||
[scrollView setDocumentView:auView];
|
||||
// [auView release];
|
||||
|
||||
// Carbonize it
|
||||
result = HICocoaViewCreate(scrollView, 0, &hiView);
|
||||
if (result == noErr)
|
||||
{
|
||||
// Resize the HIView to match the AU view
|
||||
SizeControl(hiView, viewFrame.size.width, viewFrame.size.height);
|
||||
}
|
||||
}
|
||||
|
||||
return hiView;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Create a Cocoa based generic panner AU view wrapped in a Carbon view
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
HIViewRef createPanner(AudioUnit unit)
|
||||
{
|
||||
HIViewRef hiView = NULL;
|
||||
OSStatus result;
|
||||
|
||||
// Create a generic AU view
|
||||
NSView *auView = [[AUPannerView AUPannerViewWithAudioUnit:unit] retain];
|
||||
if (auView != nil)
|
||||
{
|
||||
// Get the AU view's frame for later
|
||||
NSRect viewFrame = [auView frame];
|
||||
|
||||
// Create the view that will host the AU view
|
||||
AUScrollView *scrollView =
|
||||
[[[AUScrollView alloc] initWithFrame:viewFrame] autorelease];
|
||||
|
||||
// Not sure if this is necessary, but crashes seemed to occur
|
||||
// without it.
|
||||
[scrollView retain];
|
||||
|
||||
// Set the scroller options
|
||||
[scrollView setDrawsBackground:YES];
|
||||
[scrollView setAutohidesScrollers:YES];
|
||||
[scrollView setHasHorizontalScroller:YES];
|
||||
[scrollView setHasVerticalScroller:YES];
|
||||
[scrollView setBorderType:NSNoBorder];
|
||||
[scrollView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
|
||||
|
||||
// Let the scrollview know about the AU view
|
||||
//
|
||||
// Should the AU view be released after this???
|
||||
[scrollView setDocumentView:auView];
|
||||
// [auView release];
|
||||
|
||||
// Carbonize it
|
||||
result = HICocoaViewCreate(scrollView, 0, &hiView);
|
||||
if (result == noErr)
|
||||
{
|
||||
// Resize the HIView to match the AU view
|
||||
SizeControl(hiView, viewFrame.size.width, viewFrame.size.height);
|
||||
}
|
||||
}
|
||||
|
||||
return hiView;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Create a Cocoa based custom AU view wrapped in a Carbon view
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
HIViewRef createCocoa(AudioUnit unit)
|
||||
{
|
||||
HIViewRef hiView = NULL;
|
||||
OSStatus result;
|
||||
|
||||
AudioUnitCocoaViewInfo cocoaViewInfo;
|
||||
UInt32 dataSize = sizeof(AudioUnitCocoaViewInfo);
|
||||
|
||||
// Get info about first Cocoa view
|
||||
result = AudioUnitGetProperty(unit,
|
||||
kAudioUnitProperty_CocoaUI,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&cocoaViewInfo,
|
||||
&dataSize);
|
||||
if (result != noErr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Looks like the AU has a Cocoa UI, so load the factory class
|
||||
NSURL *bundleLoc = (NSURL *) cocoaViewInfo.mCocoaAUViewBundleLocation;
|
||||
NSString *className = (NSString *) cocoaViewInfo.mCocoaAUViewClass[0];
|
||||
if (!bundleLoc || !className)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Load the bundle
|
||||
NSBundle *bundle = [NSBundle bundleWithPath: [bundleLoc path]];
|
||||
if (bundle != nil)
|
||||
{
|
||||
// Load the class from the bundle
|
||||
Class factoryClass = [bundle classNamed: className];
|
||||
if (factoryClass != nil)
|
||||
{
|
||||
// Create an instance of the class
|
||||
id factoryInst = [[[factoryClass alloc] init] autorelease];
|
||||
if (factoryInst != nil)
|
||||
{
|
||||
// Suggest a resonable size
|
||||
NSSize size = {800, 600};
|
||||
|
||||
// Create the view
|
||||
NSView *auView = [[factoryInst uiViewForAudioUnit: unit withSize: size] retain];
|
||||
if (auView != nil)
|
||||
{
|
||||
// Get the AU views frame for later
|
||||
NSRect viewFrame = [auView frame];
|
||||
|
||||
// Create the view that will host the AU view
|
||||
AUScrollView *scrollView =
|
||||
[[[AUScrollView alloc] initWithFrame:viewFrame] autorelease];
|
||||
|
||||
// Not sure if this is necessary, but crashes seemed to occur
|
||||
// without it.
|
||||
[scrollView retain];
|
||||
|
||||
// Set the scroller options
|
||||
[scrollView setDrawsBackground:YES];
|
||||
[scrollView setAutohidesScrollers:YES];
|
||||
[scrollView setHasHorizontalScroller:YES];
|
||||
[scrollView setHasVerticalScroller:YES];
|
||||
[scrollView setBorderType:NSNoBorder];
|
||||
|
||||
// Let the scrollview know about the AU view
|
||||
//
|
||||
// Should the AU view be released after this???
|
||||
[scrollView setDocumentView:auView];
|
||||
|
||||
// Carbonize it
|
||||
result = HICocoaViewCreate(scrollView, 0, &hiView);
|
||||
if (result == noErr)
|
||||
{
|
||||
// Resize the HIView to match the AU view
|
||||
SizeControl(hiView, viewFrame.size.width, viewFrame.size.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release the bundle???
|
||||
// [bundle release];
|
||||
}
|
||||
|
||||
// Release the bundle path
|
||||
[bundleLoc release];
|
||||
|
||||
return hiView;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Create a Carbon based AU view
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
HIViewRef createCarbon(AudioUnit unit, WindowRef window, AudioUnitCarbonView *carbonView)
|
||||
{
|
||||
HIViewRef hiView = NULL;
|
||||
OSStatus result;
|
||||
|
||||
// Retrieve the view component description
|
||||
ComponentDescription compDesc;
|
||||
UInt32 dataSize = sizeof(compDesc);
|
||||
result = AudioUnitGetProperty(unit,
|
||||
kAudioUnitProperty_GetUIComponentList,
|
||||
kAudioUnitScope_Global,
|
||||
0,
|
||||
&compDesc,
|
||||
&dataSize);
|
||||
if (result != noErr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Try to open it
|
||||
Component comp = FindNextComponent(NULL, &compDesc);
|
||||
result = OpenAComponent(comp, carbonView);
|
||||
if (result != noErr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the root control
|
||||
ControlRef root = HIViewGetRoot(window);
|
||||
GetRootControl(window, &root);
|
||||
|
||||
// Find the content view within our window
|
||||
HIViewRef content;
|
||||
result = HIViewFindByID(root, kHIViewWindowContentID, &content);
|
||||
if (result != noErr)
|
||||
{
|
||||
CloseComponent(*carbonView);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Suggest a reasonable size
|
||||
Float32Point loc = {0.0, 0.0};
|
||||
Float32Point size = {800.0, 600.0};
|
||||
|
||||
// And create it
|
||||
result = AudioUnitCarbonViewCreate(*carbonView,
|
||||
unit,
|
||||
window,
|
||||
root,
|
||||
&loc,
|
||||
&size,
|
||||
&hiView);
|
||||
|
||||
return hiView;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -8,22 +8,24 @@
|
|||
Leland Lucius
|
||||
|
||||
**********************************************************************/
|
||||
#ifndef AUDACITY_AUDIOUNIT_EFFECT_H
|
||||
|
||||
#include "../../Audacity.h"
|
||||
|
||||
#if USE_AUDIO_UNITS
|
||||
|
||||
#include <wx/dialog.h>
|
||||
|
||||
#include "../Effect.h"
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#include <Carbon/Carbon.h>
|
||||
#include <AudioUnit/AudioUnitProperties.h>
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
#include <AudioToolbox/AudioUnitUtilities.h>
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioUnit/AudioUnitProperties.h>
|
||||
|
||||
#include "audacity/EffectInterface.h"
|
||||
#include "audacity/ModuleInterface.h"
|
||||
#include "audacity/PluginInterface.h"
|
||||
|
||||
#include "AUControl.h"
|
||||
|
||||
#define AUDIOUNITEFFECTS_VERSION wxT("1.0.0.0")
|
||||
#define AUDIOUNITEFFECTS_FAMILY wxT("AudioUnit")
|
||||
|
||||
|
@ -41,7 +43,7 @@ class AudioUnitEffect : public wxEvtHandler,
|
|||
public:
|
||||
AudioUnitEffect(const wxString & path,
|
||||
const wxString & name,
|
||||
Component component,
|
||||
AudioComponent component,
|
||||
AudioUnitEffect *master = NULL);
|
||||
virtual ~AudioUnitEffect();
|
||||
|
||||
|
@ -156,53 +158,39 @@ private:
|
|||
void EventListener(const AudioUnitEvent *inEvent,
|
||||
AudioUnitParameterValue inParameterValue);
|
||||
|
||||
static pascal OSStatus WindowEventHandlerCallback(EventHandlerCallRef handler,
|
||||
EventRef event,
|
||||
void *data);
|
||||
OSStatus WindowEventHandler(EventRef event);
|
||||
|
||||
static pascal OSStatus ControlEventHandlerCallback(EventHandlerCallRef handler,
|
||||
EventRef event,
|
||||
void *data);
|
||||
OSStatus ControlEventHandler(EventRef event);
|
||||
|
||||
static pascal OSStatus TrackingEventHandler(EventHandlerCallRef handler,
|
||||
EventRef event,
|
||||
void *data);
|
||||
OSStatus OnTrackingEvent(EventRef event);
|
||||
|
||||
void RemoveHandler();
|
||||
|
||||
void GetChannelCounts();
|
||||
|
||||
bool LoadParameters(const wxString & group);
|
||||
bool SaveParameters(const wxString & group);
|
||||
|
||||
void OnSize(wxSizeEvent & evt);
|
||||
|
||||
bool CreatePlain(wxWindow *parent);
|
||||
|
||||
private:
|
||||
|
||||
wxString mPath;
|
||||
wxString mName;
|
||||
wxString mVendor;
|
||||
Component mComponent;
|
||||
AudioUnit mUnit;
|
||||
bool mSupportsMono;
|
||||
bool mSupportsStereo;
|
||||
wxString mPath;
|
||||
wxString mName;
|
||||
wxString mVendor;
|
||||
AudioComponent mComponent;
|
||||
AudioUnit mUnit;
|
||||
bool mUnitInitialized;
|
||||
|
||||
bool mSupportsMono;
|
||||
bool mSupportsStereo;
|
||||
|
||||
EffectHostInterface *mHost;
|
||||
int mAudioIns;
|
||||
int mAudioOuts;
|
||||
bool mInteractive;
|
||||
bool mLatencyDone;
|
||||
UInt32 mBlockSize;
|
||||
double mSampleRate;
|
||||
int mAudioIns;
|
||||
int mAudioOuts;
|
||||
bool mInteractive;
|
||||
bool mLatencyDone;
|
||||
UInt32 mBlockSize;
|
||||
double mSampleRate;
|
||||
|
||||
int mBufferSize;
|
||||
bool mUseLatency;
|
||||
int mBufferSize;
|
||||
bool mUseLatency;
|
||||
|
||||
AudioTimeStamp mTimeStamp;
|
||||
bool mReady;
|
||||
bool mReady;
|
||||
|
||||
AudioBufferList *mInputList;
|
||||
AudioBufferList *mOutputList;
|
||||
|
@ -210,14 +198,9 @@ private:
|
|||
EffectUIHostInterface *mUIHost;
|
||||
wxWindow *mParent;
|
||||
wxDialog *mDialog;
|
||||
wxSizerItem *mContainer;
|
||||
AudioUnitCarbonView mCarbonView;
|
||||
bool mUseGUI;
|
||||
HIViewRef mAUView;
|
||||
EventTargetRef mEventRef;
|
||||
bool mIsCocoa;
|
||||
bool mIsCarbon;
|
||||
bool mIsGeneric;
|
||||
AUControl *mControl;
|
||||
wxString mUIType;
|
||||
bool mIsGraphical;
|
||||
|
||||
AudioUnitEffect *mMaster; // non-NULL if a slave
|
||||
AudioUnitEffectArray mSlaves;
|
||||
|
@ -228,18 +211,6 @@ private:
|
|||
|
||||
AUEventListenerRef mEventListenerRef;
|
||||
|
||||
EventHandlerRef mHandlerRef;
|
||||
EventHandlerUPP mHandlerUPP;
|
||||
EventHandlerRef mControlHandlerRef;
|
||||
EventHandlerUPP mControlHandlerUPP;
|
||||
|
||||
EventHandlerUPP mTrackingHandlerUPP;
|
||||
EventHandlerRef mRootTrackingHandlerRef;
|
||||
EventHandlerRef mContentTrackingHandlerRef;
|
||||
EventHandlerRef mAUTrackingHandlerRef;
|
||||
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
friend class AudioUnitEffectExportDialog;
|
||||
friend class AudioUnitEffectImportDialog;
|
||||
};
|
||||
|
@ -282,7 +253,7 @@ public:
|
|||
// AudioUnitEffectModule implementation
|
||||
|
||||
void LoadAudioUnitsOfType(OSType inAUType, wxArrayString & effects);
|
||||
Component FindAudioUnit(const wxString & path, wxString & name);
|
||||
AudioComponent FindAudioUnit(const wxString & path, wxString & name);
|
||||
|
||||
wxString FromOSType(OSType type);
|
||||
OSType ToOSType(const wxString & type);
|
||||
|
@ -292,3 +263,6 @@ private:
|
|||
wxString mPath;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1671,8 +1671,8 @@ bool LV2Effect::BuildPlain()
|
|||
}
|
||||
else if (ctrl.mEnumeration) // Check before integer
|
||||
{
|
||||
size_t s;
|
||||
for (s = ctrl.mScaleValues.GetCount() - 1; s >= 0; s--)
|
||||
int s;
|
||||
for (s = (int) ctrl.mScaleValues.GetCount() - 1; s >= 0; s--)
|
||||
{
|
||||
if (ctrl.mVal >= ctrl.mScaleValues[s])
|
||||
{
|
||||
|
@ -1901,8 +1901,8 @@ bool LV2Effect::TransferDataToWindow()
|
|||
}
|
||||
else if (ctrl.mEnumeration) // Check before integer
|
||||
{
|
||||
size_t s;
|
||||
for (s = ctrl.mScaleValues.GetCount() - 1; s >= 0; s--)
|
||||
int s;
|
||||
for (s = (int) ctrl.mScaleValues.GetCount() - 1; s >= 0; s--)
|
||||
{
|
||||
if (ctrl.mVal >= ctrl.mScaleValues[s])
|
||||
{
|
||||
|
|
|
@ -47,7 +47,7 @@ void GetQTImportPlugin(ImportPluginList *importPluginList,
|
|||
#include <Carbon/Carbon.h>
|
||||
#include <QuickTime/QuickTime.h>
|
||||
|
||||
#include <wx/mac/private.h>
|
||||
#include <wx/osx/core/private.h>
|
||||
#else
|
||||
// These get used when building under Windows
|
||||
#include <ConditionalMacros.h>
|
||||
|
|
|
@ -142,7 +142,8 @@ void LibraryPrefs::PopulateOrExchange(ShuttleGui & S)
|
|||
bfnd->Enable(FALSE);
|
||||
#else
|
||||
// fix compilation warnings about unused variables
|
||||
bfnd, bdwn;
|
||||
wxUnusedVar(bfnd);
|
||||
wxUnusedVar(bdwn);
|
||||
#endif
|
||||
}
|
||||
S.EndTwoColumn();
|
||||
|
|
|
@ -38,11 +38,14 @@
|
|||
#include "../ImageManipulation.h"
|
||||
#include "../Project.h"
|
||||
#include "../TimeTrack.h"
|
||||
#include "../VoiceKey.h"
|
||||
#include "../WaveTrack.h"
|
||||
#include "../widgets/AButton.h"
|
||||
#include "../widgets/ASlider.h"
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
#include "../VoiceKey.h"
|
||||
#endif
|
||||
|
||||
IMPLEMENT_CLASS(TranscriptionToolBar, ToolBar);
|
||||
|
||||
///////////////////////////////////////////
|
||||
|
@ -52,9 +55,13 @@ IMPLEMENT_CLASS(TranscriptionToolBar, ToolBar);
|
|||
|
||||
BEGIN_EVENT_TABLE(TranscriptionToolBar, ToolBar)
|
||||
EVT_CHAR(TranscriptionToolBar::OnKeyEvent)
|
||||
EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, TranscriptionToolBar::OnCaptureKey)
|
||||
|
||||
EVT_COMMAND_RANGE(TTB_PlaySpeed, TTB_PlaySpeed,
|
||||
wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnPlaySpeed)
|
||||
EVT_SLIDER(TTB_PlaySpeedSlider, TranscriptionToolBar::OnSpeedSlider)
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
EVT_COMMAND_RANGE(TTB_StartOn, TTB_StartOn,
|
||||
wxEVT_COMMAND_BUTTON_CLICKED, TranscriptionToolBar::OnStartOn)
|
||||
EVT_COMMAND_RANGE(TTB_StartOff, TTB_StartOff,
|
||||
|
@ -76,7 +83,7 @@ BEGIN_EVENT_TABLE(TranscriptionToolBar, ToolBar)
|
|||
EVT_SLIDER(TTB_SensitivitySlider, TranscriptionToolBar::OnSensitivitySlider)
|
||||
|
||||
EVT_CHOICE(TTB_KeyType, TranscriptionToolBar::SetKeyType)
|
||||
EVT_COMMAND(wxID_ANY, EVT_CAPTURE_KEY, TranscriptionToolBar::OnCaptureKey)
|
||||
#endif
|
||||
END_EVENT_TABLE()
|
||||
; //semicolon enforces proper automatic indenting in emacs.
|
||||
|
||||
|
@ -264,6 +271,25 @@ void TranscriptionToolBar::Populate()
|
|||
UpdatePrefs();
|
||||
}
|
||||
|
||||
void TranscriptionToolBar::EnableDisableButtons()
|
||||
{
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
AudacityProject *p = GetActiveProject();
|
||||
if (!p) return;
|
||||
// Is anything selected?
|
||||
bool selection = false;
|
||||
TrackListIterator iter(p->GetTracks());
|
||||
for (Track *t = iter.First(); t; t = iter.Next())
|
||||
if (t->GetSelected()) {
|
||||
selection = true;
|
||||
break;
|
||||
}
|
||||
selection &= (p->GetSel0() < p->GetSel1());
|
||||
|
||||
mButtons[TTB_Calibrate]->SetEnabled(selection);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TranscriptionToolBar::UpdatePrefs()
|
||||
{
|
||||
RegenerateTooltips();
|
||||
|
@ -471,6 +497,7 @@ void TranscriptionToolBar::OnSpeedSlider(wxCommandEvent& WXUNUSED(event))
|
|||
//}
|
||||
}
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
void TranscriptionToolBar::OnStartOn(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
//If IO is busy, abort immediately
|
||||
|
@ -847,26 +874,6 @@ void TranscriptionToolBar::OnSensitivitySlider(wxCommandEvent & WXUNUSED(event))
|
|||
mSensitivity = (mSensitivitySlider->Get());
|
||||
}
|
||||
|
||||
void TranscriptionToolBar::EnableDisableButtons()
|
||||
{
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
AudacityProject *p = GetActiveProject();
|
||||
if (!p) return;
|
||||
// Is anything selected?
|
||||
bool selection = false;
|
||||
TrackListIterator iter(p->GetTracks());
|
||||
for (Track *t = iter.First(); t; t = iter.Next())
|
||||
if (t->GetSelected()) {
|
||||
selection = true;
|
||||
break;
|
||||
}
|
||||
selection &= (p->GetSel0() < p->GetSel1());
|
||||
|
||||
mButtons[TTB_Calibrate]->SetEnabled(selection);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TranscriptionToolBar::SetKeyType(wxCommandEvent & WXUNUSED(event))
|
||||
{
|
||||
int value = mKeyTypeChoice->GetSelection();
|
||||
|
@ -892,6 +899,7 @@ void TranscriptionToolBar::SetKeyType(wxCommandEvent & WXUNUSED(event))
|
|||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void TranscriptionToolBar::ShowPlaySpeedDialog()
|
||||
{
|
||||
|
|
|
@ -32,31 +32,36 @@ class wxPen;
|
|||
class AButton;
|
||||
class ASlider;
|
||||
class TimeTrack;
|
||||
class VoiceKey;
|
||||
class WaveTrack;
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
class VoiceKey;
|
||||
//TTB 0-8 are button-ids, which also correspond to their
|
||||
//position in mButtons. 9 & 10 are ids for sliders, which aren't
|
||||
//in the button array.
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
TTB_PlaySpeed,
|
||||
TTB_StartOn,
|
||||
TTB_EndOn,
|
||||
TTB_StartOff,
|
||||
TTB_EndOff,
|
||||
TTB_SelectSound,
|
||||
TTB_SelectSilence,
|
||||
TTB_AutomateSelection,
|
||||
TTB_MakeLabel,
|
||||
TTB_Calibrate,
|
||||
{
|
||||
TTB_PlaySpeed,
|
||||
TTB_PlaySpeedSlider,
|
||||
|
||||
TTB_SensitivitySlider,
|
||||
TTB_PlaySpeedSlider,
|
||||
TTB_KeyType
|
||||
};
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
TTB_StartOn,
|
||||
TTB_EndOn,
|
||||
TTB_StartOff,
|
||||
TTB_EndOff,
|
||||
TTB_SelectSound,
|
||||
TTB_SelectSilence,
|
||||
TTB_AutomateSelection,
|
||||
TTB_MakeLabel,
|
||||
TTB_Calibrate,
|
||||
TTB_SensitivitySlider,
|
||||
TTB_KeyType,
|
||||
#endif
|
||||
|
||||
#define TTBNumButtons 10
|
||||
TTBNumButtons
|
||||
};
|
||||
|
||||
class TranscriptionToolBar:public ToolBar {
|
||||
|
||||
|
@ -70,6 +75,16 @@ class TranscriptionToolBar:public ToolBar {
|
|||
virtual void OnKeyEvent(wxKeyEvent & event);
|
||||
virtual void OnPlaySpeed(wxCommandEvent & event);
|
||||
virtual void OnSpeedSlider(wxCommandEvent & event);
|
||||
|
||||
virtual void Populate();
|
||||
virtual void Repaint(wxDC * WXUNUSED(dc)) {};
|
||||
virtual void EnableDisableButtons();
|
||||
virtual void UpdatePrefs();
|
||||
|
||||
void OnFocus(wxFocusEvent &event);
|
||||
void OnCaptureKey(wxCommandEvent &event);
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
virtual void OnStartOn(wxCommandEvent & event);
|
||||
virtual void OnStartOff(wxCommandEvent & event);
|
||||
virtual void OnEndOn(wxCommandEvent & event);
|
||||
|
@ -80,17 +95,9 @@ class TranscriptionToolBar:public ToolBar {
|
|||
virtual void OnMakeLabel(wxCommandEvent & event);
|
||||
virtual void OnAutomateSelection(wxCommandEvent & event);
|
||||
virtual void OnSensitivitySlider(wxCommandEvent & event);
|
||||
|
||||
virtual void Populate();
|
||||
virtual void Repaint(wxDC * WXUNUSED(dc)) {};
|
||||
virtual void EnableDisableButtons();
|
||||
virtual void UpdatePrefs();
|
||||
|
||||
void OnFocus(wxFocusEvent &event);
|
||||
void OnCaptureKey(wxCommandEvent &event);
|
||||
|
||||
virtual double GetSensitivity();
|
||||
virtual void SetKeyType(wxCommandEvent & event);
|
||||
#endif
|
||||
|
||||
void PlayAtSpeed(bool looped, bool cutPreview);
|
||||
void ShowPlaySpeedDialog();
|
||||
|
@ -123,8 +130,12 @@ class TranscriptionToolBar:public ToolBar {
|
|||
ASlider *mPlaySpeedSlider;
|
||||
double mPlaySpeed;
|
||||
ASlider *mSensitivitySlider;
|
||||
|
||||
#ifdef EXPERIMENTAL_VOICE_DETECTION
|
||||
double mSensitivity;
|
||||
VoiceKey *mVk;
|
||||
wxChoice *mKeyTypeChoice;
|
||||
#endif
|
||||
|
||||
wxBrush mBackgroundBrush;
|
||||
wxPen mBackgroundPen;
|
||||
|
@ -132,7 +143,6 @@ class TranscriptionToolBar:public ToolBar {
|
|||
int mBackgroundHeight;
|
||||
|
||||
TimeTrack *mTimeTrack;
|
||||
wxChoice *mKeyTypeChoice;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -140,7 +150,5 @@ class TranscriptionToolBar:public ToolBar {
|
|||
DECLARE_EVENT_TABLE();
|
||||
};
|
||||
|
||||
|
||||
#define COMMAND_LINE_LOG_TRACE TRUE
|
||||
#endif
|
||||
|
||||
|
|
|
@ -46,13 +46,13 @@ class HtmlTextHelpDialog : public BrowserFrame
|
|||
public:
|
||||
HtmlTextHelpDialog() : BrowserFrame()
|
||||
{
|
||||
#if !wxCHECK_VERSION(3, 1, 0)
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
MakeModal( true );
|
||||
#endif
|
||||
}
|
||||
virtual ~HtmlTextHelpDialog()
|
||||
{
|
||||
#if !wxCHECK_VERSION(3, 1, 0)
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
MakeModal( false );
|
||||
#endif
|
||||
// On Windows, for some odd reason, the Audacity window will be sent to
|
||||
|
|
|
@ -1168,6 +1168,7 @@ ProgressDialog::ProgressDialog(const wxString & title, const wxString & message,
|
|||
// no editing in any project until Timer Record finishes.
|
||||
mDisable = new wxWindowDisabler(this);
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
#if defined(__WXMAC__)
|
||||
// LL: On the Mac, the parent windows get disabled, but they still respond
|
||||
// to the close button being clicked and the application quit menu item
|
||||
|
@ -1206,6 +1207,7 @@ ProgressDialog::ProgressDialog(const wxString & title, const wxString & message,
|
|||
// no longer be processed.
|
||||
wxTheApp->SetEvtHandlerEnabled(false);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1220,6 +1222,7 @@ ProgressDialog::~ProgressDialog()
|
|||
Beep();
|
||||
}
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
#if defined(__WXMSW__)
|
||||
// Undo above fix for bug 334.
|
||||
wxTheApp->SetEvtHandlerEnabled(true);
|
||||
|
@ -1245,6 +1248,7 @@ ProgressDialog::~ProgressDialog()
|
|||
if (windowRef) {
|
||||
EndAppModalStateForWindow(windowRef);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (mDisable)
|
||||
|
@ -1316,6 +1320,7 @@ ProgressDialog::Show(bool show)
|
|||
{
|
||||
mDisable = new wxWindowDisabler(this);
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
#if defined(__WXMAC__)
|
||||
// LL: On the Mac, the parent windows get disabled, but they still respond
|
||||
// to the close button being clicked and the application quit menu item
|
||||
|
@ -1330,6 +1335,7 @@ ProgressDialog::Show(bool show)
|
|||
bar->Enable(wxID_PREFERENCES, false);
|
||||
bar->Enable(wxID_EXIT, false);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -130,13 +130,16 @@ Ruler::Ruler()
|
|||
mMinorMinorFont = new wxFont(fontSize - 1, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
||||
mMinorFont = new wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
|
||||
mMajorFont = new wxFont(fontSize, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD);
|
||||
|
||||
mUserFonts = false;
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
#ifdef __WXMAC__
|
||||
mMinorMinorFont->SetNoAntiAliasing(true);
|
||||
mMinorFont->SetNoAntiAliasing(true);
|
||||
mMajorFont->SetNoAntiAliasing(true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
mMajorLabels = 0;
|
||||
mMinorLabels = 0;
|
||||
|
@ -291,11 +294,13 @@ void Ruler::SetFonts(const wxFont &minorFont, const wxFont &majorFont, const wxF
|
|||
*mMinorFont = minorFont;
|
||||
*mMajorFont = majorFont;
|
||||
|
||||
#if !wxCHECK_VERSION(3, 0, 0)
|
||||
#ifdef __WXMAC__
|
||||
mMinorMinorFont->SetNoAntiAliasing(true);
|
||||
mMinorFont->SetNoAntiAliasing(true);
|
||||
mMajorFont->SetNoAntiAliasing(true);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Won't override these fonts
|
||||
mUserFonts = true;
|
||||
|
|
Loading…
Reference in New Issue