From 4ed1d791e573c3e4476be0d938f89fb4bf9771b3 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Sat, 2 Jan 2010 14:55:44 +0000 Subject: [PATCH] New class HeapBlock, which provides a safe and object-oriented way to allocate heap space. I've used HeapBlocks to replace almost all uses of malloc/free throughout the codebase. --- build/macosx/Juce.xcodeproj/project.pbxproj | 6 + build/win32/vc8/JUCE.vcproj | 4 + .../wrapper/AU/juce_AU_Wrapper.mm | 11 +- .../wrapper/RTAS/juce_RTAS_Wrapper.cpp | 9 +- .../wrapper/VST/juce_VST_Wrapper.cpp | 15 +- .../wrapper/juce_ActiveX_GlueCode.cpp | 16 +- .../wrapper/juce_NPAPI_GlueCode.cpp | 10 +- .../juce demo/build/win32_vc8/jucedemo.vcproj | 3 +- juce_amalgamated.cpp | 1919 +- juce_amalgamated.h | 40468 ++++++++-------- .../audio_file_formats/juce_AudioCDReader.h | 1 + .../audio_file_formats/juce_AudioFormat.h | 1 + .../juce_AudioFormatManager.h | 1 + .../juce_QuickTimeAudioFormat.cpp | 15 +- .../juce_WavAudioFormat.cpp | 8 +- .../juce_ChannelRemappingAudioSource.h | 1 + src/audio/dsp/juce_AudioSampleBuffer.cpp | 179 +- src/audio/dsp/juce_AudioSampleBuffer.h | 6 +- .../formats/juce_AudioUnitPluginFormat.mm | 16 +- .../plugins/formats/juce_VSTMidiEventList.h | 11 +- .../plugins/formats/juce_VSTPluginFormat.cpp | 12 +- .../processors/juce_AudioProcessorGraph.cpp | 5 +- src/containers/juce_BitArray.cpp | 26 +- src/containers/juce_BitArray.h | 3 +- src/containers/juce_HeapBlock.h | 240 + src/containers/juce_MemoryBlock.cpp | 34 +- src/containers/juce_MemoryBlock.h | 3 +- src/containers/juce_Variant.cpp | 3 +- src/containers/juce_Variant.h | 1 + src/core/juce_Memory.h | 76 +- src/cryptography/juce_BlowFish.cpp | 6 +- src/cryptography/juce_BlowFish.h | 4 +- .../code_editor/juce_CodeDocument.h | 1 + .../special/juce_MidiKeyboardComponent.cpp | 2 +- .../graphics/colour/juce_ColourGradient.cpp | 9 +- src/gui/graphics/colour/juce_ColourGradient.h | 7 +- src/gui/graphics/contexts/juce_EdgeTable.cpp | 24 +- src/gui/graphics/contexts/juce_EdgeTable.h | 2 +- .../juce_LowLevelGraphicsSoftwareRenderer.cpp | 25 +- src/gui/graphics/fonts/juce_TextLayout.h | 1 + .../graphics/geometry/juce_PathIterator.cpp | 7 +- src/gui/graphics/geometry/juce_PathIterator.h | 2 +- .../graphics/geometry/juce_PathStrokeType.cpp | 1 - .../image_file_formats/juce_JPEGLoader.cpp | 5 +- .../image_file_formats/juce_PNGLoader.cpp | 24 +- src/gui/graphics/imaging/juce_Image.cpp | 10 +- src/gui/graphics/imaging/juce_Image.h | 2 +- src/gui/graphics/imaging/juce_ImageCache.h | 1 + .../imaging/juce_ImageConvolutionKernel.cpp | 35 +- .../imaging/juce_ImageConvolutionKernel.h | 4 +- src/io/files/juce_FileOutputStream.cpp | 3 +- src/io/files/juce_FileOutputStream.h | 2 +- src/io/files/juce_ZipFile.h | 1 + src/io/network/juce_URL.cpp | 6 +- src/io/streams/juce_BufferedInputStream.cpp | 12 +- src/io/streams/juce_BufferedInputStream.h | 2 +- .../juce_GZIPCompressorOutputStream.cpp | 16 +- .../streams/juce_GZIPCompressorOutputStream.h | 2 +- .../juce_GZIPDecompressorInputStream.cpp | 16 +- .../juce_GZIPDecompressorInputStream.h | 2 +- src/io/streams/juce_OutputStream.cpp | 11 +- src/juce_app_includes.h | 684 +- src/juce_core_includes.h | 151 +- src/native/linux/juce_linux_JackAudio.cpp | 12 +- src/native/linux/juce_linux_Midi.cpp | 3 +- src/native/linux/juce_linux_Windowing.cpp | 37 +- src/native/mac/juce_mac_CoreAudio.cpp | 173 +- .../mac/juce_mac_CoreGraphicsContext.mm | 11 +- src/native/mac/juce_mac_CoreMidi.cpp | 5 +- src/native/mac/juce_mac_Fonts.mm | 46 +- src/native/mac/juce_mac_Strings.mm | 25 +- src/native/windows/juce_win32_ASIO.cpp | 9 +- .../windows/juce_win32_AudioCDReader.cpp | 4 +- .../windows/juce_win32_CameraDevice.cpp | 6 +- src/native/windows/juce_win32_DirectSound.cpp | 15 +- src/native/windows/juce_win32_Files.cpp | 4 +- src/native/windows/juce_win32_Fonts.cpp | 14 +- .../juce_win32_QuickTimeMovieComponent.cpp | 8 +- src/native/windows/juce_win32_Windowing.cpp | 689 +- src/text/juce_StringArray.cpp | 69 +- src/text/juce_StringArray.h | 4 +- src/text/juce_XmlElement.cpp | 9 +- src/text/juce_XmlElement.h | 8 +- src/threads/juce_ThreadPool.cpp | 4 +- src/threads/juce_ThreadPool.h | 3 +- src/utilities/juce_UndoManager.h | 1 + 86 files changed, 22712 insertions(+), 22630 deletions(-) create mode 100644 src/containers/juce_HeapBlock.h diff --git a/build/macosx/Juce.xcodeproj/project.pbxproj b/build/macosx/Juce.xcodeproj/project.pbxproj index 1b119fad8d..ac6496edaa 100644 --- a/build/macosx/Juce.xcodeproj/project.pbxproj +++ b/build/macosx/Juce.xcodeproj/project.pbxproj @@ -643,6 +643,7 @@ 8484E9D8103C95A6008B7C6C /* juce_posix_SharedCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8484E9D6103C95A6008B7C6C /* juce_posix_SharedCode.h */; }; 8484E9D9103C95A6008B7C6C /* juce_posix_NamedPipe.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8484E9D7103C95A6008B7C6C /* juce_posix_NamedPipe.cpp */; }; 84A63C02107DF286000326FD /* juce_mac_ObjCSuffix.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A63C01107DF286000326FD /* juce_mac_ObjCSuffix.h */; }; + 84AB6F6E10EF948B00117E64 /* juce_HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */; }; 84AB91FB10A078190048FC39 /* juce_CodeDocument.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84AB91F510A078190048FC39 /* juce_CodeDocument.cpp */; }; 84AB91FC10A078190048FC39 /* juce_CodeDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 84AB91F610A078190048FC39 /* juce_CodeDocument.h */; }; 84AB91FD10A078190048FC39 /* juce_CodeEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84AB91F710A078190048FC39 /* juce_CodeEditorComponent.cpp */; }; @@ -653,6 +654,7 @@ 84B2053E10D535EC008B4A79 /* juce_ValueTree.h in Headers */ = {isa = PBXBuildFile; fileRef = 843D4A3A10D3C54500624BA6 /* juce_ValueTree.h */; }; 84B2053F10D535EC008B4A79 /* juce_ValueTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 843D4A3910D3C54500624BA6 /* juce_ValueTree.cpp */; }; 84D0F00C109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */; }; + 84DEDD9F10EE496500909D01 /* juce_HeapBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */; }; 84F1E6E710403605006A1807 /* juce_Application.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F1E6DC10403605006A1807 /* juce_Application.cpp */; }; 84F1E6E810403605006A1807 /* juce_Application.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6DD10403605006A1807 /* juce_Application.h */; }; 84F1E6E910403605006A1807 /* juce_ApplicationCommandID.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F1E6DE10403605006A1807 /* juce_ApplicationCommandID.h */; }; @@ -1260,6 +1262,7 @@ 84AB91FA10A078190048FC39 /* juce_CPlusPlusCodeTokeniser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_CPlusPlusCodeTokeniser.h; path = components/code_editor/juce_CPlusPlusCodeTokeniser.h; sourceTree = ""; }; 84AB927110A082E30048FC39 /* juce_CodeTokeniser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_CodeTokeniser.h; path = components/code_editor/juce_CodeTokeniser.h; sourceTree = ""; }; 84D0F00B109B1546007F73A3 /* juce_mac_CoreGraphicsContext.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = juce_mac_CoreGraphicsContext.mm; sourceTree = ""; }; + 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_HeapBlock.h; sourceTree = ""; }; 84F1E6DC10403605006A1807 /* juce_Application.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Application.cpp; path = ../../src/application/juce_Application.cpp; sourceTree = SOURCE_ROOT; }; 84F1E6DD10403605006A1807 /* juce_Application.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_Application.h; path = ../../src/application/juce_Application.h; sourceTree = SOURCE_ROOT; }; 84F1E6DE10403605006A1807 /* juce_ApplicationCommandID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_ApplicationCommandID.h; path = ../../src/application/juce_ApplicationCommandID.h; sourceTree = SOURCE_ROOT; }; @@ -2162,6 +2165,7 @@ 84F1E8D510403671006A1807 /* juce_MemoryBlock.cpp */, 84F1E8D610403671006A1807 /* juce_MemoryBlock.h */, 84F1E8D710403671006A1807 /* juce_OwnedArray.h */, + 84DEDD9E10EE496500909D01 /* juce_HeapBlock.h */, 84F1E8D810403671006A1807 /* juce_PropertySet.cpp */, 84F1E8D910403671006A1807 /* juce_PropertySet.h */, 84F1E8DA10403671006A1807 /* juce_ReferenceCountedArray.h */, @@ -3206,6 +3210,7 @@ 844BB95D10C5579B00DF5536 /* juce_FillType.h in Headers */, 844BB95F10C557A800DF5536 /* juce_Config.h in Headers */, 84B2053E10D535EC008B4A79 /* juce_ValueTree.h in Headers */, + 84AB6F6E10EF948B00117E64 /* juce_HeapBlock.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3530,6 +3535,7 @@ 84AB927210A082E30048FC39 /* juce_CodeTokeniser.h in Headers */, 84F29AA010C2EFA5005014DF /* juce_FillType.h in Headers */, 843D4A3C10D3C54500624BA6 /* juce_ValueTree.h in Headers */, + 84DEDD9F10EE496500909D01 /* juce_HeapBlock.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/win32/vc8/JUCE.vcproj b/build/win32/vc8/JUCE.vcproj index 33145ff9b7..50fc89a61d 100644 --- a/build/win32/vc8/JUCE.vcproj +++ b/build/win32/vc8/JUCE.vcproj @@ -1085,6 +1085,10 @@ RelativePath="..\..\..\src\containers\juce_ElementComparator.h" > + + diff --git a/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm b/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm index 6358d47ed3..a4340a8cc2 100644 --- a/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm +++ b/extras/audio plugins/wrapper/AU/juce_AU_Wrapper.mm @@ -127,7 +127,6 @@ public: #endif juceFilter (0), bufferSpace (2, 16), - channels (0), prepared (false) { if (activePlugins.size() + activeUIs.size() == 0) @@ -162,9 +161,6 @@ public: delete juceFilter; juceFilter = 0; - juce_free (channels); - channels = 0; - jassert (activePlugins.contains (this)); activePlugins.removeValue (this); @@ -659,9 +655,8 @@ public: midiEvents.clear(); incomingEvents.clear(); - juce_free (channels); - channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), - juceFilter->getNumOutputChannels()) + 4); + channels.calloc (jmax (juceFilter->getNumInputChannels(), + juceFilter->getNumOutputChannels()) + 4); prepared = true; } @@ -940,7 +935,7 @@ protected: private: AudioProcessor* juceFilter; AudioSampleBuffer bufferSpace; - float** channels; + HeapBlock channels; MidiBuffer midiEvents, incomingEvents; bool prepared; SMPTETime lastSMPTETime; diff --git a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp index 931c6a09cd..0f161faa28 100644 --- a/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp +++ b/extras/audio plugins/wrapper/RTAS/juce_RTAS_Wrapper.cpp @@ -159,7 +159,6 @@ public: JucePlugInProcess() : midiBufferNode (0), midiTransport (0), - channels (0), prepared (false), sampleRate (44100.0) { @@ -183,7 +182,6 @@ public: juceFilter->releaseResources(); delete juceFilter; - juce_free (channels); if (--numInstances == 0) shutdownJuce_GUI(); @@ -509,9 +507,8 @@ protected: sampleRate = gProcessGroup->GetSampleRate(); jassert (sampleRate > 0); - juce_free (channels); - channels = (float**) juce_calloc (sizeof (float*) * jmax (juceFilter->getNumInputChannels(), - juceFilter->getNumOutputChannels())); + channels.calloc (jmax (juceFilter->getNumInputChannels(), + juceFilter->getNumOutputChannels())); juceFilter->setPlayConfigDetails (fNumInputs, fNumOutputs, sampleRate, mRTGlobals->mHWBufferSizeInSamples); @@ -807,7 +804,7 @@ private: DirectMidiPacket midiBuffer [midiBufferSize]; JUCE_NAMESPACE::MemoryBlock tempFilterData; - float** channels; + HeapBlock channels; bool prepared; double sampleRate; diff --git a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp index c1ab2a687a..c3d966296f 100644 --- a/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp +++ b/extras/audio plugins/wrapper/VST/juce_VST_Wrapper.cpp @@ -383,7 +383,6 @@ public: hasShutdown = false; firstProcessCallback = true; shouldDeleteEditor = false; - channels = 0; speakerIn = kSpeakerArrEmpty; speakerOut = kSpeakerArrEmpty; speakerInChans = 0; @@ -439,8 +438,7 @@ public: jassert (editorComp == 0); - juce_free (channels); - channels = 0; + channels.free(); deleteTempChannels(); jassert (activePlugins.contains (this)); @@ -766,8 +764,7 @@ public: return; isProcessing = true; - juce_free (channels); - channels = (float**) juce_calloc (sizeof (float*) * (numInChans + numOutChans)); + channels.calloc (numInChans + numOutChans); double rate = getSampleRate(); jassert (rate > 0); @@ -813,8 +810,7 @@ public: outgoingEvents.freeEvents(); isProcessing = false; - juce_free (channels); - channels = 0; + channels.free(); deleteTempChannels(); } @@ -1398,15 +1394,14 @@ private: VstSpeakerArrangementType speakerIn, speakerOut; int speakerInChans, speakerOutChans; int numInChans, numOutChans; - float** channels; + HeapBlock channels; VoidArray tempChannels; // see note in processReplacing() bool hasCreatedTempChannels; bool shouldDeleteEditor; void deleteTempChannels() { - int i; - for (i = tempChannels.size(); --i >= 0;) + for (int i = tempChannels.size(); --i >= 0;) juce_free (tempChannels.getUnchecked(i)); tempChannels.clear(); diff --git a/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp b/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp index 656b87202c..c27303e7d3 100644 --- a/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp +++ b/extras/browser plugins/wrapper/juce_ActiveX_GlueCode.cpp @@ -124,7 +124,9 @@ public: } else { - var* args = (var*) juce_calloc (sizeof (var) * numArgs); + HeapBlock args; + args.calloc (numArgs); + for (int j = 0; j < numArgs; ++j) args[(numArgs - 1) - j] = variantTojuceVar (pDispParams->rgvarg[j]); @@ -132,8 +134,6 @@ public: for (int j = 0; j < numArgs; ++j) args[j] = var(); - - juce_free (args); } if (pVarResult != 0) @@ -329,7 +329,8 @@ public: DISPID id = 0; if (source->GetIDsOfNames (IID_NULL, (LPOLESTR*)&name, 1, 0, &id) == S_OK) { - VARIANT* params = (VARIANT*) juce_calloc (sizeof (VARIANT) * (numParameters + 1)); + HeapBlock params; + params.calloc (numParameters + 1); for (int i = 0; i < numParameters; ++i) juceVarToVariant (parameters[(numParameters - 1) - i], params[i]); @@ -352,8 +353,6 @@ public: returnValue = variantTojuceVar (result); VariantClear (&result); } - - juce_free (params); } return returnValue; @@ -558,7 +557,8 @@ static const String getExeVersion (const String& exeFileName, const String& fiel if (size > 0) { - void* const exeInfo = juce_calloc (size); + HeapBlock exeInfo; + exeInfo.calloc (size); if (GetFileVersionInfo (exeFileName, 0, size, exeInfo)) { @@ -577,8 +577,6 @@ static const String getExeVersion (const String& exeFileName, const String& fiel resultString = String (result, resultLen); } - - juce_free (exeInfo); } return resultString; diff --git a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp index 17780a4955..8453e7ae53 100644 --- a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp +++ b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp @@ -621,7 +621,7 @@ public: if (numParameters > 0) { - NPVariant* const params = (NPVariant*) juce_malloc (sizeof (NPVariant) * numParameters); + HeapBlock params (numParameters); int i; for (i = 0; i < numParameters; ++i) @@ -636,8 +636,6 @@ public: for (i = 0; i < numParameters; ++i) browser.releasevariantvalue (¶ms[i]); - - juce_free (params); } else { @@ -688,7 +686,9 @@ private: if (o == 0 || ! o->hasMethod (methodName)) return false; - var* params = (var*) juce_calloc (sizeof (var) * argCount); + HeapBlock params; + params.calloc (argCount); + for (uint32_t i = 0; i < argCount; ++i) params[i] = createValueFromNPVariant (npp, args[i]); @@ -697,8 +697,6 @@ private: for (int i = argCount; --i >= 0;) params[i] = var(); - juce_free (params); - if (out != 0) createNPVariantFromValue (npp, *out, result); diff --git a/extras/juce demo/build/win32_vc8/jucedemo.vcproj b/extras/juce demo/build/win32_vc8/jucedemo.vcproj index a36493bcaa..c32dedd3b0 100644 --- a/extras/juce demo/build/win32_vc8/jucedemo.vcproj +++ b/extras/juce demo/build/win32_vc8/jucedemo.vcproj @@ -46,12 +46,13 @@ /> > 5) + 1); negative = other.negative; - const int memSize = sizeof (unsigned int) * (numValues + 1); - values = (unsigned int*)juce_malloc (memSize); - memcpy (values, other.values, memSize); + values.malloc (numValues + 1); + memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1)); } return *this; @@ -2336,9 +2331,8 @@ void BitArray::clear() throw() { if (numValues > 16) { - juce_free (values); numValues = 4; - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); } else { @@ -2986,7 +2980,7 @@ void BitArray::ensureSize (const int numVals) throw() { int oldSize = numValues; numValues = ((numVals + 2) * 3) / 2; - values = (unsigned int*) juce_realloc (values, sizeof (unsigned int) * numValues + 4); + values.realloc (numValues + 1); while (oldSize < numValues) values [oldSize++] = 0; @@ -3120,8 +3114,7 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE MemoryBlock::MemoryBlock() throw() - : data (0), - size (0) + : size (0) { } @@ -3131,35 +3124,28 @@ MemoryBlock::MemoryBlock (const int initialSize, if (initialSize > 0) { size = initialSize; - - if (initialiseToZero) - data = (char*) juce_calloc (initialSize); - else - data = (char*) juce_malloc (initialSize); + data.allocate (initialSize, initialiseToZero); } else { - data = 0; size = 0; } } MemoryBlock::MemoryBlock (const MemoryBlock& other) throw() - : data (0), - size (other.size) + : size (other.size) { if (size > 0) { jassert (other.data != 0); - data = (char*) juce_malloc (size); + data.malloc (size); memcpy (data, other.data, size); } } MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const int sizeInBytes) throw() - : data (0), - size (jmax (0, sizeInBytes)) + : size (jmax (0, sizeInBytes)) { jassert (sizeInBytes >= 0); @@ -3167,7 +3153,7 @@ MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, { jassert (dataToInitialiseFrom != 0); // non-zero size, but a zero pointer passed-in? - data = (char*) juce_malloc (size); + data.malloc (size); if (dataToInitialiseFrom != 0) memcpy (data, dataToInitialiseFrom, size); @@ -3178,8 +3164,6 @@ MemoryBlock::~MemoryBlock() throw() { jassert (size >= 0); // should never happen jassert (size == 0 || data != 0); // non-zero size but no data allocated? - - juce_free (data); } const MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) throw() @@ -3212,25 +3196,21 @@ void MemoryBlock::setSize (const int newSize, { if (newSize <= 0) { - juce_free (data); - data = 0; + data.free(); size = 0; } else { if (data != 0) { - data = (char*) juce_realloc (data, newSize); + data.realloc (newSize); if (initialiseToZero && (newSize > size)) zeromem (data + size, newSize - size); } else { - if (initialiseToZero) - data = (char*) juce_calloc (newSize); - else - data = (char*) juce_malloc (newSize); + data.allocate (newSize, initialiseToZero); } size = newSize; @@ -3327,7 +3307,7 @@ void MemoryBlock::removeSection (int startByte, int numBytesToRemove) throw() const String MemoryBlock::toString() const throw() { - return String (data, size); + return String ((const char*) data, size); } int MemoryBlock::getBitRange (const int bitRangeStart, int numBits) const throw() @@ -3987,10 +3967,9 @@ void var::writeToStream (OutputStream& output) const throw() const int len = value.stringValue->copyToUTF8 (0); output.writeCompressedInt (len + 1); output.writeByte (5); - uint8* const temp = (uint8*) juce_malloc (len); + HeapBlock temp (len); value.stringValue->copyToUTF8 (temp); output.write (temp, len); - juce_free (temp); break; } case objectType: output.writeCompressedInt (0); jassertfalse; break; // Can't write an object to a stream! @@ -4461,7 +4440,7 @@ BlowFish::BlowFish (const uint8* keyData, int keyBytes) int i, j; for (i = 4; --i >= 0;) { - s[i] = (uint32*) juce_malloc (256 * sizeof (uint32)); + s[i].malloc (256); memcpy (s[i], initialSValues + i * 256, 256 * sizeof (uint32)); } @@ -4507,7 +4486,7 @@ BlowFish::BlowFish (const uint8* keyData, int keyBytes) BlowFish::BlowFish (const BlowFish& other) { for (int i = 4; --i >= 0;) - s[i] = (uint32*) juce_malloc (256 * sizeof (uint32)); + s[i].malloc (256); operator= (other); } @@ -4524,8 +4503,6 @@ const BlowFish& BlowFish::operator= (const BlowFish& other) BlowFish::~BlowFish() { - for (int i = 4; --i >= 0;) - juce_free (s[i]); } uint32 BlowFish::F (uint32 x) const @@ -5697,18 +5674,16 @@ void OutputStream::writeDoubleBigEndian (double value) void OutputStream::writeString (const String& text) { const int numBytes = text.copyToUTF8 (0); - uint8* const temp = (uint8*) juce_malloc (numBytes); + HeapBlock temp (numBytes); text.copyToUTF8 (temp); write (temp, numBytes); // (numBytes includes the terminating null). - - juce_free (temp); } void OutputStream::printf (const char* pf, ...) { unsigned int bufSize = 256; - char* buf = (char*) juce_malloc (bufSize); + HeapBlock buf (bufSize); for (;;) { @@ -5729,12 +5704,9 @@ void OutputStream::printf (const char* pf, ...) break; } - juce_free (buf); bufSize += 256; - buf = (char*) juce_malloc (bufSize); + buf.malloc (bufSize); } - - juce_free (buf); } OutputStream& OutputStream::operator<< (const int number) @@ -6814,15 +6786,25 @@ bool File::hasFileExtension (const String& possibleSuffix) const throw() if (possibleSuffix.isEmpty()) return fullPath.lastIndexOfChar (T('.')) <= fullPath.lastIndexOfChar (separator); - if (fullPath.endsWithIgnoreCase (possibleSuffix)) + const int semicolon = possibleSuffix.indexOfChar (0, T(';')); + + if (semicolon >= 0) { - if (possibleSuffix.startsWithChar (T('.'))) - return true; + return hasFileExtension (possibleSuffix.substring (0, semicolon).trimEnd()) + || hasFileExtension (possibleSuffix.substring (semicolon + 1).trimStart()); + } + else + { + if (fullPath.endsWithIgnoreCase (possibleSuffix)) + { + if (possibleSuffix.startsWithChar (T('.'))) + return true; - const int dotPos = fullPath.length() - possibleSuffix.length() - 1; + const int dotPos = fullPath.length() - possibleSuffix.length() - 1; - if (dotPos >= 0) - return fullPath [dotPos] == T('.'); + if (dotPos >= 0) + return fullPath [dotPos] == T('.'); + } } return false; @@ -7199,7 +7181,7 @@ FileOutputStream::FileOutputStream (const File& f, } } - buffer = (char*) juce_malloc (jmax (bufferSize_, 16)); + buffer.malloc (jmax (bufferSize_, 16)); } FileOutputStream::~FileOutputStream() @@ -7207,7 +7189,6 @@ FileOutputStream::~FileOutputStream() flush(); juce_fileClose (fileHandle); - juce_free (buffer); } int64 FileOutputStream::getPosition() @@ -8538,6 +8519,8 @@ const URL URL::withFileToUpload (const String& parameterName, const File& fileToUpload, const String& mimeType) const { + jassert (mimeType.isNotEmpty()); // You need to supply a mime type! + URL u (*this); u.filesToUpload.set (parameterName, fileToUpload.getFullPathName()); u.mimeTypes.set (parameterName, mimeType); @@ -8569,7 +8552,7 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const throw() const String URL::removeEscapeChars (const String& s) { const int len = s.length(); - uint8* const resultUTF8 = (uint8*) juce_calloc (len * 4); + HeapBlock resultUTF8 (len * 4); uint8* r = resultUTF8; for (int i = 0; i < len; ++i) @@ -8591,9 +8574,7 @@ const String URL::removeEscapeChars (const String& s) *r++ = c; } - const String stringResult (String::fromUTF8 (resultUTF8)); - juce_free (resultUTF8); - return stringResult; + return String::fromUTF8 (resultUTF8); } const String URL::addEscapeChars (const String& s, const bool isParameter) @@ -8664,15 +8645,13 @@ BufferedInputStream::BufferedInputStream (InputStream* const source_, bufferSize = jmin (jmax (32, sourceSize), bufferSize); bufferStart = position; - buffer = (char*) juce_malloc (bufferSize); + buffer.malloc (bufferSize); } BufferedInputStream::~BufferedInputStream() throw() { if (deleteSourceWhenDestroyed) delete source; - - juce_free (buffer); } int64 BufferedInputStream::getTotalLength() @@ -8710,7 +8689,7 @@ void BufferedInputStream::ensureBuffered() && position >= bufferStart) { const int bytesToKeep = (int) (lastReadPos - position); - memmove (buffer, buffer + position - bufferStart, bytesToKeep); + memmove (buffer, buffer + (int) (position - bufferStart), bytesToKeep); bufferStart = position; @@ -8738,7 +8717,7 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) if (position >= bufferStart && position + maxBytesToRead <= lastReadPos) { - memcpy (destBuffer, buffer + (position - bufferStart), maxBytesToRead); + memcpy (destBuffer, buffer + (int) (position - bufferStart), maxBytesToRead); position += maxBytesToRead; return maxBytesToRead; @@ -8756,7 +8735,7 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) if (bytesAvailable > 0) { - memcpy (destBuffer, buffer + (position - bufferStart), bytesAvailable); + memcpy (destBuffer, buffer + (int) (position - bufferStart), bytesAvailable); maxBytesToRead -= bytesAvailable; bytesRead += bytesAvailable; position += bytesAvailable; @@ -8784,7 +8763,7 @@ const String BufferedInputStream::readString() { const int maxChars = (int) (lastReadPos - position); - const char* const src = buffer + (position - bufferStart); + const char* const src = buffer + (int) (position - bufferStart); for (int i = 0; i < maxChars; ++i) { @@ -12837,13 +12816,8 @@ bool StringArray::operator== (const StringArray& other) const throw() return false; for (int i = size(); --i >= 0;) - { - if (*(String*) other.strings.getUnchecked(i) - != *(String*) strings.getUnchecked(i)) - { + if (*other.strings.getUnchecked(i) != *strings.getUnchecked(i)) return false; - } - } return true; } @@ -12855,19 +12829,13 @@ bool StringArray::operator!= (const StringArray& other) const throw() void StringArray::clear() throw() { - for (int i = size(); --i >= 0;) - { - String* const s = (String*) strings.getUnchecked(i); - delete s; - } - strings.clear(); } const String& StringArray::operator[] (const int index) const throw() { if (((unsigned int) index) < (unsigned int) strings.size()) - return *(const String*) (strings.getUnchecked (index)); + return *strings.getUnchecked (index); return String::empty; } @@ -12904,22 +12872,18 @@ void StringArray::addArray (const StringArray& otherArray, numElementsToAdd = otherArray.size() - startIndex; while (--numElementsToAdd >= 0) - strings.add (new String (*(const String*) otherArray.strings.getUnchecked (startIndex++))); + strings.add (new String (*otherArray.strings.getUnchecked (startIndex++))); } void StringArray::set (const int index, const String& newString) throw() { - String* const s = (String*) strings [index]; + String* const s = strings [index]; if (s != 0) - { *s = newString; - } else if (index >= 0) - { add (newString); - } } bool StringArray::contains (const String& stringToLookFor, @@ -12928,13 +12892,13 @@ bool StringArray::contains (const String& stringToLookFor, if (ignoreCase) { for (int i = size(); --i >= 0;) - if (stringToLookFor.equalsIgnoreCase (*(const String*)(strings.getUnchecked(i)))) + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToLookFor)) return true; } else { for (int i = size(); --i >= 0;) - if (stringToLookFor == *(const String*)(strings.getUnchecked(i))) + if (stringToLookFor == *strings.getUnchecked(i)) return true; } @@ -12954,7 +12918,7 @@ int StringArray::indexOf (const String& stringToLookFor, { while (i < numElements) { - if (stringToLookFor.equalsIgnoreCase (*(const String*) strings.getUnchecked (i))) + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToLookFor)) return i; ++i; @@ -12964,7 +12928,7 @@ int StringArray::indexOf (const String& stringToLookFor, { while (i < numElements) { - if (stringToLookFor == *(const String*) strings.getUnchecked (i)) + if (stringToLookFor == *strings.getUnchecked (i)) return i; ++i; @@ -12976,13 +12940,7 @@ int StringArray::indexOf (const String& stringToLookFor, void StringArray::remove (const int index) throw() { - String* const s = (String*) strings [index]; - - if (s != 0) - { - strings.remove (index); - delete s; - } + strings.remove (index); } void StringArray::removeString (const String& stringToRemove, @@ -12991,14 +12949,14 @@ void StringArray::removeString (const String& stringToRemove, if (ignoreCase) { for (int i = size(); --i >= 0;) - if (stringToRemove.equalsIgnoreCase (*(const String*) strings.getUnchecked (i))) - remove (i); + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToRemove)) + strings.remove (i); } else { for (int i = size(); --i >= 0;) - if (stringToRemove == *(const String*) strings.getUnchecked (i)) - remove (i); + if (stringToRemove == *strings.getUnchecked (i)) + strings.remove (i); } } @@ -13007,14 +12965,14 @@ void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings) throw( if (removeWhitespaceStrings) { for (int i = size(); --i >= 0;) - if (! ((const String*) strings.getUnchecked(i))->containsNonWhitespaceChars()) - remove (i); + if (! strings.getUnchecked(i)->containsNonWhitespaceChars()) + strings.remove (i); } else { for (int i = size(); --i >= 0;) - if (((const String*) strings.getUnchecked(i))->isEmpty()) - remove (i); + if (strings.getUnchecked(i)->isEmpty()) + strings.remove (i); } } @@ -13022,7 +12980,7 @@ void StringArray::trim() throw() { for (int i = size(); --i >= 0;) { - String& s = *(String*) strings.getUnchecked(i); + String& s = *strings.getUnchecked(i); s = s.trim(); } } @@ -13078,13 +13036,13 @@ const String StringArray::joinIntoString (const String& separator, return String::empty; if (start == last - 1) - return *(const String*) strings.getUnchecked (start); + return *strings.getUnchecked (start); const int separatorLen = separator.length(); int charsNeeded = separatorLen * (last - start - 1); for (int i = start; i < last; ++i) - charsNeeded += ((const String*) strings.getUnchecked(i))->length(); + charsNeeded += strings.getUnchecked(i)->length(); String result; result.preallocateStorage (charsNeeded); @@ -13093,7 +13051,7 @@ const String StringArray::joinIntoString (const String& separator, while (start < last) { - const String& s = *(const String*) strings.getUnchecked (start); + const String& s = *strings.getUnchecked (start); const int len = s.length(); if (len > 0) @@ -13258,7 +13216,7 @@ void StringArray::removeDuplicates (const bool ignoreCase) throw() { for (int i = 0; i < size() - 1; ++i) { - const String& s = *(String*) strings.getUnchecked(i); + const String& s = *strings.getUnchecked(i); int nextIndex = i + 1; @@ -13269,7 +13227,7 @@ void StringArray::removeDuplicates (const bool ignoreCase) throw() if (nextIndex < 0) break; - remove (nextIndex); + strings.remove (nextIndex); } } } @@ -13281,7 +13239,7 @@ void StringArray::appendNumbersToDuplicates (const bool ignoreCase, { for (int i = 0; i < size() - 1; ++i) { - String& s = *(String*) strings.getUnchecked(i); + String& s = *strings.getUnchecked(i); int nextIndex = indexOf (s, ignoreCase, i + 1); @@ -15355,20 +15313,15 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo return 0; } -XmlElement** XmlElement::getChildElementsAsArray (const int num) const throw() +void XmlElement::getChildElementsAsArray (XmlElement** elems) const throw() { - XmlElement** const elems = new XmlElement* [num]; - XmlElement* e = firstChildElement; - int i = 0; while (e != 0) { - elems [i++] = e; + *elems++ = e; e = e->nextElement; } - - return elems; } void XmlElement::reorderChildElements (XmlElement** const elems, const int num) throw() @@ -15945,7 +15898,7 @@ ThreadPool::ThreadPool (const int numThreads_, { jassert (numThreads_ > 0); // not much point having one of these with no threads in it. - threads = (Thread**) juce_calloc (sizeof (Thread*) * numThreads); + threads.calloc (numThreads); for (int i = numThreads; --i >= 0;) threads[i] = new ThreadPoolThread (*this); @@ -15968,8 +15921,6 @@ ThreadPool::~ThreadPool() threads[i]->stopThread (500); delete threads[i]; } - - juce_free (threads); } void ThreadPool::addJob (ThreadPoolJob* const job) @@ -21403,7 +21354,7 @@ public: lastThreadId (0), dataHandle (0) { - bufferList = (AudioBufferList*) juce_calloc (256); + bufferList.calloc (256, 1); #ifdef WIN32 if (InitializeQTML (0) != noErr) @@ -21461,24 +21412,22 @@ public: if (err != noErr) return; - AudioChannelLayout* const qt_audio_channel_layout - = (AudioChannelLayout*) juce_calloc (output_layout_size); + HeapBlock qt_audio_channel_layout; + qt_audio_channel_layout.calloc (output_layout_size, 1); err = MovieAudioExtractionGetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, output_layout_size, qt_audio_channel_layout, 0); - qt_audio_channel_layout->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; err = MovieAudioExtractionSetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - sizeof (qt_audio_channel_layout), + output_layout_size, qt_audio_channel_layout); - juce_free (qt_audio_channel_layout); - err = MovieAudioExtractionGetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, @@ -21541,7 +21490,6 @@ public: DisposeMovie (movie); juce_free (bufferList->mBuffers[0].mData); - juce_free (bufferList); #if JUCE_MAC ExitMoviesOnThread (); @@ -21626,7 +21574,7 @@ private: Thread::ThreadID lastThreadId; MovieAudioExtractionRef extractor; AudioStreamBasicDescription inputStreamDesc; - AudioBufferList* bufferList; + HeapBlock bufferList; Handle dataHandle; /*OSErr readMovieStream (long offset, long size, void* dataPtr) @@ -21956,17 +21904,17 @@ public: bwavSize = length; // Broadcast-wav extension chunk.. - BWAVChunk* const bwav = (BWAVChunk*) juce_calloc (jmax (length + 1, (int) sizeof (BWAVChunk))); + HeapBlock bwav; + bwav.calloc (jmax (length + 1, (int) sizeof (BWAVChunk)), 1); input->read (bwav, length); bwav->copyTo (metadataValues); - juce_free (bwav); } else if (chunkType == chunkName ("smpl")) { - SMPLChunk* const smpl = (SMPLChunk*) juce_calloc (jmax (length + 1, (int) sizeof (SMPLChunk))); + HeapBlock smpl; + smpl.calloc (jmax (length + 1, (int) sizeof (SMPLChunk)), 1); input->read (smpl, length); smpl->copyTo (metadataValues, length); - juce_free (smpl); } else if (chunkEnd <= input->getPosition()) { @@ -25729,18 +25677,35 @@ AudioSampleBuffer::AudioSampleBuffer (const int numChannels_, jassert (numSamples >= 0); jassert (numChannels_ > 0); - allocatedBytes = numChannels * numSamples * sizeof (float) + 32; - allocatedData = (float*) juce_malloc (allocatedBytes); - channels = (float**) juce_malloc ((numChannels_ + 1) * sizeof (float*)); + allocateData(); +} - float* chan = allocatedData; - for (int i = 0; i < numChannels_; ++i) +AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) throw() + : numChannels (other.numChannels), + size (other.size) +{ + allocateData(); + const int numBytes = size * sizeof (float); + + for (int i = 0; i < numChannels; ++i) + memcpy (channels[i], other.channels[i], numBytes); +} + +void AudioSampleBuffer::allocateData() +{ + const int channelListSize = (numChannels + 1) * sizeof (float*); + allocatedBytes = numChannels * size * sizeof (float) + channelListSize + 32; + allocatedData.malloc (allocatedBytes); + channels = (float**) allocatedData; + + float* chan = (float*) (allocatedData + channelListSize); + for (int i = 0; i < numChannels; ++i) { channels[i] = chan; - chan += numSamples; + chan += size; } - channels [numChannels_] = 0; + channels [numChannels] = 0; } AudioSampleBuffer::AudioSampleBuffer (float** dataToReferTo, @@ -25748,45 +25713,41 @@ AudioSampleBuffer::AudioSampleBuffer (float** dataToReferTo, const int numSamples) throw() : numChannels (numChannels_), size (numSamples), - allocatedBytes (0), - allocatedData (0) + allocatedBytes (0) { jassert (numChannels_ > 0); - - // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) - if (numChannels_ < numElementsInArray (preallocatedChannelSpace)) - channels = (float**) preallocatedChannelSpace; - else - channels = (float**) juce_malloc ((numChannels_ + 1) * sizeof (float*)); - - for (int i = 0; i < numChannels_; ++i) - { - // you have to pass in the same number of valid pointers as numChannels - jassert (dataToReferTo[i] != 0); - - channels[i] = dataToReferTo[i]; - } - - channels [numChannels_] = 0; + allocateChannels (dataToReferTo); } void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, - const int numChannels_, - const int numSamples) throw() + const int newNumChannels, + const int newNumSamples) throw() { - jassert (numChannels_ > 0); + jassert (newNumChannels > 0); - juce_free (allocatedData); - allocatedData = 0; allocatedBytes = 0; + allocatedData.free(); - if (numChannels_ > numChannels) - channels = (float**) juce_realloc (channels, (numChannels_ + 1) * sizeof (float*)); + numChannels = newNumChannels; + size = newNumSamples; - numChannels = numChannels_; - size = numSamples; + allocateChannels (dataToReferTo); +} - for (int i = 0; i < numChannels_; ++i) +void AudioSampleBuffer::allocateChannels (float** const dataToReferTo) +{ + // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) + if (numChannels < numElementsInArray (preallocatedChannelSpace)) + { + channels = (float**) preallocatedChannelSpace; + } + else + { + allocatedData.malloc (numChannels + 1, sizeof (float*)); + channels = (float**) allocatedData; + } + + for (int i = 0; i < numChannels; ++i) { // you have to pass in the same number of valid pointers as numChannels jassert (dataToReferTo[i] != 0); @@ -25794,38 +25755,7 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, channels[i] = dataToReferTo[i]; } - channels [numChannels_] = 0; -} - -AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) throw() - : numChannels (other.numChannels), - size (other.size) -{ - channels = (float**) juce_malloc ((other.numChannels + 1) * sizeof (float*)); - - if (other.allocatedData != 0) - { - allocatedBytes = numChannels * size * sizeof (float) + 32; - allocatedData = (float*) juce_malloc (allocatedBytes); - - memcpy (allocatedData, other.allocatedData, allocatedBytes); - - float* chan = allocatedData; - for (int i = 0; i < numChannels; ++i) - { - channels[i] = chan; - chan += size; - } - - channels [numChannels] = 0; - } - else - { - allocatedData = 0; - allocatedBytes = 0; - - memcpy (channels, other.channels, sizeof (channels)); - } + channels [numChannels] = 0; } const AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) throw() @@ -25845,10 +25775,6 @@ const AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& AudioSampleBuffer::~AudioSampleBuffer() throw() { - juce_free (allocatedData); - - if (channels != (float**) preallocatedChannelSpace) - juce_free (channels); } void AudioSampleBuffer::setSize (const int newNumChannels, @@ -25861,26 +25787,29 @@ void AudioSampleBuffer::setSize (const int newNumChannels, if (newNumSamples != size || newNumChannels != numChannels) { - const int newTotalBytes = newNumChannels * newNumSamples * sizeof (float) + 32; + const int channelListSize = (newNumChannels + 1) * sizeof (float*); + const int newTotalBytes = (newNumChannels * newNumSamples * sizeof (float)) + channelListSize + 32; if (keepExistingContent) { - float* const newData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes) - : (float*) juce_malloc (newTotalBytes); + HeapBlock newData; + newData.allocate (newTotalBytes, clearExtraSpace); - const int sizeToCopy = sizeof (float) * jmin (newNumSamples, size); + const int numChansToCopy = jmin (numChannels, newNumChannels); + const int numBytesToCopy = sizeof (float) * jmin (newNumSamples, size); - for (int i = jmin (newNumChannels, numChannels); --i >= 0;) + float** const newChannels = (float**) newData; + float* newChan = (float*) (newData + channelListSize); + for (int i = 0; i < numChansToCopy; ++i) { - memcpy (newData + i * newNumSamples, - channels[i], - sizeToCopy); + memcpy (newChan, channels[i], numBytesToCopy); + newChannels[i] = newChan; + newChan += newNumSamples; } - juce_free (allocatedData); - - allocatedData = newData; + allocatedData.swapWith (newData); allocatedBytes = newTotalBytes; + channels = (float**) allocatedData; } else { @@ -25891,29 +25820,22 @@ void AudioSampleBuffer::setSize (const int newNumChannels, } else { - juce_free (allocatedData); - - allocatedData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes) - : (float*) juce_malloc (newTotalBytes); allocatedBytes = newTotalBytes; + allocatedData.allocate (newTotalBytes, clearExtraSpace); + channels = (float**) allocatedData; + } + + float* chan = (float*) (allocatedData + channelListSize); + for (int i = 0; i < newNumChannels; ++i) + { + channels[i] = chan; + chan += newNumSamples; } } - size = newNumSamples; - - if (newNumChannels > numChannels) - channels = (float**) juce_realloc (channels, (newNumChannels + 1) * sizeof (float*)); - - numChannels = newNumChannels; - - float* chan = allocatedData; - for (int i = 0; i < newNumChannels; ++i) - { - channels[i] = chan; - chan += size; - } - channels [newNumChannels] = 0; + size = newNumSamples; + numChannels = newNumChannels; } } @@ -26367,7 +26289,8 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer, } else { - chans[0] = (int*) juce_malloc (sizeof (int) * numSamples * 2); + HeapBlock tempBuffer (numSamples * 2); + chans[0] = tempBuffer; if (numChannels > 1) chans[1] = chans[0] + numSamples; @@ -26399,8 +26322,6 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer, } writer->write ((const int**) chans, numSamples); - - juce_free (chans[0]); } } } @@ -30321,7 +30242,7 @@ private: CriticalSection lock; bool initialised, wantsMidiMessages, wasPlaying; - AudioBufferList* outputBufferList; + HeapBlock outputBufferList; AudioTimeStamp timeStamp; AudioSampleBuffer* currentBuffer; @@ -30415,7 +30336,6 @@ AudioUnitPluginInstance::AudioUnitPluginInstance (const String& fileOrIdentifier initialised (false), wantsMidiMessages (false), audioUnit (0), - outputBufferList (0), currentBuffer (0) { try @@ -30459,8 +30379,6 @@ AudioUnitPluginInstance::~AudioUnitPluginInstance() audioUnit = 0; } } - - juce_free (outputBufferList); } bool AudioUnitPluginInstance::getComponentDescFromFile (const String& fileOrIdentifier) @@ -30639,8 +30557,7 @@ void AudioUnitPluginInstance::prepareToPlay (double sampleRate_, kAudioUnitScope_Output, 0, &stream, sizeof (stream)); - juce_free (outputBufferList); - outputBufferList = (AudioBufferList*) juce_calloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * (numOuts + 1)); + outputBufferList.calloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * (numOuts + 1), 1); outputBufferList->mNumberBuffers = numOuts; for (int i = numOuts; --i >= 0;) @@ -30664,8 +30581,7 @@ void AudioUnitPluginInstance::releaseResources() AudioUnitReset (audioUnit, kAudioUnitScope_Output, 0); AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0); - juce_free (outputBufferList); - outputBufferList = 0; + outputBufferList.free(); currentBuffer = 0; } } @@ -30935,7 +30851,8 @@ private: && AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, 0, &dataSize, &isWritable) == noErr) { - AudioUnitCocoaViewInfo* info = (AudioUnitCocoaViewInfo*) juce_calloc (dataSize); + HeapBlock info; + info.calloc (dataSize, 1); if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, 0, info, &dataSize) == noErr) @@ -30960,8 +30877,6 @@ private: CFRelease (info->mCocoaAUViewBundleLocation); } } - - juce_free (info); } if (createGenericViewIfNeeded && (pluginView == 0)) @@ -31645,7 +31560,7 @@ class VSTMidiEventList public: VSTMidiEventList() - : events (0), numEventsUsed (0), numEventsAllocated (0) + : numEventsUsed (0), numEventsAllocated (0) { } @@ -31740,9 +31655,9 @@ public: const int size = 20 + sizeof (VstEvent*) * numEventsNeeded; if (events == 0) - events = (VstEvents*) juce_calloc (size); + events.calloc (size, 1); else - events = (VstEvents*) juce_realloc (events, size); + events.realloc (size, 1); for (int i = numEventsAllocated; i < numEventsNeeded; ++i) { @@ -31772,14 +31687,13 @@ public: juce_free (e); } - juce_free (events); - events = 0; + events.free(); numEventsUsed = 0; numEventsAllocated = 0; } } - VstEvents* events; + HeapBlock events; private: int numEventsUsed, numEventsAllocated; @@ -32425,7 +32339,7 @@ private: MidiBuffer incomingMidi; VSTMidiEventList midiEventsToSend; VstTimeInfo vstHostTime; - float** channels; + HeapBlock channels; ReferenceCountedObjectPtr module; @@ -32462,7 +32376,6 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr initialDelay); - juce_free (channels); - channels = (float**) juce_calloc (sizeof (float*) * jmax (16, getNumOutputChannels() + 2, getNumInputChannels() + 2)); + channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); vstHostTime.tempo = 120.0; vstHostTime.timeSigNumerator = 4; @@ -32671,8 +32580,7 @@ void VSTPluginInstance::releaseResources() incomingMidi.clear(); midiEventsToSend.freeEvents(); - juce_free (channels); - channels = 0; + channels.free(); } void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, @@ -35410,7 +35318,7 @@ public: totalChans (jmax (1, totalChans_)), midiBufferToUse (midiBufferToUse_) { - channels = (float**) juce_calloc (sizeof (float*) * totalChans); + channels.calloc (totalChans); while (audioChannelsToUse.size() < totalChans) audioChannelsToUse.add (0); @@ -35418,7 +35326,6 @@ public: ~ProcessBufferOp() throw() { - juce_free (channels); } void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray & sharedMidiBuffers, const int numSamples) throw() @@ -35436,7 +35343,7 @@ public: private: Array audioChannelsToUse; - float** channels; + HeapBlock channels; int totalChans; int midiBufferToUse; @@ -49727,6 +49634,7 @@ void Slider::mouseDown (const MouseEvent& e) menuShown = true; PopupMenu m; + m.setLookAndFeel (&getLookAndFeel()); m.addItem (1, TRANS ("velocity-sensitive mode"), true, isVelocityBased); m.addSeparator(); @@ -53341,6 +53249,7 @@ void TextEditor::mouseDown (const MouseEvent& e) else { PopupMenu m; + m.setLookAndFeel (&getLookAndFeel()); addPopupMenuItems (m, &e); menuActive = true; @@ -53359,7 +53268,7 @@ void TextEditor::mouseDrag (const MouseEvent& e) { if (! (popupMenuEnabled && e.mods.isPopupMenu())) { - moveCursorTo (getTextIndexAt (e.x, e.y), true); + moveCursorTo (getTextIndexAt (e.x, e.y), true); } } } @@ -75159,7 +75068,7 @@ void MidiKeyboardComponent::resetAnyKeysInUse() void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y) { - float mousePositionVelocity; + float mousePositionVelocity = 0.0f; const int newNote = (mouseDragging || isMouseOver()) ? xyToNote (x, y, mousePositionVelocity) : -1; @@ -79409,7 +79318,7 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th return col1.interpolatedWith (col2, (integerPos - pos1) / (float) (pos2 - pos1)); } -PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, int& numEntries) const throw() +int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock & lookupTable) const throw() { #ifdef JUCE_DEBUG // trying to use the object without setting its co-ordinates? Have a careful read of @@ -79424,9 +79333,8 @@ PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, transform.transformPoint (tx2, ty2); const double distance = juce_hypot (tx1 - tx2, ty1 - ty2); - numEntries = jlimit (1, (numColours - 1) << 8, 3 * (int) distance); - - PixelARGB* const lookupTable = (PixelARGB*) juce_calloc (numEntries * sizeof (PixelARGB)); + const int numEntries = jlimit (1, (numColours - 1) << 8, 3 * (int) distance); + lookupTable.malloc (numEntries); if (numColours >= 2) { @@ -79462,7 +79370,7 @@ PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, jassertfalse // no colours specified! } - return lookupTable; + return numEntries; } bool ColourGradient::isOpaque() const throw() @@ -79812,10 +79720,10 @@ EdgeTable::EdgeTable (const Rectangle& bounds_, lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), needToCheckEmptinesss (true) { - table = (int*) juce_malloc ((bounds.getHeight() + 1) * lineStrideElements * sizeof (int)); + table.malloc ((bounds.getHeight() + 1) * lineStrideElements); int* t = table; - int i = 0; - for (i = bounds.getHeight(); --i >= 0;) + + for (int i = bounds.getHeight(); --i >= 0;) { *t = 0; t += lineStrideElements; @@ -79877,53 +79785,7 @@ EdgeTable::EdgeTable (const Rectangle& bounds_, } } - // Convert the table from relative windings to absolute levels.. - int* lineStart = table; - - for (i = bounds.getHeight(); --i >= 0;) - { - int* line = lineStart; - lineStart += lineStrideElements; - - int num = *line; - if (num == 0) - continue; - - int level = 0; - - if (path.isUsingNonZeroWinding()) - { - while (--num > 0) - { - line += 2; - level += *line; - int corrected = abs (level); - if (corrected >> 8) - corrected = 255; - - *line = corrected; - } - } - else - { - while (--num > 0) - { - line += 2; - level += *line; - int corrected = abs (level); - if (corrected >> 8) - { - corrected &= 511; - if (corrected >> 8) - corrected = 511 - corrected; - } - - *line = corrected; - } - } - - line[2] = 0; // force the last level to 0, just in case something went wrong in creating the table - } + sanitiseLevels (path.isUsingNonZeroWinding()); } EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw() @@ -79932,8 +79794,8 @@ EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw() lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), needToCheckEmptinesss (true) { - table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int)); - *table = 0; + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); + table[0] = 0; const int x1 = rectangleToAdd.getX() << 8; const int x2 = rectangleToAdd.getRight() << 8; @@ -79950,6 +79812,40 @@ EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw() } } +EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) throw() + : bounds (rectanglesToAdd.getBounds()), + maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), + lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), + needToCheckEmptinesss (true) +{ + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); + + int* t = table; + for (int i = bounds.getHeight(); --i >= 0;) + { + *t = 0; + t += lineStrideElements; + } + + for (RectangleList::Iterator iter (rectanglesToAdd); iter.next();) + { + const Rectangle* const r = iter.getRectangle(); + + const int x1 = r->getX() << 8; + const int x2 = r->getRight() << 8; + int y = r->getY() - bounds.getY(); + + for (int j = r->getHeight(); --j >= 0;) + { + addEdgePoint (x1, y, 255); + addEdgePoint (x2, y, -255); + ++y; + } + } + + sanitiseLevels (true); +} + EdgeTable::EdgeTable (const float x, const float y, const float w, const float h) throw() : bounds (Rectangle ((int) floorf (x), roundFloatToInt (y * 256.0f) >> 8, 2 + (int) w, 2 + (int) h)), maxEdgesPerLine (juce_edgeTableDefaultEdgesPerLine), @@ -79957,8 +79853,8 @@ EdgeTable::EdgeTable (const float x, const float y, const float w, const float h needToCheckEmptinesss (true) { jassert (w > 0 && h > 0); - table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int)); - *table = 0; + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); + table[0] = 0; const int x1 = roundFloatToInt (x * 256.0f); const int x2 = roundFloatToInt ((x + w) * 256.0f); @@ -80033,22 +79929,69 @@ EdgeTable::EdgeTable (const EdgeTable& other) throw() const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw() { - juce_free (table); - bounds = other.bounds; maxEdgesPerLine = other.maxEdgesPerLine; lineStrideElements = other.lineStrideElements; needToCheckEmptinesss = other.needToCheckEmptinesss; - const int tableSize = jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int); - table = (int*) juce_malloc (tableSize); + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); copyEdgeTableData (table, lineStrideElements, other.table, lineStrideElements, bounds.getHeight()); return *this; } EdgeTable::~EdgeTable() throw() { - juce_free (table); +} + +void EdgeTable::sanitiseLevels (const bool useNonZeroWinding) throw() +{ + // Convert the table from relative windings to absolute levels.. + int* lineStart = table; + + for (int i = bounds.getHeight(); --i >= 0;) + { + int* line = lineStart; + lineStart += lineStrideElements; + + int num = *line; + if (num == 0) + continue; + + int level = 0; + + if (useNonZeroWinding) + { + while (--num > 0) + { + line += 2; + level += *line; + int corrected = abs (level); + if (corrected >> 8) + corrected = 255; + + *line = corrected; + } + } + else + { + while (--num > 0) + { + line += 2; + level += *line; + int corrected = abs (level); + if (corrected >> 8) + { + corrected &= 511; + if (corrected >> 8) + corrected = 511 - corrected; + } + + *line = corrected; + } + } + + line[2] = 0; // force the last level to 0, just in case something went wrong in creating the table + } } void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw() @@ -80059,12 +80002,12 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw() jassert (bounds.getHeight() > 0); const int newLineStrideElements = maxEdgesPerLine * 2 + 1; - int* const newTable = (int*) juce_malloc (bounds.getHeight() * newLineStrideElements * sizeof (int)); + + HeapBlock newTable (bounds.getHeight() * newLineStrideElements); copyEdgeTableData (newTable, newLineStrideElements, table, lineStrideElements, bounds.getHeight()); - juce_free (table); - table = newTable; + table.swapWith (newTable); lineStrideElements = newLineStrideElements; } } @@ -82296,12 +82239,11 @@ public: maxY (srcData_.height - 1), scratchSize (2048) { - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } ~TransformedImageFillEdgeTableRenderer() throw() { - juce_free (scratchBuffer); } forcedinline void setEdgeTableYPos (const int newY) throw() @@ -82326,8 +82268,7 @@ public: if (width > scratchSize) { scratchSize = width; - juce_free (scratchBuffer); - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } SrcPixelType* span = scratchBuffer; @@ -82358,8 +82299,7 @@ public: if (width > scratchSize) { scratchSize = width; - juce_free (scratchBuffer); - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } uint8* mask = (uint8*) scratchBuffer; @@ -82667,7 +82607,7 @@ private: const int pixelOffsetInt, maxX, maxY; int y; DestPixelType* linePixels; - SrcPixelType* scratchBuffer; + HeapBlock scratchBuffer; int scratchSize; TransformedImageFillEdgeTableRenderer (const TransformedImageFillEdgeTableRenderer&); @@ -82708,13 +82648,10 @@ public: bool clipToRectangleList (const RectangleList& r) throw() { dupeEdgeTableIfMultiplyReferenced(); - RectangleList temp (r); - temp.offsetAll (xOffset, yOffset); - RectangleList totalArea (edgeTable->edgeTable.getMaximumBounds()); - totalArea.subtract (temp); - - for (RectangleList::Iterator i (totalArea); i.next();) - edgeTable->edgeTable.excludeRectangle (*i.getRectangle()); + RectangleList offsetList (r); + offsetList.offsetAll (xOffset, yOffset); + EdgeTable e2 (offsetList); + edgeTable->edgeTable.clipToEdgeTable (e2); return ! edgeTable->edgeTable.isEmpty(); } @@ -82758,8 +82695,8 @@ public: transform = AffineTransform::identity; } - int numLookupEntries; - PixelARGB* const lookupTable = g2.createLookupTable (transform, numLookupEntries); + HeapBlock lookupTable; + const int numLookupEntries = g2.createLookupTable (transform, lookupTable); jassert (numLookupEntries > 0); switch (image.getFormat()) @@ -82768,8 +82705,6 @@ public: case Image::RGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) 0); break; default: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) 0); break; } - - juce_free (lookupTable); } else if (fillType.isTiledImage()) { @@ -89693,10 +89628,9 @@ void Path::writePathToStream (OutputStream& dest) const const String Path::toString() const { - String s; - s.preallocateStorage (numElements * 4); + MemoryOutputStream s (2048, 2048); if (! useNonZeroWinding) - s << T("a "); + s << "a "; int i = 0; float lastMarker = 0.0f; @@ -89704,38 +89638,38 @@ const String Path::toString() const while (i < numElements) { const float marker = data.elements [i++]; - tchar markerChar = 0; + char markerChar = 0; int numCoords = 0; if (marker == moveMarker) { - markerChar = T('m'); + markerChar = 'm'; numCoords = 2; } else if (marker == lineMarker) { - markerChar = T('l'); + markerChar = 'l'; numCoords = 2; } else if (marker == quadMarker) { - markerChar = T('q'); + markerChar = 'q'; numCoords = 4; } else if (marker == cubicMarker) { - markerChar = T('c'); + markerChar = 'c'; numCoords = 6; } else { jassert (marker == closeSubPathMarker); - markerChar = T('z'); + markerChar = 'z'; } if (marker != lastMarker) { - s << markerChar << T(' '); + s << markerChar << ' '; lastMarker = marker; } @@ -89743,17 +89677,28 @@ const String Path::toString() const { String n (data.elements [i++], 3); - while (n.endsWithChar (T('0'))) - n = n.dropLastCharacters (1); + if (n.endsWithChar (T('0'))) + { + do + { + n = n.dropLastCharacters (1); + } while (n.endsWithChar (T('0'))); - if (n.endsWithChar (T('.'))) - n = n.dropLastCharacters (1); + if (n.endsWithChar (T('.'))) + n = n.dropLastCharacters (1); + } - s << n << T(' '); + s << n << ' '; } } - return s.trimEnd(); + const char* const result = (const char*) s.getData(); + int len = s.getDataSize(); + + while (len > 0 && CharacterFunctions::isWhitespace (result [len - 1])) + --len; + + return String (result, len); } static const String nextToken (const tchar*& t) @@ -89939,17 +89884,16 @@ PathFlatteningIterator::PathFlatteningIterator (const Path& path_, tolerence (tolerence_ * tolerence_), subPathCloseX (0), subPathCloseY (0), + stackBase (32), index (0), stackSize (32) { - stackBase = (float*) juce_malloc (stackSize * sizeof (float)); isIdentityTransform = transform.isIdentity(); stackPos = stackBase; } PathFlatteningIterator::~PathFlatteningIterator() throw() { - juce_free (stackBase); } bool PathFlatteningIterator::next() throw() @@ -90050,7 +89994,7 @@ bool PathFlatteningIterator::next() throw() if (offset >= stackSize - 10) { stackSize <<= 1; - stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float)); + stackBase.realloc (stackSize); stackPos = stackBase + offset; } @@ -90100,7 +90044,7 @@ bool PathFlatteningIterator::next() throw() if (offset >= stackSize - 16) { stackSize <<= 1; - stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float)); + stackBase.realloc (stackSize); stackPos = stackBase + offset; } @@ -92093,10 +92037,9 @@ Image::Image (const PixelFormat format_, pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1); lineStride = (pixelStride * jmax (1, imageWidth_) + 3) & ~3; - const int dataSize = lineStride * jmax (1, imageHeight_); - imageData = (uint8*) (clearImage ? juce_calloc (dataSize) - : juce_malloc (dataSize)); + imageDataAllocated.allocate (lineStride * jmax (1, imageHeight_), clearImage); + imageData = imageDataAllocated; } Image::Image (const Image& other) @@ -92106,9 +92049,9 @@ Image::Image (const Image& other) { pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1); lineStride = (pixelStride * jmax (1, imageWidth) + 3) & ~3; - const int dataSize = lineStride * jmax (1, imageHeight); - imageData = (uint8*) juce_malloc (dataSize); + imageDataAllocated.malloc (lineStride * jmax (1, imageHeight)); + imageData = imageDataAllocated; BitmapData srcData (other, 0, 0, imageWidth, imageHeight); setPixelData (0, 0, imageWidth, imageHeight, srcData.data, srcData.lineStride); @@ -92116,7 +92059,6 @@ Image::Image (const Image& other) Image::~Image() { - juce_free (imageData); } LowLevelGraphicsContext* Image::createLowLevelContext() @@ -92729,22 +92671,14 @@ END_JUCE_NAMESPACE BEGIN_JUCE_NAMESPACE ImageConvolutionKernel::ImageConvolutionKernel (const int size_) throw() - : size (size_) + : values (size_ * size_), + size (size_) { - values = new float* [size]; - - for (int i = size; --i >= 0;) - values[i] = new float [size]; - clear(); } ImageConvolutionKernel::~ImageConvolutionKernel() throw() { - for (int i = size; --i >= 0;) - delete[] values[i]; - - delete[] values; } void ImageConvolutionKernel::setKernelValue (const int x, @@ -92754,7 +92688,7 @@ void ImageConvolutionKernel::setKernelValue (const int x, if (((unsigned int) x) < (unsigned int) size && ((unsigned int) y) < (unsigned int) size) { - values[x][y] = value; + values [x + y * size] = value; } else { @@ -92764,27 +92698,24 @@ void ImageConvolutionKernel::setKernelValue (const int x, void ImageConvolutionKernel::clear() throw() { - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - values[x][y] = 0; + for (int i = size * size; --i >= 0;) + values[i] = 0; } void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum) throw() { double currentTotal = 0.0; - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - currentTotal += values[x][y]; + for (int i = size * size; --i >= 0;) + currentTotal += values[i]; rescaleAllValues ((float) (desiredTotalSum / currentTotal)); } void ImageConvolutionKernel::rescaleAllValues (const float multiplier) throw() { - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - values[x][y] *= multiplier; + for (int i = size * size; --i >= 0;) + values[i] *= multiplier; } void ImageConvolutionKernel::createGaussianBlur (const float radius) throw() @@ -92799,7 +92730,7 @@ void ImageConvolutionKernel::createGaussianBlur (const float radius) throw() const int cx = x - centre; const int cy = y - centre; - values[x][y] = (float) exp (radiusFactor * (cx * cx + cy * cy)); + values [x + y * size] = (float) exp (radiusFactor * (cx * cx + cy * cy)); } } @@ -92884,7 +92815,7 @@ void ImageConvolutionKernel::applyToImage (Image& destImage, if (sx >= 0) { - const float kernelMult = values[xx][yy]; + const float kernelMult = values [xx + yy * size]; c1 += kernelMult * *src++; c2 += kernelMult * *src++; c3 += kernelMult * *src++; @@ -92939,7 +92870,7 @@ void ImageConvolutionKernel::applyToImage (Image& destImage, if (sx >= 0) { - const float kernelMult = values[xx][yy]; + const float kernelMult = values [xx + yy * size]; c1 += kernelMult * *src++; c2 += kernelMult * *src++; c3 += kernelMult * *src++; @@ -95336,7 +95267,7 @@ using namespace zlibNamespace; class GZIPCompressorHelper { private: - z_stream* stream; + HeapBlock stream; uint8* data; int dataSize, compLevel, strategy; bool setParams; @@ -95353,7 +95284,7 @@ public: finished (false), shouldFinish (false) { - stream = (z_stream*) juce_calloc (sizeof (z_stream)); + stream.calloc (1); if (deflateInit2 (stream, compLevel, @@ -95362,18 +95293,14 @@ public: 8, strategy) != Z_OK) { - juce_free (stream); - stream = 0; + stream.free(); } } ~GZIPCompressorHelper() { if (stream != 0) - { deflateEnd (stream); - juce_free (stream); - } } bool needsInput() const throw() @@ -95428,14 +95355,14 @@ GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const dest const bool deleteDestStream_, const bool noWrap) : destStream (destStream_), - deleteDestStream (deleteDestStream_) + deleteDestStream (deleteDestStream_), + buffer (gzipCompBufferSize) { if (compressionLevel < 1 || compressionLevel > 9) compressionLevel = -1; helper = new GZIPCompressorHelper (compressionLevel, noWrap); - buffer = (uint8*) juce_malloc (gzipCompBufferSize); } GZIPCompressorOutputStream::~GZIPCompressorOutputStream() @@ -95445,8 +95372,6 @@ GZIPCompressorOutputStream::~GZIPCompressorOutputStream() GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper; delete h; - juce_free (buffer); - if (deleteDestStream) delete destStream; } @@ -102740,7 +102665,7 @@ using namespace zlibNamespace; class GZIPDecompressHelper { private: - z_stream* stream; + HeapBlock stream; uint8* data; int dataSize; @@ -102754,13 +102679,12 @@ public: needsDictionary (false), error (false) { - stream = (z_stream*) juce_calloc (sizeof (z_stream)); + stream.calloc (1); if (inflateInit2 (stream, (noWrap) ? -MAX_WBITS : MAX_WBITS) != Z_OK) { - juce_free (stream); - stream = 0; + stream.free(); error = true; finished = true; } @@ -102769,10 +102693,7 @@ public: ~GZIPDecompressHelper() throw() { if (stream != 0) - { inflateEnd (stream); - juce_free (stream); - } } bool needsInput() const throw() { return dataSize <= 0; } @@ -102835,16 +102756,14 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou isEof (false), activeBufferSize (0), originalSourcePos (sourceStream_->getPosition()), - currentPos (0) + currentPos (0), + buffer (gzipDecompBufferSize) { - buffer = (uint8*) juce_malloc (gzipDecompBufferSize); helper = new GZIPDecompressHelper (noWrap_); } GZIPDecompressorInputStream::~GZIPDecompressorInputStream() { - juce_free (buffer); - if (deleteSourceWhenDestroyed) delete sourceStream; @@ -208655,7 +208574,8 @@ bool juce_writeJPEGImageToStream (const Image& image, jpegCompStruct.dest = &dest; dest.output = &out; - dest.buffer = (char*) juce_malloc (bufferSize); + HeapBlock tempBuffer (bufferSize); + dest.buffer = (char*) tempBuffer; dest.next_output_byte = (JOCTET*) dest.buffer; dest.free_in_buffer = bufferSize; dest.init_destination = jpegWriteInit; @@ -208711,8 +208631,6 @@ bool juce_writeJPEGImageToStream (const Image& image, jpeg_finish_compress (&jpegCompStruct); jpeg_destroy_compress (&jpegCompStruct); - juce_free (dest.buffer); - out.flush(); return true; @@ -234224,17 +234142,17 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() || pngInfoStruct->num_trans > 0; // Load the image into a temp buffer in the pnglib format.. - uint8* const tempBuffer = (uint8*) juce_malloc (height * (width << 2)); + HeapBlock tempBuffer (height * (width << 2)); - png_bytepp rows = (png_bytepp) juce_malloc (sizeof (png_bytep) * height); - int y; - for (y = (int) height; --y >= 0;) - rows[y] = (png_bytep) (tempBuffer + (width << 2) * y); + { + HeapBlock rows (height); + for (int y = (int) height; --y >= 0;) + rows[y] = (png_bytep) (tempBuffer + (width << 2) * y); - png_read_image (pngReadStruct, rows); - png_read_end (pngReadStruct, pngInfoStruct); + png_read_image (pngReadStruct, rows); + png_read_end (pngReadStruct, pngInfoStruct); + } - juce_free (rows); png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0); // now convert the data to a juce image format.. @@ -234247,7 +234165,7 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() uint8* srcRow = tempBuffer; uint8* destRow = destData.data; - for (y = 0; y < (int) height; ++y) + for (int y = 0; y < (int) height; ++y) { const uint8* src = srcRow; srcRow += (width << 2); @@ -234274,8 +234192,6 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() } } } - - juce_free (tempBuffer); } return image; @@ -234318,7 +234234,7 @@ bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw() PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - png_bytep rowData = (png_bytep) juce_malloc (width * 4 * sizeof (png_byte)); + HeapBlock rowData (width * 4); png_color_8 sig_bit; sig_bit.red = 8; @@ -234367,8 +234283,6 @@ bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw() png_write_rows (pngWriteStruct, &rowData, 1); } - juce_free (rowData); - png_write_end (pngWriteStruct, pngInfoStruct); png_destroy_write_struct (&pngWriteStruct, &pngInfoStruct); @@ -235724,7 +235638,8 @@ const String File::getVersion() const throw() DWORD handle = 0; DWORD bufferSize = GetFileVersionInfoSize (getFullPathName(), &handle); - void* buffer = juce_calloc (bufferSize); + HeapBlock buffer; + buffer.calloc (bufferSize); if (GetFileVersionInfo (getFullPathName(), 0, bufferSize, buffer)) { @@ -235741,7 +235656,6 @@ const String File::getVersion() const throw() } } - juce_free (buffer); return result; } @@ -237149,7 +237063,6 @@ public: { DeleteDC (hdc); DeleteObject (hBitmap); - imageData = 0; // to stop the base class freeing this } void blitToWindow (HWND hwnd, HDC dc, const bool transparent, @@ -238733,408 +238646,408 @@ public: private: LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) { + if (isValidPeer (this)) { - if (isValidPeer (this)) + switch (message) { - switch (message) - { - case WM_NCHITTEST: - if (hasTitleBar()) - break; - return HTCLIENT; + case WM_NCHITTEST: + if ((styleFlags & windowIgnoresMouseClicks) != 0) + return HTTRANSPARENT; - case WM_PAINT: + if (hasTitleBar()) + break; + + return HTCLIENT; + + case WM_PAINT: + handlePaintMessage(); + return 0; + + case WM_NCPAINT: + if (wParam != 1) handlePaintMessage(); - return 0; - case WM_NCPAINT: - if (wParam != 1) - handlePaintMessage(); + if (hasTitleBar()) + break; - if (hasTitleBar()) - break; + return 0; - return 0; + case WM_ERASEBKGND: + case WM_NCCALCSIZE: + if (hasTitleBar()) + break; - case WM_ERASEBKGND: - case WM_NCCALCSIZE: - if (hasTitleBar()) - break; + return 1; - return 1; + case WM_MOUSEMOVE: + doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); + return 0; - case WM_MOUSEMOVE: - doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); - return 0; + case WM_MOUSELEAVE: + doMouseExit(); + return 0; - case WM_MOUSELEAVE: - doMouseExit(); - return 0; + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); + return 0; - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); - return 0; + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); + return 0; - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); - return 0; + case WM_CAPTURECHANGED: + doCaptureChanged(); + return 0; - case WM_CAPTURECHANGED: - doCaptureChanged(); - return 0; + case WM_NCMOUSEMOVE: + if (hasTitleBar()) + break; - case WM_NCMOUSEMOVE: - if (hasTitleBar()) - break; + return 0; - return 0; + case 0x020A: /* WM_MOUSEWHEEL */ + doMouseWheel (wParam, true); + return 0; - case 0x020A: /* WM_MOUSEWHEEL */ - doMouseWheel (wParam, true); - return 0; + case 0x020E: /* WM_MOUSEHWHEEL */ + doMouseWheel (wParam, false); + return 0; - case 0x020E: /* WM_MOUSEHWHEEL */ - doMouseWheel (wParam, false); - return 0; + case WM_WINDOWPOSCHANGING: + if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + { + WINDOWPOS* const wp = (WINDOWPOS*) lParam; - case WM_WINDOWPOSCHANGING: - if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) { - WINDOWPOS* const wp = (WINDOWPOS*) lParam; - - if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) + if (constrainer != 0) { - if (constrainer != 0) - { - const Rectangle current (component->getX() - windowBorder.getLeft(), - component->getY() - windowBorder.getTop(), - component->getWidth() + windowBorder.getLeftAndRight(), - component->getHeight() + windowBorder.getTopAndBottom()); + const Rectangle current (component->getX() - windowBorder.getLeft(), + component->getY() - windowBorder.getTop(), + component->getWidth() + windowBorder.getLeftAndRight(), + component->getHeight() + windowBorder.getTopAndBottom()); - constrainer->checkBounds (wp->x, wp->y, wp->cx, wp->cy, - current, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - wp->y != current.getY() && wp->y + wp->cy == current.getBottom(), - wp->x != current.getX() && wp->x + wp->cx == current.getRight(), - wp->y == current.getY() && wp->y + wp->cy != current.getBottom(), - wp->x == current.getX() && wp->x + wp->cx != current.getRight()); - } + constrainer->checkBounds (wp->x, wp->y, wp->cx, wp->cy, + current, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + wp->y != current.getY() && wp->y + wp->cy == current.getBottom(), + wp->x != current.getX() && wp->x + wp->cx == current.getRight(), + wp->y == current.getY() && wp->y + wp->cy != current.getBottom(), + wp->x == current.getX() && wp->x + wp->cx != current.getRight()); } } + } + return 0; + + case WM_WINDOWPOSCHANGED: + handleMovedOrResized(); + + if (dontRepaint) + break; // needed for non-accelerated openGL windows to draw themselves correctly.. + + return 0; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (doKeyDown (wParam)) return 0; - case WM_WINDOWPOSCHANGED: - handleMovedOrResized(); + break; - if (dontRepaint) - break; // needed for non-accelerated openGL windows to draw themselves correctly.. - else - return 0; - - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if (doKeyDown (wParam)) - return 0; - - break; - - case WM_KEYUP: - case WM_SYSKEYUP: - if (doKeyUp (wParam)) - return 0; - - break; - - case WM_CHAR: - if (doKeyChar ((int) wParam, lParam)) - return 0; - - break; - - case WM_APPCOMMAND: - if (doAppCommand (lParam)) - return TRUE; - - break; - - case WM_SETFOCUS: - updateKeyModifiers(); - handleFocusGain(); - break; - - case WM_KILLFOCUS: - if (hasCreatedCaret) - { - hasCreatedCaret = false; - DestroyCaret(); - } - - handleFocusLoss(); - break; - - case WM_ACTIVATEAPP: - // Windows does weird things to process priority when you swap apps, - // so this forces an update when the app is brought to the front - if (wParam != FALSE) - juce_repeatLastProcessPriority(); - else - Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus - - juce_CheckCurrentlyFocusedTopLevelWindow(); - modifiersAtLastCallback = -1; + case WM_KEYUP: + case WM_SYSKEYUP: + if (doKeyUp (wParam)) return 0; - case WM_ACTIVATE: - if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE) - { - modifiersAtLastCallback = -1; - updateKeyModifiers(); - - if (isMinimised()) - { - component->repaint(); - handleMovedOrResized(); - - if (! isValidMessageListener()) - return 0; - } - - if (LOWORD (wParam) == WA_CLICKACTIVE - && component->isCurrentlyBlockedByAnotherModalComponent()) - { - int mx, my; - component->getMouseXYRelative (mx, my); - Component* const underMouse = component->getComponentAt (mx, my); - - if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent()) - Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); - - return 0; - } - - handleBroughtToFront(); - - if (component->isCurrentlyBlockedByAnotherModalComponent()) - Component::getCurrentlyModalComponent()->toFront (true); - - return 0; - } - - break; - - case WM_NCACTIVATE: - // while a temporary window is being shown, prevent Windows from deactivating the - // title bars of our main windows. - if (wParam == 0 && ! shouldDeactivateTitleBar) - wParam = TRUE; // change this and let it get passed to the DefWindowProc. - - break; - - case WM_MOUSEACTIVATE: - if (! component->getMouseClickGrabsKeyboardFocus()) - return MA_NOACTIVATE; - - break; - - case WM_SHOWWINDOW: - if (wParam != 0) - handleBroughtToFront(); - - break; - - case WM_CLOSE: - if (! component->isCurrentlyBlockedByAnotherModalComponent()) - handleUserClosingWindow(); + break; + case WM_CHAR: + if (doKeyChar ((int) wParam, lParam)) return 0; - case WM_QUIT: - if (JUCEApplication::getInstance() != 0) - JUCEApplication::getInstance()->systemRequestedQuit(); - return 0; + break; - case WM_QUERYENDSESSION: - if (JUCEApplication::getInstance() != 0) - { - JUCEApplication::getInstance()->systemRequestedQuit(); - return MessageManager::getInstance()->hasStopMessageBeenSent(); - } + case WM_APPCOMMAND: + if (doAppCommand (lParam)) return TRUE; - case WM_TRAYNOTIFY: + break; + + case WM_SETFOCUS: + updateKeyModifiers(); + handleFocusGain(); + break; + + case WM_KILLFOCUS: + if (hasCreatedCaret) + { + hasCreatedCaret = false; + DestroyCaret(); + } + + handleFocusLoss(); + break; + + case WM_ACTIVATEAPP: + // Windows does weird things to process priority when you swap apps, + // so this forces an update when the app is brought to the front + if (wParam != FALSE) + juce_repeatLastProcessPriority(); + else + Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus + + juce_CheckCurrentlyFocusedTopLevelWindow(); + modifiersAtLastCallback = -1; + return 0; + + case WM_ACTIVATE: + if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE) + { + modifiersAtLastCallback = -1; + updateKeyModifiers(); + + if (isMinimised()) + { + component->repaint(); + handleMovedOrResized(); + + if (! isValidMessageListener()) + return 0; + } + + if (LOWORD (wParam) == WA_CLICKACTIVE + && component->isCurrentlyBlockedByAnotherModalComponent()) + { + int mx, my; + component->getMouseXYRelative (mx, my); + Component* const underMouse = component->getComponentAt (mx, my); + + if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent()) + Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); + + return 0; + } + + handleBroughtToFront(); + if (component->isCurrentlyBlockedByAnotherModalComponent()) + Component::getCurrentlyModalComponent()->toFront (true); + + return 0; + } + + break; + + case WM_NCACTIVATE: + // while a temporary window is being shown, prevent Windows from deactivating the + // title bars of our main windows. + if (wParam == 0 && ! shouldDeactivateTitleBar) + wParam = TRUE; // change this and let it get passed to the DefWindowProc. + + break; + + case WM_MOUSEACTIVATE: + if (! component->getMouseClickGrabsKeyboardFocus()) + return MA_NOACTIVATE; + + break; + + case WM_SHOWWINDOW: + if (wParam != 0) + handleBroughtToFront(); + + break; + + case WM_CLOSE: + if (! component->isCurrentlyBlockedByAnotherModalComponent()) + handleUserClosingWindow(); + + return 0; + + case WM_QUIT: + if (JUCEApplication::getInstance() != 0) + JUCEApplication::getInstance()->systemRequestedQuit(); + return 0; + + case WM_QUERYENDSESSION: + if (JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->systemRequestedQuit(); + return MessageManager::getInstance()->hasStopMessageBeenSent(); + } + return TRUE; + + case WM_TRAYNOTIFY: + if (component->isCurrentlyBlockedByAnotherModalComponent()) + { + if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN + || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) { - if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN - || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) - { - Component* const current = Component::getCurrentlyModalComponent(); + Component* const current = Component::getCurrentlyModalComponent(); - if (current != 0) - current->inputAttemptWhenModal(); - } + if (current != 0) + current->inputAttemptWhenModal(); } - else + } + else + { + const int oldModifiers = currentModifiers; + + MouseEvent e (0, 0, ModifierKeys::getCurrentModifiersRealtime(), component, + getMouseEventTime(), 0, 0, getMouseEventTime(), 1, false); + + if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) + e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); + else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) + e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier); + + if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) { - const int oldModifiers = currentModifiers; + SetFocus (hwnd); + SetForegroundWindow (hwnd); - MouseEvent e (0, 0, ModifierKeys::getCurrentModifiersRealtime(), component, - getMouseEventTime(), 0, 0, getMouseEventTime(), 1, false); - - if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) - e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); - else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) - e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier); - - if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) - { - SetFocus (hwnd); - SetForegroundWindow (hwnd); - - component->mouseDown (e); - } - else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) - { - e.mods = ModifierKeys (oldModifiers); - component->mouseUp (e); - } - else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) - { - e.mods = ModifierKeys (oldModifiers); - component->mouseDoubleClick (e); - } - else if (lParam == WM_MOUSEMOVE) - { - component->mouseMove (e); - } + component->mouseDown (e); } + else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) + { + e.mods = ModifierKeys (oldModifiers); + component->mouseUp (e); + } + else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) + { + e.mods = ModifierKeys (oldModifiers); + component->mouseDoubleClick (e); + } + else if (lParam == WM_MOUSEMOVE) + { + component->mouseMove (e); + } + } + + break; + + case WM_SYNCPAINT: + return 0; + + case WM_PALETTECHANGED: + InvalidateRect (h, 0, 0); + break; + + case WM_DISPLAYCHANGE: + InvalidateRect (h, 0, 0); + createPaletteIfNeeded = true; + // intentional fall-through... + case WM_SETTINGCHANGE: // note the fall-through in the previous case! + doSettingChange(); + break; + + case WM_INITMENU: + if (! hasTitleBar()) + { + if (isFullScreen()) + { + EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); + } + else if (! isMinimised()) + { + EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + } + } + break; + + case WM_SYSCOMMAND: + switch (wParam & 0xfff0) + { + case SC_CLOSE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + if (hasTitleBar()) + { + PostMessage (h, WM_CLOSE, 0, 0); + return 0; + } + break; + + case SC_KEYMENU: + // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very + // obscure situations that can arise if a modal loop is started from an alt-key + // keypress). + + if (hasTitleBar() && h == GetCapture()) + ReleaseCapture(); break; - case WM_SYNCPAINT: + case SC_MAXIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + setFullScreen (true); return 0; - case WM_PALETTECHANGED: - InvalidateRect (h, 0, 0); - break; + case SC_MINIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; - case WM_DISPLAYCHANGE: - InvalidateRect (h, 0, 0); - createPaletteIfNeeded = true; - // intentional fall-through... - case WM_SETTINGCHANGE: // note the fall-through in the previous case! - doSettingChange(); - break; - - case WM_INITMENU: if (! hasTitleBar()) + { + setMinimised (true); + return 0; + } + break; + + case SC_RESTORE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + if (hasTitleBar()) { if (isFullScreen()) { - EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); - } - else if (! isMinimised()) - { - EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + setFullScreen (false); + return 0; } } - break; - - case WM_SYSCOMMAND: - switch (wParam & 0xfff0) + else { - case SC_CLOSE: - if (sendInputAttemptWhenModalMessage()) - return 0; + if (isMinimised()) + setMinimised (false); + else if (isFullScreen()) + setFullScreen (false); - if (hasTitleBar()) - { - PostMessage (h, WM_CLOSE, 0, 0); - return 0; - } - break; - - case SC_KEYMENU: - // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very - // obscure situations that can arise if a modal loop is started from an alt-key - // keypress). - - if (hasTitleBar() && h == GetCapture()) - ReleaseCapture(); - - break; - - case SC_MAXIMIZE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - setFullScreen (true); return 0; - - case SC_MINIMIZE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - if (! hasTitleBar()) - { - setMinimised (true); - return 0; - } - break; - - case SC_RESTORE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - if (hasTitleBar()) - { - if (isFullScreen()) - { - setFullScreen (false); - return 0; - } - } - else - { - if (isMinimised()) - setMinimised (false); - else if (isFullScreen()) - setFullScreen (false); - - return 0; - } - - break; } break; + } - case WM_NCLBUTTONDOWN: - case WM_NCRBUTTONDOWN: - case WM_NCMBUTTONDOWN: - sendInputAttemptWhenModalMessage(); - break; + break; - //case WM_IME_STARTCOMPOSITION; - // return 0; + case WM_NCLBUTTONDOWN: + case WM_NCRBUTTONDOWN: + case WM_NCMBUTTONDOWN: + sendInputAttemptWhenModalMessage(); + break; - case WM_GETDLGCODE: - return DLGC_WANTALLKEYS; + //case WM_IME_STARTCOMPOSITION; + // return 0; - default: - break; - } + case WM_GETDLGCODE: + return DLGC_WANTALLKEYS; + + default: + break; } } - // (the message manager lock exits before calling this, to avoid deadlocks if - // this calls into non-juce windows) return DefWindowProc (h, message, wParam, lParam); } @@ -239534,8 +239447,9 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot else { const int stride = (maxW + 7) >> 3; - uint8* const andPlane = (uint8*) juce_calloc (stride * maxH); - uint8* const xorPlane = (uint8*) juce_calloc (stride * maxH); + HeapBlock andPlane, xorPlane; + andPlane.calloc (stride * maxH); + xorPlane.calloc (stride * maxH); int index = 0; for (int y = 0; y < maxH; ++y) @@ -239556,9 +239470,6 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot } cursorH = CreateCursor (0, hotspotX, hotspotY, maxW, maxH, andPlane, xorPlane); - - juce_free (andPlane); - juce_free (xorPlane); } delete newIm; @@ -240106,7 +240017,7 @@ class FontDCHolder : private DeletedAtShutdown public: FontDCHolder() throw() - : dc (0), kps (0), numKPs (0), size (0), + : dc (0), numKPs (0), size (0), bold (false), italic (false) { } @@ -240117,7 +240028,6 @@ public: { DeleteDC (dc); DeleteObject (fontH); - juce_free (kps); } clearSingletonInstance(); @@ -240138,8 +240048,7 @@ public: { DeleteDC (dc); DeleteObject (fontH); - juce_free (kps); - kps = 0; + kps.free(); } fontH = 0; @@ -240201,7 +240110,7 @@ public: if (kps == 0) { numKPs = GetKerningPairs (dc, 0, 0); - kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs); + kps.calloc (numKPs); GetKerningPairs (dc, numKPs, kps); } @@ -240214,7 +240123,7 @@ private: HFONT fontH; HDC dc; String fontName; - KERNINGPAIR* kps; + HeapBlock kps; int numKPs, size; bool bold, italic; @@ -240277,7 +240186,7 @@ public: if (bufSize > 0) { - char* const data = (char*) juce_malloc (bufSize); + HeapBlock data (bufSize); GetGlyphOutline (dc, character, GGO_NATIVE, &gm, bufSize, data, &identityMatrix); @@ -240345,8 +240254,6 @@ public: glyphPath.closeSubPath(); } - - juce_free (data); } addGlyph (character, glyphPath, gm.gmCellIncX / height); @@ -241582,15 +241489,11 @@ static CFStringRef juceStringToCFString (const String& s) const int len = s.length(); const juce_wchar* const t = (const juce_wchar*) s; - UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4); - + HeapBlock temp (len + 2); for (int i = 0; i <= len; ++i) temp[i] = t[i]; - CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); - juce_free (temp); - - return result; + return CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); } static bool openMovie (QTNewMoviePropertyElement* props, int prop, Movie& movie) @@ -244840,7 +244743,7 @@ bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples) hr = info->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4)); - byte* const buffer = (byte*) juce_malloc (bytesPerBlock); + HeapBlock buffer (bytesPerBlock); AudioSampleBuffer sourceBuffer (2, samplesPerBlock); int samplesDone = 0; @@ -244878,8 +244781,6 @@ bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples) break; } - juce_free (buffer); - hr = info->redbook->CloseAudioTrack(); delete source; @@ -245553,7 +245454,6 @@ public: optionalDllForDirectLoading (optionalDllForDirectLoading_), currentBitDepth (16), currentSampleRate (0), - tempBuffer (0), isOpen_ (false), isStarted (false), postOutput (true), @@ -245580,8 +245480,6 @@ public: close(); log ("ASIO - exiting"); removeCurrentDriver(); - - juce_free (tempBuffer); } void updateSampleRates() @@ -245916,9 +245814,7 @@ public: { buffersCreated = true; - juce_free (tempBuffer); - - tempBuffer = (float*) juce_calloc (totalBuffers * currentBlockSizeSamples * sizeof (float) + 128); + tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32); int n = 0; Array types; @@ -246304,7 +246200,7 @@ private: bool outputChannelLittleEndian [maxASIOChannels]; WaitableEvent event1; - float* tempBuffer; + HeapBlock tempBuffer; int volatile bufferIndex, numActiveInputChans, numActiveOutputChans; bool isOpen_, isStarted; @@ -248561,8 +248457,7 @@ private: int64 volatile lastBlockTime; double sampleRate; BitArray enabledInputs, enabledOutputs; - float** inputBuffers; - float** outputBuffers; + HeapBlock inputBuffers, outputBuffers; AudioIODeviceCallback* callback; CriticalSection startStopLock; @@ -248587,15 +248482,13 @@ private: for (i = 0; i < numInputBuffers; ++i) juce_free (inputBuffers[i]); - delete[] inputBuffers; - inputBuffers = 0; + inputBuffers.free(); numInputBuffers = 0; for (i = 0; i < numOutputBuffers; ++i) juce_free (outputBuffers[i]); - delete[] outputBuffers; - outputBuffers = 0; + outputBuffers.free(); numOutputBuffers = 0; } @@ -248909,8 +248802,7 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, false); numInputBuffers = enabledInputs.countNumberOfSetBits(); - inputBuffers = new float* [numInputBuffers + 2]; - zeromem (inputBuffers, sizeof (float*) * numInputBuffers + 2); + inputBuffers.calloc (numInputBuffers + 2); int i, numIns = 0; for (i = 0; i <= enabledInputs.getHighestBit(); i += 2) @@ -248937,8 +248829,7 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, false); numOutputBuffers = enabledOutputs.countNumberOfSetBits(); - outputBuffers = new float* [numOutputBuffers + 2]; - zeromem (outputBuffers, sizeof (float*) * numOutputBuffers + 2); + outputBuffers.calloc (numOutputBuffers + 2); int numOuts = 0; for (i = 0; i <= enabledOutputs.getHighestBit(); i += 2) @@ -250253,14 +250144,14 @@ public: if (getPin (filter, PINDIR_OUTPUT, &pin)) { ComSmartPtr pushSource; - hr = pin->QueryInterface (IID_IAMPushSource, (void**) &pushSource); + HRESULT hr = pin->QueryInterface (IID_IAMPushSource, (void**) &pushSource); if (pushSource != 0) { REFERENCE_TIME latency = 0; - hr = ps->GetLatency (&latency); + hr = pushSource->GetLatency (&latency); - firstRecordedTime -= RelativeTime ((double) latency); + firstRecordedTime = firstRecordedTime - RelativeTime ((double) latency); } } } @@ -254240,7 +254131,7 @@ static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& i { const int width = image.getWidth(); const int height = image.getHeight(); - uint32* const colour = (uint32*) juce_malloc (width * height * sizeof (uint32)); + HeapBlock colour (width * height); int index = 0; for (int y = 0; y < height; ++y) @@ -254256,7 +254147,6 @@ static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& i GC gc = XCreateGC (display, pixmap, 0, 0); XPutImage (display, pixmap, gc, ximage, 0, 0, 0, 0, width, height); XFreeGC (display, gc); - juce_free (colour); return pixmap; } @@ -254266,7 +254156,8 @@ static Pixmap juce_createMaskPixmapFromImage (Display* display, const Image& ima const int width = image.getWidth(); const int height = image.getHeight(); const int stride = (width + 7) >> 3; - uint8* const mask = (uint8*) juce_calloc (stride * height); + HeapBlock mask; + mask.calloc (stride * height); const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); for (int y = 0; y < height; ++y) @@ -254281,12 +254172,8 @@ static Pixmap juce_createMaskPixmapFromImage (Display* display, const Image& ima } } - Pixmap pixmap = XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), - (char*) mask, width, height, 1, 0, 1); - - juce_free (mask); - - return pixmap; + return XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), + (char*) mask, width, height, 1, 0, 1); } class XBitmapImage : public Image @@ -254352,7 +254239,8 @@ public: if (! usingXShm) #endif { - imageData = (uint8*) juce_malloc (lineStride * h); + imageDataAllocated.malloc (lineStride * h); + imageData = imageDataAllocated; if (format_ == ARGB && clearImage) zeromem (imageData, h * lineStride); @@ -254380,7 +254268,8 @@ public: const int pixelStride = 2; const int lineStride = ((w * pixelStride + 3) & ~3); - xImage->data = (char*) juce_malloc (lineStride * h); + imageData16Bit.malloc (lineStride * h); + xImage->data = imageData16Bit; xImage->bitmap_pad = 16; xImage->depth = pixelStride * 8; xImage->bytes_per_line = lineStride; @@ -254413,13 +254302,9 @@ public: else #endif { - juce_free (xImage->data); xImage->data = 0; XDestroyImage (xImage); } - - if (! is16Bit) - imageData = 0; // to stop the base class freeing this (for the 16-bit version we want it to free it) } void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy) @@ -254474,6 +254359,7 @@ public: private: XImage* xImage; const bool is16Bit; + HeapBlock imageData16Bit; #if JUCE_USE_XSHM XShmSegmentInfo segmentInfo; @@ -254937,7 +254823,7 @@ public: void setIcon (const Image& newIcon) { const int dataSize = newIcon.getWidth() * newIcon.getHeight() + 2; - unsigned long* const data = (unsigned long*) juce_malloc (dataSize * sizeof (uint32)); + HeapBlock data (dataSize); int index = 0; data[index++] = newIcon.getWidth(); @@ -254952,8 +254838,6 @@ public: XA_CARDINAL, 32, PropModeReplace, (unsigned char*) data, dataSize); - juce_free (data); - deleteIconPixmaps(); XWMHints* wmHints = XGetWMHints (display, windowH); @@ -256568,8 +256452,9 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot } const int stride = (cursorW + 7) >> 3; - uint8* const maskPlane = (uint8*) juce_calloc (stride * cursorH); - uint8* const sourcePlane = (uint8*) juce_calloc (stride * cursorH); + HeapBlock maskPlane, sourcePlane; + maskPlane.calloc (stride * cursorH); + sourcePlane.calloc (stride * cursorH); const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); @@ -256593,9 +256478,6 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*) sourcePlane, cursorW, cursorH, 0xffff, 0, 1); Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*) maskPlane, cursorW, cursorH, 0xffff, 0, 1); - juce_free (maskPlane); - juce_free (sourcePlane); - XColor white, black; black.red = black.green = black.blue = 0; white.red = white.green = white.blue = 0xffff; @@ -258201,8 +258083,6 @@ public: outputId (outputId_), isOpen_ (false), callback (0), - inChans (0), - outChans (0), totalNumberOfInputChannels (0), totalNumberOfOutputChannels (0) { @@ -258241,8 +258121,8 @@ public: JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)); } - inChans = (float**) juce_calloc (sizeof (float*) * (totalNumberOfInputChannels + 2)); - outChans = (float**) juce_calloc (sizeof (float*) * (totalNumberOfOutputChannels + 2)); + inChans.calloc (totalNumberOfInputChannels + 2); + outChans.calloc (totalNumberOfOutputChannels + 2); } } @@ -258254,9 +258134,6 @@ public: JUCE_NAMESPACE::jack_client_close (client); client = 0; } - - juce_free (inChans); - juce_free (outChans); } const StringArray getChannelNames (bool forInput) const @@ -258521,8 +258398,7 @@ private: AudioIODeviceCallback* callback; CriticalSection callbackLock; - float** inChans; - float** outChans; + HeapBlock inChans, outChans; int totalNumberOfInputChannels; int totalNumberOfOutputChannels; VoidArray inputPorts, outputPorts; @@ -258961,7 +258837,7 @@ public: if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) { - uint8* const buffer = (uint8*) juce_malloc (maxEventSize); + HeapBlock buffer (maxEventSize); const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd)); @@ -259004,7 +258880,6 @@ public: } snd_midi_event_free (midiParser); - juce_free (buffer); } }; @@ -259390,20 +259265,15 @@ const String PlatformUtilities::cfStringToJuceString (CFStringRef cfString) { #if JUCE_STRINGS_ARE_UNICODE CFRange range = { 0, CFStringGetLength (cfString) }; - UniChar* const u = (UniChar*) juce_malloc (sizeof (UniChar) * (range.length + 1)); - + HeapBlock u (range.length + 1); CFStringGetCharacters (cfString, range, u); u[range.length] = 0; - result = convertUTF16ToString (u); - - juce_free (u); #else const int len = CFStringGetLength (cfString); - char* buffer = (char*) juce_malloc (len + 1); + HeapBlock buffer (len + 1); CFStringGetCString (cfString, buffer, len + 1, CFStringGetSystemEncoding()); result = buffer; - juce_free (buffer); #endif } @@ -259415,16 +259285,12 @@ CFStringRef PlatformUtilities::juceStringToCFString (const String& s) #if JUCE_STRINGS_ARE_UNICODE const int len = s.length(); const juce_wchar* t = (const juce_wchar*) s; - - UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4); + HeapBlock temp (len + 2); for (int i = 0; i <= len; ++i) temp[i] = t[i]; - CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); - juce_free (temp); - - return result; + return CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); #else return CFStringCreateWithCString (kCFAllocatorDefault, @@ -259458,8 +259324,9 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) { const int len = s.length(); - UniChar* const tempIn = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); - UniChar* const tempOut = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); + HeapBlock tempIn, tempOut; + tempIn.calloc (len + 2); + tempOut.calloc (len + 2); for (int i = 0; i <= len; ++i) tempIn[i] = s[i]; @@ -259485,9 +259352,6 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) t[i] = 0; } - juce_free (tempIn); - juce_free (tempOut); - DisposeUnicodeToTextInfo (&conversionInfo); } @@ -262078,45 +261942,38 @@ public: return 0; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); float x = 0; #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) for (int i = 0; i < length; ++i) x += advances[i]; - - juce_free (advances); } #endif - juce_free (glyphs); - return x * unitsToHeightScaleFactor; } @@ -262128,10 +261985,11 @@ public: return; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; int x = 0; @@ -262142,12 +262000,11 @@ public: resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; float x = 0; @@ -262157,13 +262014,11 @@ public: xOffsets.add (x * unitsToHeightScaleFactor); resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) { @@ -262175,12 +262030,8 @@ public: resultGlyphs.add (glyphs[i]); } } - - juce_free (advances); } #endif - - juce_free (glyphs); } bool getOutlineForGlyph (int glyphNumber, Path& path) @@ -262245,19 +262096,20 @@ private: AffineTransform pathTransform; #endif - CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw() + void createGlyphsForString (const juce_wchar* const text, const int length, HeapBlock & glyphs) throw() { #if SUPPORT_10_4_FONTS #if ! SUPPORT_ONLY_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) #endif { - NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length); + glyphs.malloc (sizeof (NSGlyph) * length, 1); + NSGlyph* const g = (NSGlyph*) glyphs; for (int i = 0; i < length; ++i) g[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]]; - return (CGGlyph*) g; + return; } #endif @@ -262265,12 +262117,10 @@ private: if (charToGlyphMapper == 0) charToGlyphMapper = new CharToGlyphMapper (fontRef); - CGGlyph* const g = (CGGlyph*) juce_malloc (sizeof (CGGlyph) * length); + glyphs.malloc (length); for (int i = 0; i < length; ++i) - g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); - - return g; + glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); #endif } @@ -262522,7 +262372,6 @@ public: CoreGraphicsContext (CGContextRef context_, const float flipHeight_) : context (context_), flipHeight (flipHeight_), - gradientLookupTable (0), numGradientLookupEntries (0) { CGContextRetain (context); @@ -262545,7 +262394,6 @@ public: CGColorSpaceRelease (rgbColourSpace); CGColorSpaceRelease (greyColourSpace); delete state; - delete gradientLookupTable; } bool isVectorDevice() const { return false; } @@ -262572,7 +262420,7 @@ public: { const int numRects = clipRegion.getNumRectangles(); - CGRect* const rects = new CGRect [numRects]; + HeapBlock rects (numRects); for (int i = 0; i < numRects; ++i) { const Rectangle& r = clipRegion.getRectangle(i); @@ -262580,8 +262428,6 @@ public: } CGContextClipToRects (context, rects, numRects); - delete[] rects; - return ! isClipEmpty(); } } @@ -262950,7 +262796,7 @@ private: SavedState* state; OwnedArray stateStack; - PixelARGB* gradientLookupTable; + HeapBlock gradientLookupTable; int numGradientLookupEntries; static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData) @@ -262969,8 +262815,7 @@ private: CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw() { - delete gradientLookupTable; - gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries); + numGradientLookupEntries = gradient.createLookupTable (transform, gradientLookupTable); --numGradientLookupEntries; CGShadingRef result = 0; @@ -265992,7 +265837,8 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) const int maxPacketSize = 256; int pos = 0, bytesLeft = message.getRawDataSize(); const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; - MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 * numPackets + message.getRawDataSize()); + HeapBlock packets; + packets.malloc (32 * numPackets + message.getRawDataSize(), 1); packets->numPackets = numPackets; MIDIPacket* p = packets->packet; @@ -266011,8 +265857,6 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) MIDISend (mpe->port, mpe->endPoint, packets); else MIDIReceived (mpe->endPoint, packets); - - juce_free (packets); } else { @@ -266546,45 +266390,38 @@ public: return 0; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); float x = 0; #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) for (int i = 0; i < length; ++i) x += advances[i]; - - juce_free (advances); } #endif - juce_free (glyphs); - return x * unitsToHeightScaleFactor; } @@ -266596,10 +266433,11 @@ public: return; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; int x = 0; @@ -266610,12 +266448,11 @@ public: resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; float x = 0; @@ -266625,13 +266462,11 @@ public: xOffsets.add (x * unitsToHeightScaleFactor); resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) { @@ -266643,12 +266478,8 @@ public: resultGlyphs.add (glyphs[i]); } } - - juce_free (advances); } #endif - - juce_free (glyphs); } bool getOutlineForGlyph (int glyphNumber, Path& path) @@ -266713,19 +266544,20 @@ private: AffineTransform pathTransform; #endif - CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw() + void createGlyphsForString (const juce_wchar* const text, const int length, HeapBlock & glyphs) throw() { #if SUPPORT_10_4_FONTS #if ! SUPPORT_ONLY_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) #endif { - NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length); + glyphs.malloc (sizeof (NSGlyph) * length, 1); + NSGlyph* const g = (NSGlyph*) glyphs; for (int i = 0; i < length; ++i) g[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]]; - return (CGGlyph*) g; + return; } #endif @@ -266733,12 +266565,10 @@ private: if (charToGlyphMapper == 0) charToGlyphMapper = new CharToGlyphMapper (fontRef); - CGGlyph* const g = (CGGlyph*) juce_malloc (sizeof (CGGlyph) * length); + glyphs.malloc (length); for (int i = 0; i < length; ++i) - g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); - - return g; + glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); #endif } @@ -266992,7 +266822,6 @@ public: CoreGraphicsContext (CGContextRef context_, const float flipHeight_) : context (context_), flipHeight (flipHeight_), - gradientLookupTable (0), numGradientLookupEntries (0) { CGContextRetain (context); @@ -267015,7 +266844,6 @@ public: CGColorSpaceRelease (rgbColourSpace); CGColorSpaceRelease (greyColourSpace); delete state; - delete gradientLookupTable; } bool isVectorDevice() const { return false; } @@ -267042,7 +266870,7 @@ public: { const int numRects = clipRegion.getNumRectangles(); - CGRect* const rects = new CGRect [numRects]; + HeapBlock rects (numRects); for (int i = 0; i < numRects; ++i) { const Rectangle& r = clipRegion.getRectangle(i); @@ -267050,8 +266878,6 @@ public: } CGContextClipToRects (context, rects, numRects); - delete[] rects; - return ! isClipEmpty(); } } @@ -267420,7 +267246,7 @@ private: SavedState* state; OwnedArray stateStack; - PixelARGB* gradientLookupTable; + HeapBlock gradientLookupTable; int numGradientLookupEntries; static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData) @@ -267439,8 +267265,7 @@ private: CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw() { - delete gradientLookupTable; - gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries); + numGradientLookupEntries = gradient.createLookupTable (transform, gradientLookupTable); --numGradientLookupEntries; CGShadingRef result = 0; @@ -272140,16 +271965,11 @@ public: started (false), sampleRate (0), bufferSize (512), - audioBuffer (0), numInputChans (0), numOutputChans (0), callbacksAllowed (true), numInputChannelInfos (0), - numOutputChannelInfos (0), - tempInputBuffers (0), - tempOutputBuffers (0), - inputChannelInfo (0), - outputChannelInfo (0) + numOutputChannelInfos (0) { jassert (deviceID != 0); @@ -272174,24 +271994,15 @@ public: stop (false); delete inputDevice; - - juce_free (audioBuffer); - juce_free (tempInputBuffers); - juce_free (tempOutputBuffers); - juce_free (inputChannelInfo); - juce_free (outputChannelInfo); } void allocateTempBuffers() { const int tempBufSize = bufferSize + 4; - juce_free (audioBuffer); - audioBuffer = (float*) juce_calloc ((numInputChans + numOutputChans) * tempBufSize * sizeof (float)); + audioBuffer.calloc ((numInputChans + numOutputChans) * tempBufSize); - juce_free (tempInputBuffers); - tempInputBuffers = (float**) juce_calloc (sizeof (float*) * (numInputChans + 2)); - juce_free (tempOutputBuffers); - tempOutputBuffers = (float**) juce_calloc (sizeof (float*) * (numOutputChans + 2)); + tempInputBuffers.calloc (numInputChans + 2); + tempOutputBuffers.calloc (numOutputChans + 2); int i, count = 0; for (i = 0; i < numInputChans; ++i) @@ -272214,7 +272025,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); + HeapBlock bufList; + bufList.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) { @@ -272274,8 +272086,6 @@ public: } } } - - juce_free (bufList); } } @@ -272315,7 +272125,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); + HeapBlock ranges; + ranges.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) { @@ -272336,8 +272147,6 @@ public: if (bufferSize > 0) bufferSizes.addIfNotAlreadyThere (bufferSize); } - - juce_free (ranges); } if (bufferSizes.size() == 0 && bufferSize > 0) @@ -272351,7 +272160,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); + HeapBlock ranges; + ranges.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) { @@ -272370,8 +272180,6 @@ public: } } } - - juce_free (ranges); } if (sampleRates.size() == 0 && sampleRate > 0) @@ -272403,12 +272211,10 @@ public: inChanNames.clear(); outChanNames.clear(); - juce_free (inputChannelInfo); - inputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numInputChans + 2)); + inputChannelInfo.calloc (numInputChans + 2); numInputChannelInfos = 0; - juce_free (outputChannelInfo); - outputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numOutputChans + 2)); + outputChannelInfo.calloc (numOutputChans + 2); numOutputChannelInfos = 0; fillInChannelInfo (true); @@ -272418,36 +272224,31 @@ public: const StringArray getSources (bool input) { StringArray s; - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + for (int i = 0; i < num; ++i) { - for (int i = 0; i < num; ++i) + AudioValueTranslation avt; + char buffer[256]; + + avt.mInputData = (void*) &(types[i]); + avt.mInputDataSize = sizeof (UInt32); + avt.mOutputData = buffer; + avt.mOutputDataSize = 256; + + UInt32 transSize = sizeof (avt); + + AudioObjectPropertyAddress pa; + pa.mSelector = kAudioDevicePropertyDataSourceNameForID; + pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + pa.mElement = kAudioObjectPropertyElementMaster; + + if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt))) { - AudioValueTranslation avt; - char buffer[256]; - - avt.mInputData = (void*) &(types[i]); - avt.mInputDataSize = sizeof (UInt32); - avt.mOutputData = buffer; - avt.mOutputDataSize = 256; - - UInt32 transSize = sizeof (avt); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSourceNameForID; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt))) - { - DBG (buffer); - s.add (buffer); - } + DBG (buffer); + s.add (buffer); } - - juce_free (types); } return s; @@ -272468,21 +272269,16 @@ public: { if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ¤tSourceID))) { - int num = 0; - OSType* const types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + for (int i = 0; i < num; ++i) { - for (int i = 0; i < num; ++i) + if (types[num] == currentSourceID) { - if (types[num] == currentSourceID) - { - result = i; - break; - } + result = i; + break; } - - juce_free (types); } } } @@ -272494,24 +272290,19 @@ public: { if (deviceID != 0) { - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + if (((unsigned int) index) < (unsigned int) num) { - if (((unsigned int) index) < (unsigned int) num) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; + AudioObjectPropertyAddress pa; + pa.mSelector = kAudioDevicePropertyDataSource; + pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + pa.mElement = kAudioObjectPropertyElementMaster; - OSType typeId = types[index]; + OSType typeId = types[index]; - OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); - } - - juce_free (types); + OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); } } } @@ -272825,7 +272616,8 @@ public: && AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size) == noErr && size > 0) { - AudioDeviceID* devs = (AudioDeviceID*) juce_calloc (size); + HeapBlock devs; + devs.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, devs))) { @@ -272847,8 +272639,6 @@ public: } } } - - juce_free (devs); } return result; @@ -272875,7 +272665,7 @@ private: bool started; double sampleRate; int bufferSize; - float* audioBuffer; + HeapBlock audioBuffer; int numInputChans, numOutputChans; bool callbacksAllowed; @@ -272887,10 +272677,8 @@ private: }; int numInputChannelInfos, numOutputChannelInfos; - CallbackDetailsForChannel* inputChannelInfo; - CallbackDetailsForChannel* outputChannelInfo; - float** tempInputBuffers; - float** tempOutputBuffers; + HeapBlock inputChannelInfo, outputChannelInfo; + HeapBlock tempInputBuffers, tempOutputBuffers; CoreAudioInternal (const CoreAudioInternal&); const CoreAudioInternal& operator= (const CoreAudioInternal&); @@ -272933,34 +272721,24 @@ private: return noErr; } - static OSType* getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, int& num) + static int getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, HeapBlock & types) { - OSType* types = 0; - UInt32 size = 0; - num = 0; - AudioObjectPropertyAddress pa; pa.mSelector = kAudioDevicePropertyDataSources; pa.mScope = kAudioObjectPropertyScopeWildcard; pa.mElement = kAudioObjectPropertyElementMaster; + UInt32 size = 0; if (deviceID != 0 && OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - types = (OSType*) juce_calloc (size); + types.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, types))) - { - num = size / sizeof (OSType); - } - else - { - juce_free (types); - types = 0; - } + return size / sizeof (OSType); } - return types; + return 0; } }; @@ -273247,7 +273025,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size))) { - AudioDeviceID* const devs = (AudioDeviceID*) juce_calloc (size); + HeapBlock devs; + devs.calloc (size, 1); if (OK (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, devs))) { @@ -273285,8 +273064,6 @@ public: alreadyLogged = true; } - - juce_free (devs); } inputDeviceNames.appendNumbersToDuplicates (false, true); @@ -273393,7 +273170,8 @@ private: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); + HeapBlock bufList; + bufList.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) { @@ -273405,8 +273183,6 @@ private: total += b.mNumberChannels; } } - - juce_free (bufList); } return total; @@ -273734,7 +273510,8 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) const int maxPacketSize = 256; int pos = 0, bytesLeft = message.getRawDataSize(); const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; - MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 * numPackets + message.getRawDataSize()); + HeapBlock packets; + packets.malloc (32 * numPackets + message.getRawDataSize(), 1); packets->numPackets = numPackets; MIDIPacket* p = packets->packet; @@ -273753,8 +273530,6 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) MIDISend (mpe->port, mpe->endPoint, packets); else MIDIReceived (mpe->endPoint, packets); - - juce_free (packets); } else { diff --git a/juce_amalgamated.h b/juce_amalgamated.h index a371ef64f5..7f88500e21 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -763,13 +763,24 @@ extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw(); // Win32 debug non-DLL versions.. - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) _malloc_dbg (numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) _calloc_dbg (1, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) _realloc_dbg (location, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) _free_dbg (location, _NORMAL_BLOCK) #else @@ -783,13 +794,24 @@ extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw(); extern JUCE_API void* juce_DebugRealloc (void* const block, const int size, const char* file, const int line); extern JUCE_API void juce_DebugFree (void* const block); - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) JUCE_NAMESPACE::juce_DebugMalloc (numBytes, __FILE__, __LINE__) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) JUCE_NAMESPACE::juce_DebugCalloc (numBytes, __FILE__, __LINE__) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_DebugRealloc (location, numBytes, __FILE__, __LINE__) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) JUCE_NAMESPACE::juce_DebugFree (location) #endif @@ -815,13 +837,24 @@ extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw(); extern JUCE_API void* juce_Realloc (void* const block, const int size); extern JUCE_API void juce_Free (void* const block); - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) JUCE_NAMESPACE::juce_Malloc (numBytes) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) JUCE_NAMESPACE::juce_Calloc (numBytes) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_Realloc (location, numBytes) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) JUCE_NAMESPACE::juce_Free (location) #define juce_UseDebuggingNewOperator \ @@ -833,13 +866,24 @@ extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw(); // Mac, Linux and Win32 (release) versions.. - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) malloc (numBytes) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) calloc (1, numBytes) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) realloc (location, numBytes) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) free (location) #endif @@ -2607,210 +2651,11 @@ BEGIN_JUCE_NAMESPACE #ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ #define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ -#ifndef __JUCE_ATOMIC_JUCEHEADER__ +#ifndef __JUCE_ARRAY_JUCEHEADER__ -/********* Start of inlined file: juce_Atomic.h *********/ -#ifndef __JUCE_ATOMIC_JUCEHEADER__ -#define __JUCE_ATOMIC_JUCEHEADER__ - -// Atomic increment/decrement operations.. - -#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN - - #include - static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } - static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } - static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } - static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } - -#elif JUCE_GCC - - #if JUCE_USE_GCC_ATOMIC_INTRINSICS - forcedinline void atomicIncrement (int& variable) throw() { __sync_add_and_fetch (&variable, 1); } - forcedinline int atomicIncrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, 1); } - forcedinline void atomicDecrement (int& variable) throw() { __sync_add_and_fetch (&variable, -1); } - forcedinline int atomicDecrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, -1); } - #else - - /** Increments an integer in a thread-safe way. */ - forcedinline void atomicIncrement (int& variable) throw() - { - __asm__ __volatile__ ( - #if JUCE_64BIT - "lock incl (%%rax)" - : - : "a" (&variable) - : "cc", "memory"); - #else - "lock incl %0" - : "=m" (variable) - : "m" (variable)); - #endif - } - - /** Increments an integer in a thread-safe way and returns the incremented value. */ - forcedinline int atomicIncrementAndReturn (int& variable) throw() - { - int result; - - __asm__ __volatile__ ( - #if JUCE_64BIT - "lock xaddl %%ebx, (%%rax) \n\ - incl %%ebx" - : "=b" (result) - : "a" (&variable), "b" (1) - : "cc", "memory"); - #else - "lock xaddl %%eax, (%%ecx) \n\ - incl %%eax" - : "=a" (result) - : "c" (&variable), "a" (1) - : "memory"); - #endif - - return result; - } - - /** Decrememts an integer in a thread-safe way. */ - forcedinline void atomicDecrement (int& variable) throw() - { - __asm__ __volatile__ ( - #if JUCE_64BIT - "lock decl (%%rax)" - : - : "a" (&variable) - : "cc", "memory"); - #else - "lock decl %0" - : "=m" (variable) - : "m" (variable)); - #endif - } - - /** Decrememts an integer in a thread-safe way and returns the incremented value. */ - forcedinline int atomicDecrementAndReturn (int& variable) throw() - { - int result; - - __asm__ __volatile__ ( - #if JUCE_64BIT - "lock xaddl %%ebx, (%%rax) \n\ - decl %%ebx" - : "=b" (result) - : "a" (&variable), "b" (-1) - : "cc", "memory"); - #else - "lock xaddl %%eax, (%%ecx) \n\ - decl %%eax" - : "=a" (result) - : "c" (&variable), "a" (-1) - : "memory"); - #endif - return result; - } - #endif - -#elif JUCE_USE_INTRINSICS - - #pragma intrinsic (_InterlockedIncrement) - #pragma intrinsic (_InterlockedDecrement) - - /** Increments an integer in a thread-safe way. */ - forcedinline void __fastcall atomicIncrement (int& variable) throw() - { - _InterlockedIncrement (reinterpret_cast (&variable)); - } - - /** Increments an integer in a thread-safe way and returns the incremented value. */ - forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw() - { - return _InterlockedIncrement (reinterpret_cast (&variable)); - } - - /** Decrememts an integer in a thread-safe way. */ - forcedinline void __fastcall atomicDecrement (int& variable) throw() - { - _InterlockedDecrement (reinterpret_cast (&variable)); - } - - /** Decrememts an integer in a thread-safe way and returns the incremented value. */ - forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw() - { - return _InterlockedDecrement (reinterpret_cast (&variable)); - } -#else - - /** Increments an integer in a thread-safe way. */ - forcedinline void __fastcall atomicIncrement (int& variable) throw() - { - __asm { - mov ecx, dword ptr [variable] - lock inc dword ptr [ecx] - } - } - - /** Increments an integer in a thread-safe way and returns the incremented value. */ - forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw() - { - int result; - - __asm { - mov ecx, dword ptr [variable] - mov eax, 1 - lock xadd dword ptr [ecx], eax - inc eax - mov result, eax - } - - return result; - } - - /** Decrememts an integer in a thread-safe way. */ - forcedinline void __fastcall atomicDecrement (int& variable) throw() - { - __asm { - mov ecx, dword ptr [variable] - lock dec dword ptr [ecx] - } - } - - /** Decrememts an integer in a thread-safe way and returns the incremented value. */ - forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw() - { - int result; - - __asm { - mov ecx, dword ptr [variable] - mov eax, -1 - lock xadd dword ptr [ecx], eax - dec eax - mov result, eax - } - - return result; - } -#endif - -#endif // __JUCE_ATOMIC_JUCEHEADER__ -/********* End of inlined file: juce_Atomic.h *********/ - -#endif -#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILELOGGER_JUCEHEADER__ - -/********* Start of inlined file: juce_FileLogger.h *********/ -#ifndef __JUCE_FILELOGGER_JUCEHEADER__ -#define __JUCE_FILELOGGER_JUCEHEADER__ - -/********* Start of inlined file: juce_File.h *********/ -#ifndef __JUCE_FILE_JUCEHEADER__ -#define __JUCE_FILE_JUCEHEADER__ - -/********* Start of inlined file: juce_OwnedArray.h *********/ -#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__ -#define __JUCE_OWNEDARRAY_JUCEHEADER__ +/********* Start of inlined file: juce_Array.h *********/ +#ifndef __JUCE_ARRAY_JUCEHEADER__ +#define __JUCE_ARRAY_JUCEHEADER__ /********* Start of inlined file: juce_ArrayAllocationBase.h *********/ #ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ @@ -3310,6 +3155,1784 @@ public: #endif // __JUCE_CRITICALSECTION_JUCEHEADER__ /********* End of inlined file: juce_CriticalSection.h *********/ +/** + Holds a list of primitive objects, such as ints, doubles, or pointers. + + Examples of arrays are: Array or Array + + Note that when holding pointers to objects, the array doesn't take any ownership + of the objects - for doing this, see the OwnedArray class or the ReferenceCountedArray class. + + If you're using a class or struct as the element type, it must be + capable of being copied or moved with a straightforward memcpy, rather than + needing construction and destruction code. + + For holding lists of strings, use the specialised class StringArray. + + To make all the array's methods thread-safe, pass in "CriticalSection" as the templated + TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. + + @see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection +*/ +template +class Array +{ +public: + + /** Creates an empty array. + + @param granularity this is the size of increment by which the internal storage + used by the array will grow. Only change it from the default if you know the + array is going to be very big and needs to be able to grow efficiently. + */ + Array (const int granularity = juceDefaultArrayGranularity) throw() + : data (granularity), + numUsed (0) + { + } + + /** Creates a copy of another array. + @param other the array to copy + */ + Array (const Array& other) throw() + : data (other.data.granularity) + { + other.lockArray(); + numUsed = other.numUsed; + data.setAllocatedSize (other.numUsed); + memcpy (data.elements, other.data.elements, numUsed * sizeof (ElementType)); + other.unlockArray(); + } + + /** Initalises from a null-terminated C array of values. + + @param values the array to copy from + */ + Array (const ElementType* values) throw() + : data (juceDefaultArrayGranularity), + numUsed (0) + { + while (*values != 0) + add (*values++); + } + + /** Initalises from a C array of values. + + @param values the array to copy from + @param numValues the number of values in the array + */ + Array (const ElementType* values, int numValues) throw() + : data (juceDefaultArrayGranularity), + numUsed (numValues) + { + data.setAllocatedSize (numValues); + memcpy (data.elements, values, numValues * sizeof (ElementType)); + } + + /** Destructor. */ + ~Array() throw() + { + } + + /** Copies another array. + @param other the array to copy + */ + const Array & operator= (const Array & other) throw() + { + if (this != &other) + { + other.lockArray(); + lock.enter(); + + data.granularity = other.data.granularity; + data.ensureAllocatedSize (other.size()); + numUsed = other.numUsed; + memcpy (data.elements, other.data.elements, numUsed * sizeof (ElementType)); + minimiseStorageOverheads(); + + lock.exit(); + other.unlockArray(); + } + + return *this; + } + + /** Compares this array to another one. + Two arrays are considered equal if they both contain the same set of + elements, in the same order. + @param other the other array to compare with + */ + template + bool operator== (const OtherArrayType& other) const throw() + { + lock.enter(); + + if (numUsed != other.numUsed) + { + lock.exit(); + return false; + } + + for (int i = numUsed; --i >= 0;) + { + if (data.elements [i] != other.data.elements [i]) + { + lock.exit(); + return false; + } + } + + lock.exit(); + return true; + } + + /** Compares this array to another one. + Two arrays are considered equal if they both contain the same set of + elements, in the same order. + @param other the other array to compare with + */ + template + bool operator!= (const OtherArrayType& other) const throw() + { + return ! operator== (other); + } + + /** Removes all elements from the array. + This will remove all the elements, and free any storage that the array is + using. To clear the array without freeing the storage, use the clearQuick() + method instead. + + @see clearQuick + */ + void clear() throw() + { + lock.enter(); + data.setAllocatedSize (0); + numUsed = 0; + lock.exit(); + } + + /** Removes all elements from the array without freeing the array's allocated storage. + + @see clear + */ + void clearQuick() throw() + { + lock.enter(); + numUsed = 0; + lock.exit(); + } + + /** Returns the current number of elements in the array. + */ + inline int size() const throw() + { + return numUsed; + } + + /** Returns one of the elements in the array. + If the index passed in is beyond the range of valid elements, this + will return zero. + + If you're certain that the index will always be a valid element, you + can call getUnchecked() instead, which is faster. + + @param index the index of the element being requested (0 is the first element in the array) + @see getUnchecked, getFirst, getLast + */ + inline ElementType operator[] (const int index) const throw() + { + lock.enter(); + const ElementType result = (((unsigned int) index) < (unsigned int) numUsed) + ? data.elements [index] + : ElementType(); + lock.exit(); + + return result; + } + + /** Returns one of the elements in the array, without checking the index passed in. + + Unlike the operator[] method, this will try to return an element without + checking that the index is within the bounds of the array, so should only + be used when you're confident that it will always be a valid index. + + @param index the index of the element being requested (0 is the first element in the array) + @see operator[], getFirst, getLast + */ + inline ElementType getUnchecked (const int index) const throw() + { + lock.enter(); + jassert (((unsigned int) index) < (unsigned int) numUsed); + const ElementType result = data.elements [index]; + lock.exit(); + + return result; + } + + /** Returns a direct reference to one of the elements in the array, without checking the index passed in. + + This is like getUnchecked, but returns a direct reference to the element, so that + you can alter it directly. Obviously this can be dangerous, so only use it when + absolutely necessary. + + @param index the index of the element being requested (0 is the first element in the array) + @see operator[], getFirst, getLast + */ + inline ElementType& getReference (const int index) const throw() + { + lock.enter(); + jassert (((unsigned int) index) < (unsigned int) numUsed); + ElementType& result = data.elements [index]; + lock.exit(); + return result; + } + + /** Returns the first element in the array, or 0 if the array is empty. + + @see operator[], getUnchecked, getLast + */ + inline ElementType getFirst() const throw() + { + lock.enter(); + const ElementType result = (numUsed > 0) ? data.elements [0] + : ElementType(); + lock.exit(); + + return result; + } + + /** Returns the last element in the array, or 0 if the array is empty. + + @see operator[], getUnchecked, getFirst + */ + inline ElementType getLast() const throw() + { + lock.enter(); + const ElementType result = (numUsed > 0) ? data.elements [numUsed - 1] + : ElementType(); + lock.exit(); + + return result; + } + + /** Finds the index of the first element which matches the value passed in. + + This will search the array for the given object, and return the index + of its first occurrence. If the object isn't found, the method will return -1. + + @param elementToLookFor the value or object to look for + @returns the index of the object, or -1 if it's not found + */ + int indexOf (const ElementType elementToLookFor) const throw() + { + int result = -1; + + lock.enter(); + const ElementType* e = data.elements; + + for (int i = numUsed; --i >= 0;) + { + if (elementToLookFor == *e) + { + result = (int) (e - data.elements); + break; + } + + ++e; + } + + lock.exit(); + return result; + } + + /** Returns true if the array contains at least one occurrence of an object. + + @param elementToLookFor the value or object to look for + @returns true if the item is found + */ + bool contains (const ElementType elementToLookFor) const throw() + { + lock.enter(); + + const ElementType* e = data.elements; + int num = numUsed; + + while (num >= 4) + { + if (*e == elementToLookFor + || *++e == elementToLookFor + || *++e == elementToLookFor + || *++e == elementToLookFor) + { + lock.exit(); + return true; + } + + num -= 4; + ++e; + } + + while (num > 0) + { + if (elementToLookFor == *e) + { + lock.exit(); + return true; + } + + --num; + ++e; + } + + lock.exit(); + return false; + } + + /** Appends a new element at the end of the array. + + @param newElement the new object to add to the array + @see set, insert, addIfNotAlreadyThere, addSorted, addArray + */ + void add (const ElementType newElement) throw() + { + lock.enter(); + data.ensureAllocatedSize (numUsed + 1); + data.elements [numUsed++] = newElement; + lock.exit(); + } + + /** Inserts a new element into the array at a given position. + + If the index is less than 0 or greater than the size of the array, the + element will be added to the end of the array. + Otherwise, it will be inserted into the array, moving all the later elements + along to make room. + + @param indexToInsertAt the index at which the new element should be + inserted (pass in -1 to add it to the end) + @param newElement the new object to add to the array + @see add, addSorted, set + */ + void insert (int indexToInsertAt, const ElementType newElement) throw() + { + lock.enter(); + data.ensureAllocatedSize (numUsed + 1); + + if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) + { + ElementType* const insertPos = data.elements + indexToInsertAt; + const int numberToMove = numUsed - indexToInsertAt; + + if (numberToMove > 0) + memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType)); + + *insertPos = newElement; + ++numUsed; + } + else + { + data.elements [numUsed++] = newElement; + } + + lock.exit(); + } + + /** Inserts multiple copies of an element into the array at a given position. + + If the index is less than 0 or greater than the size of the array, the + element will be added to the end of the array. + Otherwise, it will be inserted into the array, moving all the later elements + along to make room. + + @param indexToInsertAt the index at which the new element should be inserted + @param newElement the new object to add to the array + @param numberOfTimesToInsertIt how many copies of the value to insert + @see insert, add, addSorted, set + */ + void insertMultiple (int indexToInsertAt, const ElementType newElement, + int numberOfTimesToInsertIt) throw() + { + if (numberOfTimesToInsertIt > 0) + { + lock.enter(); + data.ensureAllocatedSize (numUsed + numberOfTimesToInsertIt); + + if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) + { + ElementType* insertPos = data.elements + indexToInsertAt; + const int numberToMove = numUsed - indexToInsertAt; + + memmove (insertPos + numberOfTimesToInsertIt, insertPos, numberToMove * sizeof (ElementType)); + numUsed += numberOfTimesToInsertIt; + + while (--numberOfTimesToInsertIt >= 0) + *insertPos++ = newElement; + } + else + { + while (--numberOfTimesToInsertIt >= 0) + data.elements [numUsed++] = newElement; + } + + lock.exit(); + } + } + + /** Inserts an array of values into this array at a given position. + + If the index is less than 0 or greater than the size of the array, the + new elements will be added to the end of the array. + Otherwise, they will be inserted into the array, moving all the later elements + along to make room. + + @param indexToInsertAt the index at which the first new element should be inserted + @param newElements the new values to add to the array + @param numberOfElements how many items are in the array + @see insert, add, addSorted, set + */ + void insertArray (int indexToInsertAt, + const ElementType* newElements, + int numberOfElements) throw() + { + if (numberOfElements > 0) + { + lock.enter(); + data.ensureAllocatedSize (numUsed + numberOfElements); + + if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) + { + ElementType* insertPos = data.elements + indexToInsertAt; + const int numberToMove = numUsed - indexToInsertAt; + + memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType)); + numUsed += numberOfElements; + + while (--numberOfElements >= 0) + *insertPos++ = *newElements++; + } + else + { + while (--numberOfElements >= 0) + data.elements [numUsed++] = *newElements++; + } + + lock.exit(); + } + } + + /** Appends a new element at the end of the array as long as the array doesn't + already contain it. + + If the array already contains an element that matches the one passed in, nothing + will be done. + + @param newElement the new object to add to the array + */ + void addIfNotAlreadyThere (const ElementType newElement) throw() + { + lock.enter(); + + if (! contains (newElement)) + add (newElement); + + lock.exit(); + } + + /** Replaces an element with a new value. + + If the index is less than zero, this method does nothing. + If the index is beyond the end of the array, the item is added to the end of the array. + + @param indexToChange the index whose value you want to change + @param newValue the new value to set for this index. + @see add, insert + */ + void set (const int indexToChange, + const ElementType newValue) throw() + { + jassert (indexToChange >= 0); + + if (indexToChange >= 0) + { + lock.enter(); + + if (indexToChange < numUsed) + { + data.elements [indexToChange] = newValue; + } + else + { + data.ensureAllocatedSize (numUsed + 1); + data.elements [numUsed++] = newValue; + } + + lock.exit(); + } + } + + /** Replaces an element with a new value without doing any bounds-checking. + + This just sets a value directly in the array's internal storage, so you'd + better make sure it's in range! + + @param indexToChange the index whose value you want to change + @param newValue the new value to set for this index. + @see set, getUnchecked + */ + void setUnchecked (const int indexToChange, + const ElementType newValue) throw() + { + lock.enter(); + jassert (((unsigned int) indexToChange) < (unsigned int) numUsed); + data.elements [indexToChange] = newValue; + lock.exit(); + } + + /** Adds elements from an array to the end of this array. + + @param elementsToAdd the array of elements to add + @param numElementsToAdd how many elements are in this other array + @see add + */ + void addArray (const ElementType* elementsToAdd, + int numElementsToAdd) throw() + { + lock.enter(); + + if (numElementsToAdd > 0) + { + data.ensureAllocatedSize (numUsed + numElementsToAdd); + + while (--numElementsToAdd >= 0) + data.elements [numUsed++] = *elementsToAdd++; + } + + lock.exit(); + } + + /** This swaps the contents of this array with those of another array. + + If you need to exchange two arrays, this is vastly quicker than using copy-by-value + because it just swaps their internal pointers. + */ + template + void swapWithArray (OtherArrayType& otherArray) throw() + { + lock.enter(); + otherArray.lock.enter(); + swapVariables (numUsed, otherArray.numUsed); + swapVariables (data.elements, otherArray.data.elements); + swapVariables (data.numAllocated, otherArray.data.numAllocated); + otherArray.lock.exit(); + lock.exit(); + } + + /** Adds elements from another array to the end of this array. + + @param arrayToAddFrom the array from which to copy the elements + @param startIndex the first element of the other array to start copying from + @param numElementsToAdd how many elements to add from the other array. If this + value is negative or greater than the number of available elements, + all available elements will be copied. + @see add + */ + template + void addArray (const OtherArrayType& arrayToAddFrom, + int startIndex = 0, + int numElementsToAdd = -1) throw() + { + arrayToAddFrom.lockArray(); + lock.enter(); + + if (startIndex < 0) + { + jassertfalse + startIndex = 0; + } + + if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) + numElementsToAdd = arrayToAddFrom.size() - startIndex; + + while (--numElementsToAdd >= 0) + add (arrayToAddFrom.getUnchecked (startIndex++)); + + lock.exit(); + arrayToAddFrom.unlockArray(); + } + + /** Inserts a new element into the array, assuming that the array is sorted. + + This will use a comparator to find the position at which the new element + should go. If the array isn't sorted, the behaviour of this + method will be unpredictable. + + @param comparator the comparator to use to compare the elements - see the sort() + method for details about the form this object should take + @param newElement the new element to insert to the array + @see add, sort + */ + template + void addSorted (ElementComparator& comparator, + const ElementType newElement) throw() + { + lock.enter(); + insert (findInsertIndexInSortedArray (comparator, data.elements, newElement, 0, numUsed), newElement); + lock.exit(); + } + + /** Finds the index of an element in the array, assuming that the array is sorted. + + This will use a comparator to do a binary-chop to find the index of the given + element, if it exists. If the array isn't sorted, the behaviour of this + method will be unpredictable. + + @param comparator the comparator to use to compare the elements - see the sort() + method for details about the form this object should take + @param elementToLookFor the element to search for + @returns the index of the element, or -1 if it's not found + @see addSorted, sort + */ + template + int indexOfSorted (ElementComparator& comparator, + const ElementType elementToLookFor) const throw() + { + (void) comparator; // if you pass in an object with a static compareElements() method, this + // avoids getting warning messages about the parameter being unused + lock.enter(); + + int start = 0; + int end = numUsed; + + for (;;) + { + if (start >= end) + { + lock.exit(); + return -1; + } + else if (comparator.compareElements (elementToLookFor, data.elements [start]) == 0) + { + lock.exit(); + return start; + } + else + { + const int halfway = (start + end) >> 1; + + if (halfway == start) + { + lock.exit(); + return -1; + } + else if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0) + start = halfway; + else + end = halfway; + } + } + } + + /** Removes an element from the array. + + This will remove the element at a given index, and move back + all the subsequent elements to close the gap. + If the index passed in is out-of-range, nothing will happen. + + @param indexToRemove the index of the element to remove + @returns the element that has been removed + @see removeValue, removeRange + */ + ElementType remove (const int indexToRemove) throw() + { + lock.enter(); + + if (((unsigned int) indexToRemove) < (unsigned int) numUsed) + { + --numUsed; + + ElementType* const e = data.elements + indexToRemove; + ElementType const removed = *e; + const int numberToShift = numUsed - indexToRemove; + + if (numberToShift > 0) + memmove (e, e + 1, numberToShift * sizeof (ElementType)); + + if ((numUsed << 1) < data.numAllocated) + minimiseStorageOverheads(); + + lock.exit(); + return removed; + } + else + { + lock.exit(); + return ElementType(); + } + } + + /** Removes an item from the array. + + This will remove the first occurrence of the given element from the array. + If the item isn't found, no action is taken. + + @param valueToRemove the object to try to remove + @see remove, removeRange + */ + void removeValue (const ElementType valueToRemove) throw() + { + lock.enter(); + ElementType* e = data.elements; + + for (int i = numUsed; --i >= 0;) + { + if (valueToRemove == *e) + { + remove ((int) (e - data.elements)); + break; + } + + ++e; + } + + lock.exit(); + } + + /** Removes a range of elements from the array. + + This will remove a set of elements, starting from the given index, + and move subsequent elements down to close the gap. + + If the range extends beyond the bounds of the array, it will + be safely clipped to the size of the array. + + @param startIndex the index of the first element to remove + @param numberToRemove how many elements should be removed + @see remove, removeValue + */ + void removeRange (int startIndex, + const int numberToRemove) throw() + { + lock.enter(); + const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); + startIndex = jlimit (0, numUsed, startIndex); + + if (endIndex > startIndex) + { + const int rangeSize = endIndex - startIndex; + ElementType* e = data.elements + startIndex; + int numToShift = numUsed - endIndex; + numUsed -= rangeSize; + + while (--numToShift >= 0) + { + *e = e [rangeSize]; + ++e; + } + + if ((numUsed << 1) < data.numAllocated) + minimiseStorageOverheads(); + } + + lock.exit(); + } + + /** Removes the last n elements from the array. + + @param howManyToRemove how many elements to remove from the end of the array + @see remove, removeValue, removeRange + */ + void removeLast (const int howManyToRemove = 1) throw() + { + lock.enter(); + numUsed = jmax (0, numUsed - howManyToRemove); + + if ((numUsed << 1) < data.numAllocated) + minimiseStorageOverheads(); + + lock.exit(); + } + + /** Removes any elements which are also in another array. + + @param otherArray the other array in which to look for elements to remove + @see removeValuesNotIn, remove, removeValue, removeRange + */ + template + void removeValuesIn (const OtherArrayType& otherArray) throw() + { + otherArray.lockArray(); + lock.enter(); + + if (this == &otherArray) + { + clear(); + } + else + { + if (otherArray.size() > 0) + { + for (int i = numUsed; --i >= 0;) + if (otherArray.contains (data.elements [i])) + remove (i); + } + } + + lock.exit(); + otherArray.unlockArray(); + } + + /** Removes any elements which are not found in another array. + + Only elements which occur in this other array will be retained. + + @param otherArray the array in which to look for elements NOT to remove + @see removeValuesIn, remove, removeValue, removeRange + */ + template + void removeValuesNotIn (const OtherArrayType& otherArray) throw() + { + otherArray.lockArray(); + lock.enter(); + + if (this != &otherArray) + { + if (otherArray.size() <= 0) + { + clear(); + } + else + { + for (int i = numUsed; --i >= 0;) + if (! otherArray.contains (data.elements [i])) + remove (i); + } + } + + lock.exit(); + otherArray.unlockArray(); + } + + /** Swaps over two elements in the array. + + This swaps over the elements found at the two indexes passed in. + If either index is out-of-range, this method will do nothing. + + @param index1 index of one of the elements to swap + @param index2 index of the other element to swap + */ + void swap (const int index1, + const int index2) throw() + { + lock.enter(); + + if (((unsigned int) index1) < (unsigned int) numUsed + && ((unsigned int) index2) < (unsigned int) numUsed) + { + swapVariables (data.elements [index1], + data.elements [index2]); + } + + lock.exit(); + } + + /** Moves one of the values to a different position. + + This will move the value to a specified index, shuffling along + any intervening elements as required. + + So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling + move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. + + @param currentIndex the index of the value to be moved. If this isn't a + valid index, then nothing will be done + @param newIndex the index at which you'd like this value to end up. If this + is less than zero, the value will be moved to the end + of the array + */ + void move (const int currentIndex, + int newIndex) throw() + { + if (currentIndex != newIndex) + { + lock.enter(); + + if (((unsigned int) currentIndex) < (unsigned int) numUsed) + { + if (((unsigned int) newIndex) >= (unsigned int) numUsed) + newIndex = numUsed - 1; + + const ElementType value = data.elements [currentIndex]; + + if (newIndex > currentIndex) + { + memmove (data.elements + currentIndex, + data.elements + currentIndex + 1, + (newIndex - currentIndex) * sizeof (ElementType)); + } + else + { + memmove (data.elements + newIndex + 1, + data.elements + newIndex, + (currentIndex - newIndex) * sizeof (ElementType)); + } + + data.elements [newIndex] = value; + } + + lock.exit(); + } + } + + /** Reduces the amount of storage being used by the array. + + Arrays typically allocate slightly more storage than they need, and after + removing elements, they may have quite a lot of unused space allocated. + This method will reduce the amount of allocated storage to a minimum. + */ + void minimiseStorageOverheads() throw() + { + lock.enter(); + + if (numUsed == 0) + { + data.setAllocatedSize (0); + } + else + { + const int newAllocation = data.granularity * (numUsed / data.granularity + 1); + + if (newAllocation < data.numAllocated) + data.setAllocatedSize (newAllocation); + } + + lock.exit(); + } + + /** Increases the array's internal storage to hold a minimum number of elements. + + Calling this before adding a large known number of elements means that + the array won't have to keep dynamically resizing itself as the elements + are added, and it'll therefore be more efficient. + */ + void ensureStorageAllocated (const int minNumElements) throw() + { + data.ensureAllocatedSize (minNumElements); + } + + /** Sorts the elements in the array. + + This will use a comparator object to sort the elements into order. The object + passed must have a method of the form: + @code + int compareElements (ElementType first, ElementType second); + @endcode + + ..and this method must return: + - a value of < 0 if the first comes before the second + - a value of 0 if the two objects are equivalent + - a value of > 0 if the second comes before the first + + To improve performance, the compareElements() method can be declared as static or const. + + @param comparator the comparator to use for comparing elements. + @param retainOrderOfEquivalentItems if this is true, then items + which the comparator says are equivalent will be + kept in the order in which they currently appear + in the array. This is slower to perform, but may + be important in some cases. If it's false, a faster + algorithm is used, but equivalent elements may be + rearranged. + + @see addSorted, indexOfSorted, sortArray + */ + template + void sort (ElementComparator& comparator, + const bool retainOrderOfEquivalentItems = false) const throw() + { + (void) comparator; // if you pass in an object with a static compareElements() method, this + // avoids getting warning messages about the parameter being unused + lock.enter(); + sortArray (comparator, data.elements, 0, size() - 1, retainOrderOfEquivalentItems); + lock.exit(); + } + + /** Locks the array's CriticalSection. + + Of course if the type of section used is a DummyCriticalSection, this won't + have any effect. + + @see unlockArray + */ + void lockArray() const throw() + { + lock.enter(); + } + + /** Unlocks the array's CriticalSection. + + Of course if the type of section used is a DummyCriticalSection, this won't + have any effect. + + @see lockArray + */ + void unlockArray() const throw() + { + lock.exit(); + } + + juce_UseDebuggingNewOperator + +private: + ArrayAllocationBase data; + int numUsed; + TypeOfCriticalSectionToUse lock; +}; + +#endif // __JUCE_ARRAY_JUCEHEADER__ +/********* End of inlined file: juce_Array.h *********/ + +#endif +#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ + +#endif +#ifndef __JUCE_BITARRAY_JUCEHEADER__ + +/********* Start of inlined file: juce_BitArray.h *********/ +#ifndef __JUCE_BITARRAY_JUCEHEADER__ +#define __JUCE_BITARRAY_JUCEHEADER__ + +/********* Start of inlined file: juce_HeapBlock.h *********/ +#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ +#define __JUCE_HEAPBLOCK_JUCEHEADER__ + +/** + Very simple container class to hold a pointer to some data on the heap. + + When you need to allocate some heap storage for something, always try to use + this class instead of allocating the memory directly using malloc/free. + + A HeapBlock object can be treated in pretty much exactly the same way + as an char*, but as long as you allocate it on the stack or as a class member, + it's almost impossible for it to leak memory. + + It also makes your code much more concise and readable than doing the same thing + using direct allocations, + + E.g. instead of this: + @code + int* temp = (int*) juce_malloc (1024 * sizeof (int)); + memcpy (temp, xyz, 1024 * sizeof (int)); + juce_free (temp); + temp = (int*) juce_calloc (2048 * sizeof (int)); + temp[0] = 1234; + memcpy (foobar, temp, 2048 * sizeof (int)); + juce_free (temp); + @endcode + + ..you could just write this: + @code + HeapBlock temp (1024); + memcpy (temp, xyz, 1024 * sizeof (int)); + temp.calloc (2048); + temp[0] = 1234; + memcpy (foobar, temp, 2048 * sizeof (int)); + @endcode + + The class is extremely lightweight, containing only a pointer to the + data, and exposes malloc/realloc/calloc/free methods that do the same jobs + as their less object-oriented counterparts. Despite adding safety, you probably + won't sacrifice any performance by using this in place of normal pointers. + + @see Array, OwnedArray, MemoryBlock +*/ +template +class HeapBlock +{ +public: + + /** Creates a HeapBlock which is initially just a null pointer. + + After creation, you can resize the array using the malloc(), calloc(), + or realloc() methods. + */ + HeapBlock() : data (0) + { + } + + /** Creates a HeapBlock containing a number of elements. + + The contents of the block are undefined, as it will have been created by a + malloc call. + + If you want an array of zero values, you can use the calloc() method instead. + */ + HeapBlock (const int numElements) + : data ((ElementType*) ::juce_malloc (numElements * sizeof (ElementType))) + { + } + + /** Destructor. + + This will free the data, if any has been allocated. + */ + ~HeapBlock() + { + ::juce_free (data); + } + + /** Returns a raw pointer to the allocated data. + This may be a null pointer if the data hasn't yet been allocated, or if it has been + freed by calling the free() method. + */ + inline operator ElementType*() const { return data; } + + /** Returns a void pointer to the allocated data. + This may be a null pointer if the data hasn't yet been allocated, or if it has been + freed by calling the free() method. + */ + inline operator void*() const { return (void*) data; } + + /** Lets you use indirect calls to the first element in the array. + Obviously this will cause problems if the array hasn't been initialised, because it'll + be referencing a null pointer. + */ + inline ElementType* operator->() const { return data; } + + /** Returns a pointer to the data by casting it to any type you need. + */ + template + inline operator CastType*() const { return (CastType*) data; } + + /** Returns a reference to one of the data elements. + Obviously there's no bounds-checking here, as this object is just a dumb pointer and + has no idea of the size it currently has allocated. + */ + inline ElementType& operator[] (const pointer_sized_int index) const { return data [index]; } + + /** Returns a pointer to a data element at an offset from the start of the array. + This is the same as doing pointer arithmetic on the raw pointer itself. + */ + inline ElementType* operator+ (const pointer_sized_int index) const { return data + index; } + + /** Returns a reference to the raw data pointer. + Beware that the pointer returned here will become invalid as soon as you call + any of the allocator methods on this object! + */ + inline ElementType** operator&() const { return (ElementType**) &data; } + + /** Compares the pointer with another pointer. + This can be handy for checking whether this is a null pointer. + */ + inline bool operator== (const ElementType* const otherPointer) const { return otherPointer == data; } + + /** Compares the pointer with another pointer. + This can be handy for checking whether this is a null pointer. + */ + inline bool operator!= (const ElementType* const otherPointer) const { return otherPointer != data; } + + /** Allocates a specified amount of memory. + + This uses the normal malloc to allocate an amount of memory for this object. + Any previously allocated memory will be freed by this method. + + The number of bytes allocated will be (newNumElements * elementSize). Normally + you wouldn't need to specify the second parameter, but it can be handy if you need + to allocate a size in bytes rather than in terms of the number of elements. + + The data that is allocated will be freed when this object is deleted, or when you + call free() or any of the allocation methods. + */ + void malloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + ::juce_free (data); + data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + } + + /** Allocates a specified amount of memory and clears it. + This does the same job as the malloc() method, but clears the memory that it allocates. + */ + void calloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + ::juce_free (data); + data = (ElementType*) ::juce_calloc (newNumElements * elementSize); + } + + /** Allocates a specified amount of memory and optionally clears it. + This does the same job as either malloc() or calloc(), depending on the + initialiseToZero parameter. + */ + void allocate (const int newNumElements, const bool initialiseToZero) + { + ::juce_free (data); + + if (initialiseToZero) + data = (ElementType*) ::juce_calloc (newNumElements * sizeof (ElementType)); + else + data = (ElementType*) ::juce_malloc (newNumElements * sizeof (ElementType)); + } + + /** Re-allocates a specified amount of memory. + + The semantics of this method are the same as malloc() and calloc(), but it + uses realloc() to keep as much of the existing data as possible. + */ + void realloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + if (data == 0) + data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + else + data = (ElementType*) ::juce_realloc (data, newNumElements * elementSize); + } + + /** Frees any currently-allocated data. + This will free the data and reset this object to be a null pointer. + */ + void free() + { + ::juce_free (data); + data = 0; + } + + /** Swaps this object's data with the data of another HeapBlock. + The two objects simply exchange their data pointers. + */ + void swapWith (HeapBlock & other) + { + swapVariables (data, other.data); + } + +private: + + ElementType* data; + + HeapBlock (const HeapBlock&); + const HeapBlock& operator= (const HeapBlock&); +}; + +#endif // __JUCE_HEAPBLOCK_JUCEHEADER__ +/********* End of inlined file: juce_HeapBlock.h *********/ + +class MemoryBlock; + +/** + An array of on/off bits, also usable to store large binary integers. + + A BitArray acts like an arbitrarily large integer whose bits can be set or + cleared, and some basic mathematical operations can be done on the number as + a whole. +*/ +class JUCE_API BitArray +{ +public: + + /** Creates an empty BitArray */ + BitArray() throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 32 bits of the array are initialised with this value. + */ + BitArray (const unsigned int value) throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 32 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. + */ + BitArray (const int value) throw(); + + /** Creates a BitArray containing an integer value in its low bits. + + The low 64 bits of the array are initialised with the absolute value + passed in, and its sign is set to reflect the sign of the number. + */ + BitArray (int64 value) throw(); + + /** Creates a copy of another BitArray. */ + BitArray (const BitArray& other) throw(); + + /** Destructor. */ + ~BitArray() throw(); + + /** Copies another BitArray onto this one. */ + const BitArray& operator= (const BitArray& other) throw(); + + /** Two arrays are the same if the same bits are set. */ + bool operator== (const BitArray& other) const throw(); + /** Two arrays are the same if the same bits are set. */ + bool operator!= (const BitArray& other) const throw(); + + /** Clears all bits in the BitArray to 0. */ + void clear() throw(); + + /** Clears a particular bit in the array. */ + void clearBit (const int bitNumber) throw(); + + /** Sets a specified bit to 1. + + If the bit number is high, this will grow the array to accomodate it. + */ + void setBit (const int bitNumber) throw(); + + /** Sets or clears a specified bit. */ + void setBit (const int bitNumber, + const bool shouldBeSet) throw(); + + /** Sets a range of bits to be either on or off. + + @param startBit the first bit to change + @param numBits the number of bits to change + @param shouldBeSet whether to turn these bits on or off + */ + void setRange (int startBit, + int numBits, + const bool shouldBeSet) throw(); + + /** Inserts a bit an a given position, shifting up any bits above it. */ + void insertBit (const int bitNumber, + const bool shouldBeSet) throw(); + + /** Returns the value of a specified bit in the array. + + If the index is out-of-range, the result will be false. + */ + bool operator[] (const int bit) const throw(); + + /** Returns true if no bits are set. */ + bool isEmpty() const throw(); + + /** Returns a range of bits in the array as a new BitArray. + + e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits. + @see getBitRangeAsInt + */ + const BitArray getBitRange (int startBit, int numBits) const throw(); + + /** Returns a range of bits in the array as an integer value. + + e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. + + Asking for more than 32 bits isn't allowed (obviously) - for that, use + getBitRange(). + */ + int getBitRangeAsInt (int startBit, int numBits) const throw(); + + /** Sets a range of bits in the array based on an integer value. + + Copies the given integer into the array, starting at startBit, + and only using up to numBits of the available bits. + */ + void setBitRangeAsInt (int startBit, int numBits, + unsigned int valueToSet) throw(); + + /** Performs a bitwise OR with another BitArray. + + The result ends up in this array. + */ + void orWith (const BitArray& other) throw(); + + /** Performs a bitwise AND with another BitArray. + + The result ends up in this array. + */ + void andWith (const BitArray& other) throw(); + + /** Performs a bitwise XOR with another BitArray. + + The result ends up in this array. + */ + void xorWith (const BitArray& other) throw(); + + /** Adds another BitArray's value to this one. + + Treating the two arrays as large positive integers, this + adds them up and puts the result in this array. + */ + void add (const BitArray& other) throw(); + + /** Subtracts another BitArray's value from this one. + + Treating the two arrays as large positive integers, this + subtracts them and puts the result in this array. + + Note that if the result should be negative, this won't be + handled correctly. + */ + void subtract (const BitArray& other) throw(); + + /** Multiplies another BitArray's value with this one. + + Treating the two arrays as large positive integers, this + multiplies them and puts the result in this array. + */ + void multiplyBy (const BitArray& other) throw(); + + /** Divides another BitArray's value into this one and also produces a remainder. + + Treating the two arrays as large positive integers, this + divides this value by the other, leaving the quotient in this + array, and the remainder is copied into the other BitArray passed in. + */ + void divideBy (const BitArray& divisor, BitArray& remainder) throw(); + + /** Returns the largest value that will divide both this value and the one + passed-in. + */ + const BitArray findGreatestCommonDivisor (BitArray other) const throw(); + + /** Performs a modulo operation on this value. + + The result is stored in this value. + */ + void modulo (const BitArray& divisor) throw(); + + /** Performs a combined exponent and modulo operation. + + This BitArray's value becomes (this ^ exponent) % modulus. + */ + void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); + + /** Performs an inverse modulo on the value. + + i.e. the result is (this ^ -1) mod (modulus). + */ + void inverseModulo (const BitArray& modulus) throw(); + + /** Shifts a section of bits left or right. + + @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). + @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. + */ + void shiftBits (int howManyBitsLeft, + int startBit = 0) throw(); + + /** Does a signed comparison of two BitArrays. + + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compare (const BitArray& other) const throw(); + + /** Compares the magnitudes of two BitArrays, ignoring their signs. + + Return values are: + - 0 if the numbers are the same + - < 0 if this number is smaller than the other + - > 0 if this number is bigger than the other + */ + int compareAbsolute (const BitArray& other) const throw(); + + /** Returns true if the value is less than zero. + + @see setNegative, negate + */ + bool isNegative() const throw(); + + /** Changes the sign of the number to be positive or negative. + + @see isNegative, negate + */ + void setNegative (const bool shouldBeNegative) throw(); + + /** Inverts the sign of the number. + + @see isNegative, setNegative + */ + void negate() throw(); + + /** Counts the total number of set bits in the array. */ + int countNumberOfSetBits() const throw(); + + /** Looks for the index of the next set bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first set bit, + and returns its index. + + If no set bits are found, it returns -1. + */ + int findNextSetBit (int startIndex = 0) const throw(); + + /** Looks for the index of the next clear bit after a given starting point. + + searches from startIndex (inclusive) upwards for the first clear bit, + and returns its index. + */ + int findNextClearBit (int startIndex = 0) const throw(); + + /** Returns the index of the highest set bit in the array. + + If the array is empty, this will return -1. + */ + int getHighestBit() const throw(); + + /** Converts the array to a number string. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + + If minuimumNumCharacters is greater than 0, the returned string will be + padded with leading zeros to reach at least that length. + */ + const String toString (const int base, const int minimumNumCharacters = 1) const throw(); + + /** Converts a number string to an array. + + Any non-valid characters will be ignored. + + Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). + */ + void parseString (const String& text, + const int base) throw(); + + /** Turns the array into a block of binary data. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see loadFromMemoryBlock + */ + const MemoryBlock toMemoryBlock() const throw(); + + /** Copies a block of raw data onto this array. + + The data is arranged as little-endian, so the first byte of data is the low 8 bits + of the array, and so on. + + @see toMemoryBlock + */ + void loadFromMemoryBlock (const MemoryBlock& data) throw(); + + juce_UseDebuggingNewOperator + +private: + void ensureSize (const int numVals) throw(); + HeapBlock values; + int numValues, highestBit; + bool negative; +}; + +#endif // __JUCE_BITARRAY_JUCEHEADER__ +/********* End of inlined file: juce_BitArray.h *********/ + +#endif +#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ + +#endif +#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ + +#endif +#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ + +/********* Start of inlined file: juce_MemoryBlock.h *********/ +#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ +#define __JUCE_MEMORYBLOCK_JUCEHEADER__ + +/** + A class to hold a resizable block of raw data. + +*/ +class JUCE_API MemoryBlock +{ +public: + + /** Create an uninitialised block with 0 size. */ + MemoryBlock() throw(); + + /** Creates a memory block with a given initial size. + + @param initialSize the size of block to create + @param initialiseToZero whether to clear the memory or just leave it uninitialised + */ + MemoryBlock (const int initialSize, + const bool initialiseToZero = false) throw(); + + /** Creates a copy of another memory block. */ + MemoryBlock (const MemoryBlock& other) throw(); + + /** Creates a memory block using a copy of a block of data. + + @param dataToInitialiseFrom some data to copy into this block + @param sizeInBytes how much space to use + */ + MemoryBlock (const void* const dataToInitialiseFrom, + const int sizeInBytes) throw(); + + /** Destructor. */ + ~MemoryBlock() throw(); + + /** Copies another memory block onto this one. + + This block will be resized and copied to exactly match the other one. + */ + const MemoryBlock& operator= (const MemoryBlock& other) throw(); + + /** Compares two memory blocks. + + @returns true only if the two blocks are the same size and have identical contents. + */ + bool operator== (const MemoryBlock& other) const throw(); + + /** Compares two memory blocks. + + @returns true if the two blocks are different sizes or have different contents. + */ + bool operator!= (const MemoryBlock& other) const throw(); + + /** Returns a pointer to the data, casting it to any type of primitive data required. + + Note that the pointer returned will probably become invalid when the + block is resized. + */ + template + operator DataType*() const throw() { return (DataType*) data; } + + /** Returns a void pointer to the data. + + Note that the pointer returned will probably become invalid when the + block is resized. + */ + void* getData() const throw() { return data; } + + /** Returns a byte from the memory block. + + This returns a reference, so you can also use it to set a byte. + */ + char& operator[] (const int offset) const throw() { return data [offset]; } + + /** Returns the block's current allocated size, in bytes. */ + int getSize() const throw() { return size; } + + /** Resizes the memory block. + + This will try to keep as much of the block's current content as it can, + and can optionally be made to clear any new space that gets allocated at + the end of the block. + + @param newSize the new desired size for the block + @param initialiseNewSpaceToZero if the block gets enlarged, this determines + whether to clear the new section or just leave it + uninitialised + @see ensureSize + */ + void setSize (const int newSize, + const bool initialiseNewSpaceToZero = false) throw(); + + /** Increases the block's size only if it's smaller than a given size. + + @param minimumSize if the block is already bigger than this size, no action + will be taken; otherwise it will be increased to this size + @param initialiseNewSpaceToZero if the block gets enlarged, this determines + whether to clear the new section or just leave it + uninitialised + @see setSize + */ + void ensureSize (const int minimumSize, + const bool initialiseNewSpaceToZero = false) throw(); + + /** Fills the entire memory block with a repeated byte value. + + This is handy for clearing a block of memory to zero. + */ + void fillWith (const uint8 valueToUse) throw(); + + /** Adds another block of data to the end of this one. + + This block's size will be increased accordingly. + */ + void append (const void* const data, + const int numBytes) throw(); + + /** Copies data into this MemoryBlock from a memory address. + + @param srcData the memory location of the data to copy into this block + @param destinationOffset the offset in this block at which the data being copied should begin + @param numBytes how much to copy in (if this goes beyond the size of the memory block, + it will be clipped so not to do anything nasty) + */ + void copyFrom (const void* srcData, + int destinationOffset, + int numBytes) throw(); + + /** Copies data from this MemoryBlock to a memory address. + + @param destData the memory location to write to + @param sourceOffset the offset within this block from which the copied data will be read + @param numBytes how much to copy (if this extends beyond the limits of the memory block, + zeros will be used for that portion of the data) + */ + void copyTo (void* destData, + int sourceOffset, + int numBytes) const throw(); + + /** Chops out a section of the block. + + This will remove a section of the memory block and close the gap around it, + shifting any subsequent data downwards and reducing the size of the block. + + If the range specified goes beyond the size of the block, it will be clipped. + */ + void removeSection (int startByte, int numBytesToRemove) throw(); + + /** Attempts to parse the contents of the block as a zero-terminated string of 8-bit + characters in the system's default encoding. */ + const String toString() const throw(); + + /** Parses a string of hexadecimal numbers and writes this data into the memory block. + + The block will be resized to the number of valid bytes read from the string. + Non-hex characters in the string will be ignored. + + @see String::toHexString() + */ + void loadFromHexString (const String& sourceHexString) throw(); + + /** Sets a number of bits in the memory block, treating it as a long binary sequence. */ + void setBitRange (int bitRangeStart, + int numBits, + int binaryNumberToApply) throw(); + + /** Reads a number of bits from the memory block, treating it as one long binary sequence */ + int getBitRange (int bitRangeStart, + int numBitsToRead) const throw(); + + /** Returns a string of characters that represent the binary contents of this block. + + Uses a 64-bit encoding system to allow binary data to be turned into a string + of simple non-extended characters, e.g. for storage in XML. + + @see fromBase64Encoding + */ + const String toBase64Encoding() const throw(); + + /** Takes a string of encoded characters and turns it into binary data. + + The string passed in must have been created by to64BitEncoding(), and this + block will be resized to recreate the original data block. + + @see toBase64Encoding + */ + bool fromBase64Encoding (const String& encodedString) throw(); + + juce_UseDebuggingNewOperator + +private: + + HeapBlock data; + int size; +}; + +#endif // __JUCE_MEMORYBLOCK_JUCEHEADER__ +/********* End of inlined file: juce_MemoryBlock.h *********/ + +#endif +#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__ + +/********* Start of inlined file: juce_OwnedArray.h *********/ +#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__ +#define __JUCE_OWNEDARRAY_JUCEHEADER__ + /** An array designed for holding objects. This holds a list of pointers to objects, and will automatically @@ -4052,6 +5675,920 @@ private: #endif // __JUCE_OWNEDARRAY_JUCEHEADER__ /********* End of inlined file: juce_OwnedArray.h *********/ +#endif +#ifndef __JUCE_PROPERTYSET_JUCEHEADER__ + +/********* Start of inlined file: juce_PropertySet.h *********/ +#ifndef __JUCE_PROPERTYSET_JUCEHEADER__ +#define __JUCE_PROPERTYSET_JUCEHEADER__ + +/********* Start of inlined file: juce_StringPairArray.h *********/ +#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__ +#define __JUCE_STRINGPAIRARRAY_JUCEHEADER__ + +/********* Start of inlined file: juce_StringArray.h *********/ +#ifndef __JUCE_STRINGARRAY_JUCEHEADER__ +#define __JUCE_STRINGARRAY_JUCEHEADER__ + +#ifndef DOXYGEN + // (used in StringArray::appendNumbersToDuplicates) + static const tchar* const defaultPreNumberString = JUCE_T(" ("); + static const tchar* const defaultPostNumberString = JUCE_T(")"); +#endif + +/** + A special array for holding a list of strings. + + @see String, StringPairArray +*/ +class JUCE_API StringArray +{ +public: + + /** Creates an empty string array */ + StringArray() throw(); + + /** Creates a copy of another string array */ + StringArray (const StringArray& other) throw(); + + /** Creates a copy of an array of string literals. + + @param strings an array of strings to add. Null pointers in the array will be + treated as empty strings + @param numberOfStrings how many items there are in the array + */ + StringArray (const juce_wchar** const strings, + const int numberOfStrings) throw(); + + /** Creates a copy of an array of string literals. + + @param strings an array of strings to add. Null pointers in the array will be + treated as empty strings + @param numberOfStrings how many items there are in the array + */ + StringArray (const char** const strings, + const int numberOfStrings) throw(); + + /** Creates a copy of a null-terminated array of string literals. + + Each item from the array passed-in is added, until it encounters a null pointer, + at which point it stops. + */ + StringArray (const juce_wchar** const strings) throw(); + + /** Creates a copy of a null-terminated array of string literals. + + Each item from the array passed-in is added, until it encounters a null pointer, + at which point it stops. + */ + StringArray (const char** const strings) throw(); + + /** Destructor. */ + virtual ~StringArray() throw(); + + /** Copies the contents of another string array into this one */ + const StringArray& operator= (const StringArray& other) throw(); + + /** Compares two arrays. + + Comparisons are case-sensitive. + + @returns true only if the other array contains exactly the same strings in the same order + */ + bool operator== (const StringArray& other) const throw(); + + /** Compares two arrays. + + Comparisons are case-sensitive. + + @returns false if the other array contains exactly the same strings in the same order + */ + bool operator!= (const StringArray& other) const throw(); + + /** Returns the number of strings in the array */ + inline int size() const throw() { return strings.size(); }; + + /** Returns one of the strings from the array. + + If the index is out-of-range, an empty string is returned. + + Obviously the reference returned shouldn't be stored for later use, as the + string it refers to may disappear when the array changes. + */ + const String& operator[] (const int index) const throw(); + + /** Searches for a string in the array. + + The comparison will be case-insensitive if the ignoreCase parameter is true. + + @returns true if the string is found inside the array + */ + bool contains (const String& stringToLookFor, + const bool ignoreCase = false) const throw(); + + /** Searches for a string in the array. + + The comparison will be case-insensitive if the ignoreCase parameter is true. + + @param stringToLookFor the string to try to find + @param ignoreCase whether the comparison should be case-insensitive + @param startIndex the first index to start searching from + @returns the index of the first occurrence of the string in this array, + or -1 if it isn't found. + */ + int indexOf (const String& stringToLookFor, + const bool ignoreCase = false, + int startIndex = 0) const throw(); + + /** Appends a string at the end of the array. */ + void add (const String& stringToAdd) throw(); + + /** Inserts a string into the array. + + This will insert a string into the array at the given index, moving + up the other elements to make room for it. + If the index is less than zero or greater than the size of the array, + the new string will be added to the end of the array. + */ + void insert (const int index, + const String& stringToAdd) throw(); + + /** Adds a string to the array as long as it's not already in there. + + The search can optionally be case-insensitive. + */ + void addIfNotAlreadyThere (const String& stringToAdd, + const bool ignoreCase = false) throw(); + + /** Replaces one of the strings in the array with another one. + + If the index is higher than the array's size, the new string will be + added to the end of the array; if it's less than zero nothing happens. + */ + void set (const int index, + const String& newString) throw(); + + /** Appends some strings from another array to the end of this one. + + @param other the array to add + @param startIndex the first element of the other array to add + @param numElementsToAdd the maximum number of elements to add (if this is + less than zero, they are all added) + */ + void addArray (const StringArray& other, + int startIndex = 0, + int numElementsToAdd = -1) throw(); + + /** Breaks up a string into tokens and adds them to this array. + + This will tokenise the given string using whitespace characters as the + token delimiters, and will add these tokens to the end of the array. + + @returns the number of tokens added + */ + int addTokens (const tchar* const stringToTokenise, + const bool preserveQuotedStrings) throw(); + + /** Breaks up a string into tokens and adds them to this array. + + This will tokenise the given string (using the string passed in to define the + token delimiters), and will add these tokens to the end of the array. + + @param stringToTokenise the string to tokenise + @param breakCharacters a string of characters, any of which will be considered + to be a token delimiter. + @param quoteCharacters if this string isn't empty, it defines a set of characters + which are treated as quotes. Any text occurring + between quotes is not broken up into tokens. + @returns the number of tokens added + */ + int addTokens (const tchar* const stringToTokenise, + const tchar* breakCharacters, + const tchar* quoteCharacters) throw(); + + /** Breaks up a string into lines and adds them to this array. + + This breaks a string down into lines separated by \\n or \\r\\n, and adds each line + to the array. Line-break characters are omitted from the strings that are added to + the array. + */ + int addLines (const tchar* stringToBreakUp) throw(); + + /** Removes all elements from the array. */ + void clear() throw(); + + /** Removes a string from the array. + + If the index is out-of-range, no action will be taken. + */ + void remove (const int index) throw(); + + /** Finds a string in the array and removes it. + + This will remove the first occurrence of the given string from the array. The + comparison may be case-insensitive depending on the ignoreCase parameter. + */ + void removeString (const String& stringToRemove, + const bool ignoreCase = false) throw(); + + /** Removes any duplicated elements from the array. + + If any string appears in the array more than once, only the first occurrence of + it will be retained. + + @param ignoreCase whether to use a case-insensitive comparison + */ + void removeDuplicates (const bool ignoreCase) throw(); + + /** Removes empty strings from the array. + + @param removeWhitespaceStrings if true, strings that only contain whitespace + characters will also be removed + */ + void removeEmptyStrings (const bool removeWhitespaceStrings = true) throw(); + + /** Moves one of the strings to a different position. + + This will move the string to a specified index, shuffling along + any intervening elements as required. + + So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling + move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. + + @param currentIndex the index of the value to be moved. If this isn't a + valid index, then nothing will be done + @param newIndex the index at which you'd like this value to end up. If this + is less than zero, the value will be moved to the end + of the array + */ + void move (const int currentIndex, int newIndex) throw(); + + /** Deletes any whitespace characters from the starts and ends of all the strings. */ + void trim() throw(); + + /** Adds numbers to the strings in the array, to make each string unique. + + This will add numbers to the ends of groups of similar strings. + e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)" + + @param ignoreCaseWhenComparing whether the comparison used is case-insensitive + @param appendNumberToFirstInstance whether the first of a group of similar strings + also has a number appended to it. + @param preNumberString when adding a number, this string is added before the number + @param postNumberString this string is appended after any numbers that are added + */ + void appendNumbersToDuplicates (const bool ignoreCaseWhenComparing, + const bool appendNumberToFirstInstance, + const tchar* const preNumberString = defaultPreNumberString, + const tchar* const postNumberString = defaultPostNumberString) throw(); + + /** Joins the strings in the array together into one string. + + This will join a range of elements from the array into a string, separating + them with a given string. + + e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c". + + @param separatorString the string to insert between all the strings + @param startIndex the first element to join + @param numberOfElements how many elements to join together. If this is less + than zero, all available elements will be used. + */ + const String joinIntoString (const String& separatorString, + int startIndex = 0, + int numberOfElements = -1) const throw(); + + /** Sorts the array into alphabetical order. + + @param ignoreCase if true, the comparisons used will be case-sensitive. + */ + void sort (const bool ignoreCase) throw(); + + /** Reduces the amount of storage being used by the array. + + Arrays typically allocate slightly more storage than they need, and after + removing elements, they may have quite a lot of unused space allocated. + This method will reduce the amount of allocated storage to a minimum. + */ + void minimiseStorageOverheads() throw(); + + juce_UseDebuggingNewOperator + +private: + OwnedArray strings; +}; + +#endif // __JUCE_STRINGARRAY_JUCEHEADER__ +/********* End of inlined file: juce_StringArray.h *********/ + +/** + A container for holding a set of strings which are keyed by another string. + + @see StringArray +*/ +class JUCE_API StringPairArray +{ +public: + + /** Creates an empty array */ + StringPairArray (const bool ignoreCaseWhenComparingKeys = true) throw(); + + /** Creates a copy of another array */ + StringPairArray (const StringPairArray& other) throw(); + + /** Destructor. */ + ~StringPairArray() throw(); + + /** Copies the contents of another string array into this one */ + const StringPairArray& operator= (const StringPairArray& other) throw(); + + /** Compares two arrays. + + Comparisons are case-sensitive. + + @returns true only if the other array contains exactly the same strings with the same keys + */ + bool operator== (const StringPairArray& other) const throw(); + + /** Compares two arrays. + + Comparisons are case-sensitive. + + @returns false if the other array contains exactly the same strings with the same keys + */ + bool operator!= (const StringPairArray& other) const throw(); + + /** Finds the value corresponding to a key string. + + If no such key is found, this will just return an empty string. To check whether + a given key actually exists (because it might actually be paired with an empty string), use + the getAllKeys() method to obtain a list. + + Obviously the reference returned shouldn't be stored for later use, as the + string it refers to may disappear when the array changes. + + @see getValue + */ + const String& operator[] (const String& key) const throw(); + + /** Finds the value corresponding to a key string. + + If no such key is found, this will just return the value provided as a default. + + @see operator[] + */ + const String getValue (const String& key, const String& defaultReturnValue) const; + + /** Returns a list of all keys in the array. */ + const StringArray& getAllKeys() const throw() { return keys; } + + /** Returns a list of all values in the array. */ + const StringArray& getAllValues() const throw() { return values; } + + /** Returns the number of strings in the array */ + inline int size() const throw() { return keys.size(); }; + + /** Adds or amends a key/value pair. + + If a value already exists with this key, its value will be overwritten, + otherwise the key/value pair will be added to the array. + */ + void set (const String& key, + const String& value) throw(); + + /** Adds the items from another array to this one. + + This is equivalent to using set() to add each of the pairs from the other array. + */ + void addArray (const StringPairArray& other); + + /** Removes all elements from the array. */ + void clear() throw(); + + /** Removes a string from the array based on its key. + + If the key isn't found, nothing will happen. + */ + void remove (const String& key) throw(); + + /** Removes a string from the array based on its index. + + If the index is out-of-range, no action will be taken. + */ + void remove (const int index) throw(); + + /** Indicates whether to use a case-insensitive search when looking up a key string. + */ + void setIgnoresCase (const bool shouldIgnoreCase) throw(); + + /** Returns a descriptive string containing the items. + + This is handy for dumping the contents of an array. + */ + const String getDescription() const; + + /** Reduces the amount of storage being used by the array. + + Arrays typically allocate slightly more storage than they need, and after + removing elements, they may have quite a lot of unused space allocated. + This method will reduce the amount of allocated storage to a minimum. + */ + void minimiseStorageOverheads() throw(); + + juce_UseDebuggingNewOperator + +private: + StringArray keys, values; + bool ignoreCase; +}; + +#endif // __JUCE_STRINGPAIRARRAY_JUCEHEADER__ +/********* End of inlined file: juce_StringPairArray.h *********/ + +/********* Start of inlined file: juce_XmlElement.h *********/ +#ifndef __JUCE_XMLELEMENT_JUCEHEADER__ +#define __JUCE_XMLELEMENT_JUCEHEADER__ + +/********* Start of inlined file: juce_OutputStream.h *********/ +#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__ +#define __JUCE_OUTPUTSTREAM_JUCEHEADER__ + +/********* Start of inlined file: juce_InputStream.h *********/ +#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__ +#define __JUCE_INPUTSTREAM_JUCEHEADER__ + +/** The base class for streams that read data. + + Input and output streams are used throughout the library - subclasses can override + some or all of the virtual functions to implement their behaviour. + + @see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream +*/ +class JUCE_API InputStream +{ +public: + /** Destructor. */ + virtual ~InputStream() {} + + /** Returns the total number of bytes available for reading in this stream. + + Note that this is the number of bytes available from the start of the + stream, not from the current position. + + If the size of the stream isn't actually known, this may return -1. + */ + virtual int64 getTotalLength() = 0; + + /** Returns true if the stream has no more data to read. */ + virtual bool isExhausted() = 0; + + /** Reads a set of bytes from the stream into a memory buffer. + + This is the only read method that subclasses actually need to implement, as the + InputStream base class implements the other read methods in terms of this one (although + it's often more efficient for subclasses to implement them directly). + + @param destBuffer the destination buffer for the data + @param maxBytesToRead the maximum number of bytes to read - make sure the + memory block passed in is big enough to contain this + many bytes. + + @returns the actual number of bytes that were read, which may be less than + maxBytesToRead if the stream is exhausted before it gets that far + */ + virtual int read (void* destBuffer, + int maxBytesToRead) = 0; + + /** Reads a byte from the stream. + + If the stream is exhausted, this will return zero. + + @see OutputStream::writeByte + */ + virtual char readByte(); + + /** Reads a boolean from the stream. + + The bool is encoded as a single byte - 1 for true, 0 for false. + + If the stream is exhausted, this will return false. + + @see OutputStream::writeBool + */ + virtual bool readBool(); + + /** Reads two bytes from the stream as a little-endian 16-bit value. + + If the next two bytes read are byte1 and byte2, this returns + (byte1 | (byte2 << 8)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeShort, readShortBigEndian + */ + virtual short readShort(); + + /** Reads two bytes from the stream as a little-endian 16-bit value. + + If the next two bytes read are byte1 and byte2, this returns + (byte2 | (byte1 << 8)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeShortBigEndian, readShort + */ + virtual short readShortBigEndian(); + + /** Reads four bytes from the stream as a little-endian 32-bit value. + + If the next four bytes are byte1 to byte4, this returns + (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeInt, readIntBigEndian + */ + virtual int readInt(); + + /** Reads four bytes from the stream as a big-endian 32-bit value. + + If the next four bytes are byte1 to byte4, this returns + (byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeIntBigEndian, readInt + */ + virtual int readIntBigEndian(); + + /** Reads eight bytes from the stream as a little-endian 64-bit value. + + If the next eight bytes are byte1 to byte8, this returns + (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeInt64, readInt64BigEndian + */ + virtual int64 readInt64(); + + /** Reads eight bytes from the stream as a big-endian 64-bit value. + + If the next eight bytes are byte1 to byte8, this returns + (byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)). + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeInt64BigEndian, readInt64 + */ + virtual int64 readInt64BigEndian(); + + /** Reads four bytes as a 32-bit floating point value. + + The raw 32-bit encoding of the float is read from the stream as a little-endian int. + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeFloat, readDouble + */ + virtual float readFloat(); + + /** Reads four bytes as a 32-bit floating point value. + + The raw 32-bit encoding of the float is read from the stream as a big-endian int. + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeFloatBigEndian, readDoubleBigEndian + */ + virtual float readFloatBigEndian(); + + /** Reads eight bytes as a 64-bit floating point value. + + The raw 64-bit encoding of the double is read from the stream as a little-endian int64. + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeDouble, readFloat + */ + virtual double readDouble(); + + /** Reads eight bytes as a 64-bit floating point value. + + The raw 64-bit encoding of the double is read from the stream as a big-endian int64. + + If the stream is exhausted partway through reading the bytes, this will return zero. + + @see OutputStream::writeDoubleBigEndian, readFloatBigEndian + */ + virtual double readDoubleBigEndian(); + + /** Reads an encoded 32-bit number from the stream using a space-saving compressed format. + + For small values, this is more space-efficient than using readInt() and OutputStream::writeInt() + + The format used is: number of significant bytes + up to 4 bytes in little-endian order. + + @see OutputStream::writeCompressedInt() + */ + virtual int readCompressedInt(); + + /** Reads a UTF8 string from the stream, up to the next linefeed or carriage return. + + This will read up to the next "\n" or "\r\n" or end-of-stream. + + After this call, the stream's position will be left pointing to the next character + following the line-feed, but the linefeeds aren't included in the string that + is returned. + */ + virtual const String readNextLine(); + + /** Reads a zero-terminated UTF8 string from the stream. + + This will read characters from the stream until it hits a zero character or + end-of-stream. + + @see OutputStream::writeString, readEntireStreamAsString + */ + virtual const String readString(); + + /** Tries to read the whole stream and turn it into a string. + + This will read from the stream's current position until the end-of-stream, and + will try to make an educated guess about whether it's unicode or an 8-bit encoding. + */ + virtual const String readEntireStreamAsString(); + + /** Reads from the stream and appends the data to a MemoryBlock. + + @param destBlock the block to append the data onto + @param maxNumBytesToRead if this is a positive value, it sets a limit to the number + of bytes that will be read - if it's negative, data + will be read until the stream is exhausted. + @returns the number of bytes that were added to the memory block + */ + virtual int readIntoMemoryBlock (MemoryBlock& destBlock, + int maxNumBytesToRead = -1); + + /** Returns the offset of the next byte that will be read from the stream. + + @see setPosition + */ + virtual int64 getPosition() = 0; + + /** Tries to move the current read position of the stream. + + The position is an absolute number of bytes from the stream's start. + + Some streams might not be able to do this, in which case they should do + nothing and return false. Others might be able to manage it by resetting + themselves and skipping to the correct position, although this is + obviously a bit slow. + + @returns true if the stream manages to reposition itself correctly + @see getPosition + */ + virtual bool setPosition (int64 newPosition) = 0; + + /** Reads and discards a number of bytes from the stream. + + Some input streams might implement this efficiently, but the base + class will just keep reading data until the requisite number of bytes + have been done. + */ + virtual void skipNextBytes (int64 numBytesToSkip); + + juce_UseDebuggingNewOperator + +protected: + + InputStream() throw() {} +}; + +#endif // __JUCE_INPUTSTREAM_JUCEHEADER__ +/********* End of inlined file: juce_InputStream.h *********/ + +/** + The base class for streams that write data to some kind of destination. + + Input and output streams are used throughout the library - subclasses can override + some or all of the virtual functions to implement their behaviour. + + @see InputStream, MemoryOutputStream, FileOutputStream +*/ +class JUCE_API OutputStream +{ +public: + /** Destructor. + + Some subclasses might want to do things like call flush() during their + destructors. + */ + virtual ~OutputStream(); + + /** If the stream is using a buffer, this will ensure it gets written + out to the destination. */ + virtual void flush() = 0; + + /** Tries to move the stream's output position. + + Not all streams will be able to seek to a new position - this will return + false if it fails to work. + + @see getPosition + */ + virtual bool setPosition (int64 newPosition) = 0; + + /** Returns the stream's current position. + + @see setPosition + */ + virtual int64 getPosition() = 0; + + /** Writes a block of data to the stream. + + When creating a subclass of OutputStream, this is the only write method + that needs to be overloaded - the base class has methods for writing other + types of data which use this to do the work. + + @returns false if the write operation fails for some reason + */ + virtual bool write (const void* dataToWrite, + int howManyBytes) = 0; + + /** Writes a single byte to the stream. + + @see InputStream::readByte + */ + virtual void writeByte (char byte); + + /** Writes a boolean to the stream. + + This is encoded as a byte - either 1 or 0. + + @see InputStream::readBool + */ + virtual void writeBool (bool boolValue); + + /** Writes a 16-bit integer to the stream in a little-endian byte order. + + This will write two bytes to the stream: (value & 0xff), then (value >> 8). + + @see InputStream::readShort + */ + virtual void writeShort (short value); + + /** Writes a 16-bit integer to the stream in a big-endian byte order. + + This will write two bytes to the stream: (value >> 8), then (value & 0xff). + + @see InputStream::readShortBigEndian + */ + virtual void writeShortBigEndian (short value); + + /** Writes a 32-bit integer to the stream in a little-endian byte order. + + @see InputStream::readInt + */ + virtual void writeInt (int value); + + /** Writes a 32-bit integer to the stream in a big-endian byte order. + + @see InputStream::readIntBigEndian + */ + virtual void writeIntBigEndian (int value); + + /** Writes a 64-bit integer to the stream in a little-endian byte order. + + @see InputStream::readInt64 + */ + virtual void writeInt64 (int64 value); + + /** Writes a 64-bit integer to the stream in a big-endian byte order. + + @see InputStream::readInt64BigEndian + */ + virtual void writeInt64BigEndian (int64 value); + + /** Writes a 32-bit floating point value to the stream. + + The binary 32-bit encoding of the float is written as a little-endian int. + + @see InputStream::readFloat + */ + virtual void writeFloat (float value); + + /** Writes a 32-bit floating point value to the stream. + + The binary 32-bit encoding of the float is written as a big-endian int. + + @see InputStream::readFloatBigEndian + */ + virtual void writeFloatBigEndian (float value); + + /** Writes a 64-bit floating point value to the stream. + + The eight raw bytes of the double value are written out as a little-endian 64-bit int. + + @see InputStream::readDouble + */ + virtual void writeDouble (double value); + + /** Writes a 64-bit floating point value to the stream. + + The eight raw bytes of the double value are written out as a big-endian 64-bit int. + + @see InputStream::readDoubleBigEndian + */ + virtual void writeDoubleBigEndian (double value); + + /** Writes a condensed encoding of a 32-bit integer. + + If you're storing a lot of integers which are unlikely to have very large values, + this can save a lot of space, because values under 0xff will only take up 2 bytes, + under 0xffff only 3 bytes, etc. + + The format used is: number of significant bytes + up to 4 bytes in little-endian order. + + @see InputStream::readCompressedInt + */ + virtual void writeCompressedInt (int value); + + /** Stores a string in the stream. + + This isn't the method to use if you're trying to append text to the end of a + text-file! It's intended for storing a string for later retrieval + by InputStream::readString. + + It writes the string to the stream as UTF8, with a null character terminating it. + + For appending text to a file, instead use writeText, printf, or operator<< + + @see InputStream::readString, writeText, printf, operator<< + */ + virtual void writeString (const String& text); + + /** Writes a string of text to the stream. + + It can either write it as 8-bit system-encoded characters, or as unicode, and + can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this + should only be done at the start of a file). + + The method also replaces '\\n' characters in the text with '\\r\\n'. + */ + virtual void writeText (const String& text, + const bool asUnicode, + const bool writeUnicodeHeaderBytes); + + /** Writes a string of text to the stream. + + @see writeText + */ + virtual void printf (const char* format, ...); + + /** Reads data from an input stream and writes it to this stream. + + @param source the stream to read from + @param maxNumBytesToWrite the number of bytes to read from the stream (if this is + less than zero, it will keep reading until the input + is exhausted) + */ + virtual int writeFromInputStream (InputStream& source, + int maxNumBytesToWrite); + + /** Writes a number to the stream as 8-bit characters in the default system encoding. */ + virtual OutputStream& operator<< (const int number); + + /** Writes a number to the stream as 8-bit characters in the default system encoding. */ + virtual OutputStream& operator<< (const double number); + + /** Writes a character to the stream. */ + virtual OutputStream& operator<< (const char character); + + /** Writes a null-terminated string to the stream. */ + virtual OutputStream& operator<< (const char* const text); + + /** Writes a null-terminated unicode text string to the stream, converting it + to 8-bit characters in the default system encoding. */ + virtual OutputStream& operator<< (const juce_wchar* const text); + + /** Writes a string to the stream as 8-bit characters in the default system encoding. */ + virtual OutputStream& operator<< (const String& text); + + juce_UseDebuggingNewOperator + +protected: + + OutputStream() throw(); +}; + +#endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ +/********* End of inlined file: juce_OutputStream.h *********/ + +/********* Start of inlined file: juce_File.h *********/ +#ifndef __JUCE_FILE_JUCEHEADER__ +#define __JUCE_FILE_JUCEHEADER__ + /********* Start of inlined file: juce_Time.h *********/ #ifndef __JUCE_TIME_JUCEHEADER__ #define __JUCE_TIME_JUCEHEADER__ @@ -4574,1558 +7111,6 @@ private: #endif // __JUCE_TIME_JUCEHEADER__ /********* End of inlined file: juce_Time.h *********/ -/********* Start of inlined file: juce_StringArray.h *********/ -#ifndef __JUCE_STRINGARRAY_JUCEHEADER__ -#define __JUCE_STRINGARRAY_JUCEHEADER__ - -/********* Start of inlined file: juce_VoidArray.h *********/ -#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ -#define __JUCE_VOIDARRAY_JUCEHEADER__ - -/********* Start of inlined file: juce_Array.h *********/ -#ifndef __JUCE_ARRAY_JUCEHEADER__ -#define __JUCE_ARRAY_JUCEHEADER__ - -/** - Holds a list of primitive objects, such as ints, doubles, or pointers. - - Examples of arrays are: Array or Array - - Note that when holding pointers to objects, the array doesn't take any ownership - of the objects - for doing this, see the OwnedArray class or the ReferenceCountedArray class. - - If you're using a class or struct as the element type, it must be - capable of being copied or moved with a straightforward memcpy, rather than - needing construction and destruction code. - - For holding lists of strings, use the specialised class StringArray. - - To make all the array's methods thread-safe, pass in "CriticalSection" as the templated - TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection. - - @see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection -*/ -template -class Array -{ -public: - - /** Creates an empty array. - - @param granularity this is the size of increment by which the internal storage - used by the array will grow. Only change it from the default if you know the - array is going to be very big and needs to be able to grow efficiently. - */ - Array (const int granularity = juceDefaultArrayGranularity) throw() - : data (granularity), - numUsed (0) - { - } - - /** Creates a copy of another array. - @param other the array to copy - */ - Array (const Array& other) throw() - : data (other.data.granularity) - { - other.lockArray(); - numUsed = other.numUsed; - data.setAllocatedSize (other.numUsed); - memcpy (data.elements, other.data.elements, numUsed * sizeof (ElementType)); - other.unlockArray(); - } - - /** Initalises from a null-terminated C array of values. - - @param values the array to copy from - */ - Array (const ElementType* values) throw() - : data (juceDefaultArrayGranularity), - numUsed (0) - { - while (*values != 0) - add (*values++); - } - - /** Initalises from a C array of values. - - @param values the array to copy from - @param numValues the number of values in the array - */ - Array (const ElementType* values, int numValues) throw() - : data (juceDefaultArrayGranularity), - numUsed (numValues) - { - data.setAllocatedSize (numValues); - memcpy (data.elements, values, numValues * sizeof (ElementType)); - } - - /** Destructor. */ - ~Array() throw() - { - } - - /** Copies another array. - @param other the array to copy - */ - const Array & operator= (const Array & other) throw() - { - if (this != &other) - { - other.lockArray(); - lock.enter(); - - data.granularity = other.data.granularity; - data.ensureAllocatedSize (other.size()); - numUsed = other.numUsed; - memcpy (data.elements, other.data.elements, numUsed * sizeof (ElementType)); - minimiseStorageOverheads(); - - lock.exit(); - other.unlockArray(); - } - - return *this; - } - - /** Compares this array to another one. - Two arrays are considered equal if they both contain the same set of - elements, in the same order. - @param other the other array to compare with - */ - template - bool operator== (const OtherArrayType& other) const throw() - { - lock.enter(); - - if (numUsed != other.numUsed) - { - lock.exit(); - return false; - } - - for (int i = numUsed; --i >= 0;) - { - if (data.elements [i] != other.data.elements [i]) - { - lock.exit(); - return false; - } - } - - lock.exit(); - return true; - } - - /** Compares this array to another one. - Two arrays are considered equal if they both contain the same set of - elements, in the same order. - @param other the other array to compare with - */ - template - bool operator!= (const OtherArrayType& other) const throw() - { - return ! operator== (other); - } - - /** Removes all elements from the array. - This will remove all the elements, and free any storage that the array is - using. To clear the array without freeing the storage, use the clearQuick() - method instead. - - @see clearQuick - */ - void clear() throw() - { - lock.enter(); - data.setAllocatedSize (0); - numUsed = 0; - lock.exit(); - } - - /** Removes all elements from the array without freeing the array's allocated storage. - - @see clear - */ - void clearQuick() throw() - { - lock.enter(); - numUsed = 0; - lock.exit(); - } - - /** Returns the current number of elements in the array. - */ - inline int size() const throw() - { - return numUsed; - } - - /** Returns one of the elements in the array. - If the index passed in is beyond the range of valid elements, this - will return zero. - - If you're certain that the index will always be a valid element, you - can call getUnchecked() instead, which is faster. - - @param index the index of the element being requested (0 is the first element in the array) - @see getUnchecked, getFirst, getLast - */ - inline ElementType operator[] (const int index) const throw() - { - lock.enter(); - const ElementType result = (((unsigned int) index) < (unsigned int) numUsed) - ? data.elements [index] - : ElementType(); - lock.exit(); - - return result; - } - - /** Returns one of the elements in the array, without checking the index passed in. - - Unlike the operator[] method, this will try to return an element without - checking that the index is within the bounds of the array, so should only - be used when you're confident that it will always be a valid index. - - @param index the index of the element being requested (0 is the first element in the array) - @see operator[], getFirst, getLast - */ - inline ElementType getUnchecked (const int index) const throw() - { - lock.enter(); - jassert (((unsigned int) index) < (unsigned int) numUsed); - const ElementType result = data.elements [index]; - lock.exit(); - - return result; - } - - /** Returns a direct reference to one of the elements in the array, without checking the index passed in. - - This is like getUnchecked, but returns a direct reference to the element, so that - you can alter it directly. Obviously this can be dangerous, so only use it when - absolutely necessary. - - @param index the index of the element being requested (0 is the first element in the array) - @see operator[], getFirst, getLast - */ - inline ElementType& getReference (const int index) const throw() - { - lock.enter(); - jassert (((unsigned int) index) < (unsigned int) numUsed); - ElementType& result = data.elements [index]; - lock.exit(); - return result; - } - - /** Returns the first element in the array, or 0 if the array is empty. - - @see operator[], getUnchecked, getLast - */ - inline ElementType getFirst() const throw() - { - lock.enter(); - const ElementType result = (numUsed > 0) ? data.elements [0] - : ElementType(); - lock.exit(); - - return result; - } - - /** Returns the last element in the array, or 0 if the array is empty. - - @see operator[], getUnchecked, getFirst - */ - inline ElementType getLast() const throw() - { - lock.enter(); - const ElementType result = (numUsed > 0) ? data.elements [numUsed - 1] - : ElementType(); - lock.exit(); - - return result; - } - - /** Finds the index of the first element which matches the value passed in. - - This will search the array for the given object, and return the index - of its first occurrence. If the object isn't found, the method will return -1. - - @param elementToLookFor the value or object to look for - @returns the index of the object, or -1 if it's not found - */ - int indexOf (const ElementType elementToLookFor) const throw() - { - int result = -1; - - lock.enter(); - const ElementType* e = data.elements; - - for (int i = numUsed; --i >= 0;) - { - if (elementToLookFor == *e) - { - result = (int) (e - data.elements); - break; - } - - ++e; - } - - lock.exit(); - return result; - } - - /** Returns true if the array contains at least one occurrence of an object. - - @param elementToLookFor the value or object to look for - @returns true if the item is found - */ - bool contains (const ElementType elementToLookFor) const throw() - { - lock.enter(); - - const ElementType* e = data.elements; - int num = numUsed; - - while (num >= 4) - { - if (*e == elementToLookFor - || *++e == elementToLookFor - || *++e == elementToLookFor - || *++e == elementToLookFor) - { - lock.exit(); - return true; - } - - num -= 4; - ++e; - } - - while (num > 0) - { - if (elementToLookFor == *e) - { - lock.exit(); - return true; - } - - --num; - ++e; - } - - lock.exit(); - return false; - } - - /** Appends a new element at the end of the array. - - @param newElement the new object to add to the array - @see set, insert, addIfNotAlreadyThere, addSorted, addArray - */ - void add (const ElementType newElement) throw() - { - lock.enter(); - data.ensureAllocatedSize (numUsed + 1); - data.elements [numUsed++] = newElement; - lock.exit(); - } - - /** Inserts a new element into the array at a given position. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the new element should be - inserted (pass in -1 to add it to the end) - @param newElement the new object to add to the array - @see add, addSorted, set - */ - void insert (int indexToInsertAt, const ElementType newElement) throw() - { - lock.enter(); - data.ensureAllocatedSize (numUsed + 1); - - if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) - { - ElementType* const insertPos = data.elements + indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - - if (numberToMove > 0) - memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType)); - - *insertPos = newElement; - ++numUsed; - } - else - { - data.elements [numUsed++] = newElement; - } - - lock.exit(); - } - - /** Inserts multiple copies of an element into the array at a given position. - - If the index is less than 0 or greater than the size of the array, the - element will be added to the end of the array. - Otherwise, it will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the new element should be inserted - @param newElement the new object to add to the array - @param numberOfTimesToInsertIt how many copies of the value to insert - @see insert, add, addSorted, set - */ - void insertMultiple (int indexToInsertAt, const ElementType newElement, - int numberOfTimesToInsertIt) throw() - { - if (numberOfTimesToInsertIt > 0) - { - lock.enter(); - data.ensureAllocatedSize (numUsed + numberOfTimesToInsertIt); - - if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) - { - ElementType* insertPos = data.elements + indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - - memmove (insertPos + numberOfTimesToInsertIt, insertPos, numberToMove * sizeof (ElementType)); - numUsed += numberOfTimesToInsertIt; - - while (--numberOfTimesToInsertIt >= 0) - *insertPos++ = newElement; - } - else - { - while (--numberOfTimesToInsertIt >= 0) - data.elements [numUsed++] = newElement; - } - - lock.exit(); - } - } - - /** Inserts an array of values into this array at a given position. - - If the index is less than 0 or greater than the size of the array, the - new elements will be added to the end of the array. - Otherwise, they will be inserted into the array, moving all the later elements - along to make room. - - @param indexToInsertAt the index at which the first new element should be inserted - @param newElements the new values to add to the array - @param numberOfElements how many items are in the array - @see insert, add, addSorted, set - */ - void insertArray (int indexToInsertAt, - const ElementType* newElements, - int numberOfElements) throw() - { - if (numberOfElements > 0) - { - lock.enter(); - data.ensureAllocatedSize (numUsed + numberOfElements); - - if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed) - { - ElementType* insertPos = data.elements + indexToInsertAt; - const int numberToMove = numUsed - indexToInsertAt; - - memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType)); - numUsed += numberOfElements; - - while (--numberOfElements >= 0) - *insertPos++ = *newElements++; - } - else - { - while (--numberOfElements >= 0) - data.elements [numUsed++] = *newElements++; - } - - lock.exit(); - } - } - - /** Appends a new element at the end of the array as long as the array doesn't - already contain it. - - If the array already contains an element that matches the one passed in, nothing - will be done. - - @param newElement the new object to add to the array - */ - void addIfNotAlreadyThere (const ElementType newElement) throw() - { - lock.enter(); - - if (! contains (newElement)) - add (newElement); - - lock.exit(); - } - - /** Replaces an element with a new value. - - If the index is less than zero, this method does nothing. - If the index is beyond the end of the array, the item is added to the end of the array. - - @param indexToChange the index whose value you want to change - @param newValue the new value to set for this index. - @see add, insert - */ - void set (const int indexToChange, - const ElementType newValue) throw() - { - jassert (indexToChange >= 0); - - if (indexToChange >= 0) - { - lock.enter(); - - if (indexToChange < numUsed) - { - data.elements [indexToChange] = newValue; - } - else - { - data.ensureAllocatedSize (numUsed + 1); - data.elements [numUsed++] = newValue; - } - - lock.exit(); - } - } - - /** Replaces an element with a new value without doing any bounds-checking. - - This just sets a value directly in the array's internal storage, so you'd - better make sure it's in range! - - @param indexToChange the index whose value you want to change - @param newValue the new value to set for this index. - @see set, getUnchecked - */ - void setUnchecked (const int indexToChange, - const ElementType newValue) throw() - { - lock.enter(); - jassert (((unsigned int) indexToChange) < (unsigned int) numUsed); - data.elements [indexToChange] = newValue; - lock.exit(); - } - - /** Adds elements from an array to the end of this array. - - @param elementsToAdd the array of elements to add - @param numElementsToAdd how many elements are in this other array - @see add - */ - void addArray (const ElementType* elementsToAdd, - int numElementsToAdd) throw() - { - lock.enter(); - - if (numElementsToAdd > 0) - { - data.ensureAllocatedSize (numUsed + numElementsToAdd); - - while (--numElementsToAdd >= 0) - data.elements [numUsed++] = *elementsToAdd++; - } - - lock.exit(); - } - - /** This swaps the contents of this array with those of another array. - - If you need to exchange two arrays, this is vastly quicker than using copy-by-value - because it just swaps their internal pointers. - */ - template - void swapWithArray (OtherArrayType& otherArray) throw() - { - lock.enter(); - otherArray.lock.enter(); - swapVariables (numUsed, otherArray.numUsed); - swapVariables (data.elements, otherArray.data.elements); - swapVariables (data.numAllocated, otherArray.data.numAllocated); - otherArray.lock.exit(); - lock.exit(); - } - - /** Adds elements from another array to the end of this array. - - @param arrayToAddFrom the array from which to copy the elements - @param startIndex the first element of the other array to start copying from - @param numElementsToAdd how many elements to add from the other array. If this - value is negative or greater than the number of available elements, - all available elements will be copied. - @see add - */ - template - void addArray (const OtherArrayType& arrayToAddFrom, - int startIndex = 0, - int numElementsToAdd = -1) throw() - { - arrayToAddFrom.lockArray(); - lock.enter(); - jassert (this != &arrayToAddFrom); - - if (startIndex < 0) - { - jassertfalse - startIndex = 0; - } - - if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size()) - numElementsToAdd = arrayToAddFrom.size() - startIndex; - - addArray ((const ElementType*) (arrayToAddFrom.data.elements + startIndex), numElementsToAdd); - - lock.exit(); - arrayToAddFrom.unlockArray(); - } - - /** Inserts a new element into the array, assuming that the array is sorted. - - This will use a comparator to find the position at which the new element - should go. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param newElement the new element to insert to the array - @see add, sort - */ - template - void addSorted (ElementComparator& comparator, - const ElementType newElement) throw() - { - lock.enter(); - insert (findInsertIndexInSortedArray (comparator, data.elements, newElement, 0, numUsed), newElement); - lock.exit(); - } - - /** Finds the index of an element in the array, assuming that the array is sorted. - - This will use a comparator to do a binary-chop to find the index of the given - element, if it exists. If the array isn't sorted, the behaviour of this - method will be unpredictable. - - @param comparator the comparator to use to compare the elements - see the sort() - method for details about the form this object should take - @param elementToLookFor the element to search for - @returns the index of the element, or -1 if it's not found - @see addSorted, sort - */ - template - int indexOfSorted (ElementComparator& comparator, - const ElementType elementToLookFor) const throw() - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - lock.enter(); - - int start = 0; - int end = numUsed; - - for (;;) - { - if (start >= end) - { - lock.exit(); - return -1; - } - else if (comparator.compareElements (elementToLookFor, data.elements [start]) == 0) - { - lock.exit(); - return start; - } - else - { - const int halfway = (start + end) >> 1; - - if (halfway == start) - { - lock.exit(); - return -1; - } - else if (comparator.compareElements (elementToLookFor, data.elements [halfway]) >= 0) - start = halfway; - else - end = halfway; - } - } - } - - /** Removes an element from the array. - - This will remove the element at a given index, and move back - all the subsequent elements to close the gap. - If the index passed in is out-of-range, nothing will happen. - - @param indexToRemove the index of the element to remove - @returns the element that has been removed - @see removeValue, removeRange - */ - ElementType remove (const int indexToRemove) throw() - { - lock.enter(); - - if (((unsigned int) indexToRemove) < (unsigned int) numUsed) - { - --numUsed; - - ElementType* const e = data.elements + indexToRemove; - ElementType const removed = *e; - const int numberToShift = numUsed - indexToRemove; - - if (numberToShift > 0) - memmove (e, e + 1, numberToShift * sizeof (ElementType)); - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - - lock.exit(); - return removed; - } - else - { - lock.exit(); - return ElementType(); - } - } - - /** Removes an item from the array. - - This will remove the first occurrence of the given element from the array. - If the item isn't found, no action is taken. - - @param valueToRemove the object to try to remove - @see remove, removeRange - */ - void removeValue (const ElementType valueToRemove) throw() - { - lock.enter(); - ElementType* e = data.elements; - - for (int i = numUsed; --i >= 0;) - { - if (valueToRemove == *e) - { - remove ((int) (e - data.elements)); - break; - } - - ++e; - } - - lock.exit(); - } - - /** Removes a range of elements from the array. - - This will remove a set of elements, starting from the given index, - and move subsequent elements down to close the gap. - - If the range extends beyond the bounds of the array, it will - be safely clipped to the size of the array. - - @param startIndex the index of the first element to remove - @param numberToRemove how many elements should be removed - @see remove, removeValue - */ - void removeRange (int startIndex, - const int numberToRemove) throw() - { - lock.enter(); - const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove); - startIndex = jlimit (0, numUsed, startIndex); - - if (endIndex > startIndex) - { - const int rangeSize = endIndex - startIndex; - ElementType* e = data.elements + startIndex; - int numToShift = numUsed - endIndex; - numUsed -= rangeSize; - - while (--numToShift >= 0) - { - *e = e [rangeSize]; - ++e; - } - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - } - - lock.exit(); - } - - /** Removes the last n elements from the array. - - @param howManyToRemove how many elements to remove from the end of the array - @see remove, removeValue, removeRange - */ - void removeLast (const int howManyToRemove = 1) throw() - { - lock.enter(); - numUsed = jmax (0, numUsed - howManyToRemove); - - if ((numUsed << 1) < data.numAllocated) - minimiseStorageOverheads(); - - lock.exit(); - } - - /** Removes any elements which are also in another array. - - @param otherArray the other array in which to look for elements to remove - @see removeValuesNotIn, remove, removeValue, removeRange - */ - template - void removeValuesIn (const OtherArrayType& otherArray) throw() - { - otherArray.lockArray(); - lock.enter(); - - if (this == &otherArray) - { - clear(); - } - else - { - if (otherArray.size() > 0) - { - for (int i = numUsed; --i >= 0;) - if (otherArray.contains (data.elements [i])) - remove (i); - } - } - - lock.exit(); - otherArray.unlockArray(); - } - - /** Removes any elements which are not found in another array. - - Only elements which occur in this other array will be retained. - - @param otherArray the array in which to look for elements NOT to remove - @see removeValuesIn, remove, removeValue, removeRange - */ - template - void removeValuesNotIn (const OtherArrayType& otherArray) throw() - { - otherArray.lockArray(); - lock.enter(); - - if (this != &otherArray) - { - if (otherArray.size() <= 0) - { - clear(); - } - else - { - for (int i = numUsed; --i >= 0;) - if (! otherArray.contains (data.elements [i])) - remove (i); - } - } - - lock.exit(); - otherArray.unlockArray(); - } - - /** Swaps over two elements in the array. - - This swaps over the elements found at the two indexes passed in. - If either index is out-of-range, this method will do nothing. - - @param index1 index of one of the elements to swap - @param index2 index of the other element to swap - */ - void swap (const int index1, - const int index2) throw() - { - lock.enter(); - - if (((unsigned int) index1) < (unsigned int) numUsed - && ((unsigned int) index2) < (unsigned int) numUsed) - { - swapVariables (data.elements [index1], - data.elements [index2]); - } - - lock.exit(); - } - - /** Moves one of the values to a different position. - - This will move the value to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the value to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this value to end up. If this - is less than zero, the value will be moved to the end - of the array - */ - void move (const int currentIndex, - int newIndex) throw() - { - if (currentIndex != newIndex) - { - lock.enter(); - - if (((unsigned int) currentIndex) < (unsigned int) numUsed) - { - if (((unsigned int) newIndex) >= (unsigned int) numUsed) - newIndex = numUsed - 1; - - const ElementType value = data.elements [currentIndex]; - - if (newIndex > currentIndex) - { - memmove (data.elements + currentIndex, - data.elements + currentIndex + 1, - (newIndex - currentIndex) * sizeof (ElementType)); - } - else - { - memmove (data.elements + newIndex + 1, - data.elements + newIndex, - (currentIndex - newIndex) * sizeof (ElementType)); - } - - data.elements [newIndex] = value; - } - - lock.exit(); - } - } - - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() throw() - { - lock.enter(); - - if (numUsed == 0) - { - data.setAllocatedSize (0); - } - else - { - const int newAllocation = data.granularity * (numUsed / data.granularity + 1); - - if (newAllocation < data.numAllocated) - data.setAllocatedSize (newAllocation); - } - - lock.exit(); - } - - /** Increases the array's internal storage to hold a minimum number of elements. - - Calling this before adding a large known number of elements means that - the array won't have to keep dynamically resizing itself as the elements - are added, and it'll therefore be more efficient. - */ - void ensureStorageAllocated (const int minNumElements) throw() - { - data.ensureAllocatedSize (minNumElements); - } - - /** Sorts the elements in the array. - - This will use a comparator object to sort the elements into order. The object - passed must have a method of the form: - @code - int compareElements (ElementType first, ElementType second); - @endcode - - ..and this method must return: - - a value of < 0 if the first comes before the second - - a value of 0 if the two objects are equivalent - - a value of > 0 if the second comes before the first - - To improve performance, the compareElements() method can be declared as static or const. - - @param comparator the comparator to use for comparing elements. - @param retainOrderOfEquivalentItems if this is true, then items - which the comparator says are equivalent will be - kept in the order in which they currently appear - in the array. This is slower to perform, but may - be important in some cases. If it's false, a faster - algorithm is used, but equivalent elements may be - rearranged. - - @see addSorted, indexOfSorted, sortArray - */ - template - void sort (ElementComparator& comparator, - const bool retainOrderOfEquivalentItems = false) const throw() - { - (void) comparator; // if you pass in an object with a static compareElements() method, this - // avoids getting warning messages about the parameter being unused - lock.enter(); - sortArray (comparator, data.elements, 0, size() - 1, retainOrderOfEquivalentItems); - lock.exit(); - } - - /** Locks the array's CriticalSection. - - Of course if the type of section used is a DummyCriticalSection, this won't - have any effect. - - @see unlockArray - */ - void lockArray() const throw() - { - lock.enter(); - } - - /** Unlocks the array's CriticalSection. - - Of course if the type of section used is a DummyCriticalSection, this won't - have any effect. - - @see lockArray - */ - void unlockArray() const throw() - { - lock.exit(); - } - - juce_UseDebuggingNewOperator - -private: - ArrayAllocationBase data; - int numUsed; - TypeOfCriticalSectionToUse lock; -}; - -#endif // __JUCE_ARRAY_JUCEHEADER__ -/********* End of inlined file: juce_Array.h *********/ - -/** - A typedef for an Array of void*'s. - - VoidArrays are used in various places throughout the library instead of - more strongly-typed arrays, to keep code-size low. -*/ -typedef Array VoidArray; - -#endif // __JUCE_VOIDARRAY_JUCEHEADER__ -/********* End of inlined file: juce_VoidArray.h *********/ - -#ifndef DOXYGEN - // (used in StringArray::appendNumbersToDuplicates) - static const tchar* const defaultPreNumberString = JUCE_T(" ("); - static const tchar* const defaultPostNumberString = JUCE_T(")"); -#endif - -/** - A special array for holding a list of strings. - - @see String, StringPairArray -*/ -class JUCE_API StringArray -{ -public: - - /** Creates an empty string array */ - StringArray() throw(); - - /** Creates a copy of another string array */ - StringArray (const StringArray& other) throw(); - - /** Creates a copy of an array of string literals. - - @param strings an array of strings to add. Null pointers in the array will be - treated as empty strings - @param numberOfStrings how many items there are in the array - */ - StringArray (const juce_wchar** const strings, - const int numberOfStrings) throw(); - - /** Creates a copy of an array of string literals. - - @param strings an array of strings to add. Null pointers in the array will be - treated as empty strings - @param numberOfStrings how many items there are in the array - */ - StringArray (const char** const strings, - const int numberOfStrings) throw(); - - /** Creates a copy of a null-terminated array of string literals. - - Each item from the array passed-in is added, until it encounters a null pointer, - at which point it stops. - */ - StringArray (const juce_wchar** const strings) throw(); - - /** Creates a copy of a null-terminated array of string literals. - - Each item from the array passed-in is added, until it encounters a null pointer, - at which point it stops. - */ - StringArray (const char** const strings) throw(); - - /** Destructor. */ - virtual ~StringArray() throw(); - - /** Copies the contents of another string array into this one */ - const StringArray& operator= (const StringArray& other) throw(); - - /** Compares two arrays. - - Comparisons are case-sensitive. - - @returns true only if the other array contains exactly the same strings in the same order - */ - bool operator== (const StringArray& other) const throw(); - - /** Compares two arrays. - - Comparisons are case-sensitive. - - @returns false if the other array contains exactly the same strings in the same order - */ - bool operator!= (const StringArray& other) const throw(); - - /** Returns the number of strings in the array */ - inline int size() const throw() { return strings.size(); }; - - /** Returns one of the strings from the array. - - If the index is out-of-range, an empty string is returned. - - Obviously the reference returned shouldn't be stored for later use, as the - string it refers to may disappear when the array changes. - */ - const String& operator[] (const int index) const throw(); - - /** Searches for a string in the array. - - The comparison will be case-insensitive if the ignoreCase parameter is true. - - @returns true if the string is found inside the array - */ - bool contains (const String& stringToLookFor, - const bool ignoreCase = false) const throw(); - - /** Searches for a string in the array. - - The comparison will be case-insensitive if the ignoreCase parameter is true. - - @param stringToLookFor the string to try to find - @param ignoreCase whether the comparison should be case-insensitive - @param startIndex the first index to start searching from - @returns the index of the first occurrence of the string in this array, - or -1 if it isn't found. - */ - int indexOf (const String& stringToLookFor, - const bool ignoreCase = false, - int startIndex = 0) const throw(); - - /** Appends a string at the end of the array. */ - void add (const String& stringToAdd) throw(); - - /** Inserts a string into the array. - - This will insert a string into the array at the given index, moving - up the other elements to make room for it. - If the index is less than zero or greater than the size of the array, - the new string will be added to the end of the array. - */ - void insert (const int index, - const String& stringToAdd) throw(); - - /** Adds a string to the array as long as it's not already in there. - - The search can optionally be case-insensitive. - */ - void addIfNotAlreadyThere (const String& stringToAdd, - const bool ignoreCase = false) throw(); - - /** Replaces one of the strings in the array with another one. - - If the index is higher than the array's size, the new string will be - added to the end of the array; if it's less than zero nothing happens. - */ - void set (const int index, - const String& newString) throw(); - - /** Appends some strings from another array to the end of this one. - - @param other the array to add - @param startIndex the first element of the other array to add - @param numElementsToAdd the maximum number of elements to add (if this is - less than zero, they are all added) - */ - void addArray (const StringArray& other, - int startIndex = 0, - int numElementsToAdd = -1) throw(); - - /** Breaks up a string into tokens and adds them to this array. - - This will tokenise the given string using whitespace characters as the - token delimiters, and will add these tokens to the end of the array. - - @returns the number of tokens added - */ - int addTokens (const tchar* const stringToTokenise, - const bool preserveQuotedStrings) throw(); - - /** Breaks up a string into tokens and adds them to this array. - - This will tokenise the given string (using the string passed in to define the - token delimiters), and will add these tokens to the end of the array. - - @param stringToTokenise the string to tokenise - @param breakCharacters a string of characters, any of which will be considered - to be a token delimiter. - @param quoteCharacters if this string isn't empty, it defines a set of characters - which are treated as quotes. Any text occurring - between quotes is not broken up into tokens. - @returns the number of tokens added - */ - int addTokens (const tchar* const stringToTokenise, - const tchar* breakCharacters, - const tchar* quoteCharacters) throw(); - - /** Breaks up a string into lines and adds them to this array. - - This breaks a string down into lines separated by \\n or \\r\\n, and adds each line - to the array. Line-break characters are omitted from the strings that are added to - the array. - */ - int addLines (const tchar* stringToBreakUp) throw(); - - /** Removes all elements from the array. */ - void clear() throw(); - - /** Removes a string from the array. - - If the index is out-of-range, no action will be taken. - */ - void remove (const int index) throw(); - - /** Finds a string in the array and removes it. - - This will remove the first occurrence of the given string from the array. The - comparison may be case-insensitive depending on the ignoreCase parameter. - */ - void removeString (const String& stringToRemove, - const bool ignoreCase = false) throw(); - - /** Removes any duplicated elements from the array. - - If any string appears in the array more than once, only the first occurrence of - it will be retained. - - @param ignoreCase whether to use a case-insensitive comparison - */ - void removeDuplicates (const bool ignoreCase) throw(); - - /** Removes empty strings from the array. - - @param removeWhitespaceStrings if true, strings that only contain whitespace - characters will also be removed - */ - void removeEmptyStrings (const bool removeWhitespaceStrings = true) throw(); - - /** Moves one of the strings to a different position. - - This will move the string to a specified index, shuffling along - any intervening elements as required. - - So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling - move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }. - - @param currentIndex the index of the value to be moved. If this isn't a - valid index, then nothing will be done - @param newIndex the index at which you'd like this value to end up. If this - is less than zero, the value will be moved to the end - of the array - */ - void move (const int currentIndex, int newIndex) throw(); - - /** Deletes any whitespace characters from the starts and ends of all the strings. */ - void trim() throw(); - - /** Adds numbers to the strings in the array, to make each string unique. - - This will add numbers to the ends of groups of similar strings. - e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)" - - @param ignoreCaseWhenComparing whether the comparison used is case-insensitive - @param appendNumberToFirstInstance whether the first of a group of similar strings - also has a number appended to it. - @param preNumberString when adding a number, this string is added before the number - @param postNumberString this string is appended after any numbers that are added - */ - void appendNumbersToDuplicates (const bool ignoreCaseWhenComparing, - const bool appendNumberToFirstInstance, - const tchar* const preNumberString = defaultPreNumberString, - const tchar* const postNumberString = defaultPostNumberString) throw(); - - /** Joins the strings in the array together into one string. - - This will join a range of elements from the array into a string, separating - them with a given string. - - e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c". - - @param separatorString the string to insert between all the strings - @param startIndex the first element to join - @param numberOfElements how many elements to join together. If this is less - than zero, all available elements will be used. - */ - const String joinIntoString (const String& separatorString, - int startIndex = 0, - int numberOfElements = -1) const throw(); - - /** Sorts the array into alphabetical order. - - @param ignoreCase if true, the comparisons used will be case-sensitive. - */ - void sort (const bool ignoreCase) throw(); - - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() throw(); - - juce_UseDebuggingNewOperator - -private: - VoidArray strings; -}; - -#endif // __JUCE_STRINGARRAY_JUCEHEADER__ -/********* End of inlined file: juce_StringArray.h *********/ - -/********* Start of inlined file: juce_MemoryBlock.h *********/ -#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ -#define __JUCE_MEMORYBLOCK_JUCEHEADER__ - -/** - A class to hold a resizable block of raw data. - -*/ -class JUCE_API MemoryBlock -{ -public: - - /** Create an uninitialised block with 0 size. */ - MemoryBlock() throw(); - - /** Creates a memory block with a given initial size. - - @param initialSize the size of block to create - @param initialiseToZero whether to clear the memory or just leave it uninitialised - */ - MemoryBlock (const int initialSize, - const bool initialiseToZero = false) throw(); - - /** Creates a copy of another memory block. */ - MemoryBlock (const MemoryBlock& other) throw(); - - /** Creates a memory block using a copy of a block of data. - - @param dataToInitialiseFrom some data to copy into this block - @param sizeInBytes how much space to use - */ - MemoryBlock (const void* const dataToInitialiseFrom, - const int sizeInBytes) throw(); - - /** Destructor. */ - ~MemoryBlock() throw(); - - /** Copies another memory block onto this one. - - This block will be resized and copied to exactly match the other one. - */ - const MemoryBlock& operator= (const MemoryBlock& other) throw(); - - /** Compares two memory blocks. - - @returns true only if the two blocks are the same size and have identical contents. - */ - bool operator== (const MemoryBlock& other) const throw(); - - /** Compares two memory blocks. - - @returns true if the two blocks are different sizes or have different contents. - */ - bool operator!= (const MemoryBlock& other) const throw(); - - /** Returns a pointer to the data, casting it to any type of primitive data required. - - Note that the pointer returned will probably become invalid when the - block is resized. - */ - template - operator DataType*() const throw() { return (DataType*) data; } - - /** Returns a void pointer to the data. - - Note that the pointer returned will probably become invalid when the - block is resized. - */ - void* getData() const throw() { return data; } - - /** Returns a byte from the memory block. - - This returns a reference, so you can also use it to set a byte. - */ - char& operator[] (const int offset) const throw() { return data [offset]; } - - /** Returns the block's current allocated size, in bytes. */ - int getSize() const throw() { return size; } - - /** Resizes the memory block. - - This will try to keep as much of the block's current content as it can, - and can optionally be made to clear any new space that gets allocated at - the end of the block. - - @param newSize the new desired size for the block - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see ensureSize - */ - void setSize (const int newSize, - const bool initialiseNewSpaceToZero = false) throw(); - - /** Increases the block's size only if it's smaller than a given size. - - @param minimumSize if the block is already bigger than this size, no action - will be taken; otherwise it will be increased to this size - @param initialiseNewSpaceToZero if the block gets enlarged, this determines - whether to clear the new section or just leave it - uninitialised - @see setSize - */ - void ensureSize (const int minimumSize, - const bool initialiseNewSpaceToZero = false) throw(); - - /** Fills the entire memory block with a repeated byte value. - - This is handy for clearing a block of memory to zero. - */ - void fillWith (const uint8 valueToUse) throw(); - - /** Adds another block of data to the end of this one. - - This block's size will be increased accordingly. - */ - void append (const void* const data, - const int numBytes) throw(); - - /** Copies data into this MemoryBlock from a memory address. - - @param srcData the memory location of the data to copy into this block - @param destinationOffset the offset in this block at which the data being copied should begin - @param numBytes how much to copy in (if this goes beyond the size of the memory block, - it will be clipped so not to do anything nasty) - */ - void copyFrom (const void* srcData, - int destinationOffset, - int numBytes) throw(); - - /** Copies data from this MemoryBlock to a memory address. - - @param destData the memory location to write to - @param sourceOffset the offset within this block from which the copied data will be read - @param numBytes how much to copy (if this extends beyond the limits of the memory block, - zeros will be used for that portion of the data) - */ - void copyTo (void* destData, - int sourceOffset, - int numBytes) const throw(); - - /** Chops out a section of the block. - - This will remove a section of the memory block and close the gap around it, - shifting any subsequent data downwards and reducing the size of the block. - - If the range specified goes beyond the size of the block, it will be clipped. - */ - void removeSection (int startByte, int numBytesToRemove) throw(); - - /** Attempts to parse the contents of the block as a zero-terminated string of 8-bit - characters in the system's default encoding. */ - const String toString() const throw(); - - /** Parses a string of hexadecimal numbers and writes this data into the memory block. - - The block will be resized to the number of valid bytes read from the string. - Non-hex characters in the string will be ignored. - - @see String::toHexString() - */ - void loadFromHexString (const String& sourceHexString) throw(); - - /** Sets a number of bits in the memory block, treating it as a long binary sequence. */ - void setBitRange (int bitRangeStart, - int numBits, - int binaryNumberToApply) throw(); - - /** Reads a number of bits from the memory block, treating it as one long binary sequence */ - int getBitRange (int bitRangeStart, - int numBitsToRead) const throw(); - - /** Returns a string of characters that represent the binary contents of this block. - - Uses a 64-bit encoding system to allow binary data to be turned into a string - of simple non-extended characters, e.g. for storage in XML. - - @see fromBase64Encoding - */ - const String toBase64Encoding() const throw(); - - /** Takes a string of encoded characters and turns it into binary data. - - The string passed in must have been created by to64BitEncoding(), and this - block will be resized to recreate the original data block. - - @see toBase64Encoding - */ - bool fromBase64Encoding (const String& encodedString) throw(); - - juce_UseDebuggingNewOperator - -private: - - char* data; - int size; -}; - -#endif // __JUCE_MEMORYBLOCK_JUCEHEADER__ -/********* End of inlined file: juce_MemoryBlock.h *********/ - class FileInputStream; class FileOutputStream; @@ -6286,7 +7271,10 @@ public: @param extensionToTest the extension to look for - it doesn't matter whether or not this string has a dot at the start, so ".wav" and "wav" will have the same effect. The comparison used is - case-insensitve. + case-insensitve. To compare with multiple extensions, this + parameter can contain multiple strings, separated by semi-colons - + so, for example: hasFileExtension (".jpeg;png;gif") would return + true if the file has any of those three extensions. @see getFileExtension, withFileExtension, getFileNameWithoutExtension */ @@ -6986,2637 +7974,6 @@ private: #endif // __JUCE_FILE_JUCEHEADER__ /********* End of inlined file: juce_File.h *********/ -/** - A simple implemenation of a Logger that writes to a file. - - @see Logger -*/ -class JUCE_API FileLogger : public Logger -{ -public: - - /** Creates a FileLogger for a given file. - - @param fileToWriteTo the file that to use - new messages will be appended - to the file. If the file doesn't exist, it will be created, - along with any parent directories that are needed. - @param welcomeMessage when opened, the logger will write a header to the log, along - with the current date and time, and this welcome message - @param maxInitialFileSizeBytes if this is zero or greater, then if the file already exists - but is larger than this number of bytes, then the start of the - file will be truncated to keep the size down. This prevents a log - file getting ridiculously large over time. The file will be truncated - at a new-line boundary. If this value is less than zero, no size limit - will be imposed; if it's zero, the file will always be deleted. Note that - the size is only checked once when this object is created - any logging - that is done later will be appended without any checking - */ - FileLogger (const File& fileToWriteTo, - const String& welcomeMessage, - const int maxInitialFileSizeBytes = 128 * 1024); - - /** Destructor. */ - ~FileLogger(); - - void logMessage (const String& message); - - /** Helper function to create a log file in the correct place for this platform. - - On Windows this will return a logger with a path such as: - c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName] - - On the Mac it'll create something like: - ~/Library/Logs/[logFileName] - - The method might return 0 if the file can't be created for some reason. - - @param logFileSubDirectoryName if a subdirectory is needed, this is what it will be called - - it's best to use the something like the name of your application here. - @param logFileName the name of the file to create, e.g. "MyAppLog.txt". Don't just - call it "log.txt" because if it goes in a directory with logs - from other applications (as it will do on the Mac) then no-one - will know which one is yours! - @param welcomeMessage a message that will be written to the log when it's opened. - @param maxInitialFileSizeBytes (see the FileLogger constructor for more info on this) - */ - static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName, - const String& logFileName, - const String& welcomeMessage, - const int maxInitialFileSizeBytes = 128 * 1024); - - juce_UseDebuggingNewOperator - -private: - File logFile; - CriticalSection logLock; - FileOutputStream* logStream; - - void trimFileSize (int maxFileSizeBytes) const; - - FileLogger (const FileLogger&); - const FileLogger& operator= (const FileLogger&); -}; - -#endif // __JUCE_FILELOGGER_JUCEHEADER__ -/********* End of inlined file: juce_FileLogger.h *********/ - -#endif -#ifndef __JUCE_INITIALISATION_JUCEHEADER__ - -/********* Start of inlined file: juce_Initialisation.h *********/ -#ifndef __JUCE_INITIALISATION_JUCEHEADER__ -#define __JUCE_INITIALISATION_JUCEHEADER__ - -/** Initialises Juce's GUI classes. - - If you're embedding Juce into an application that uses its own event-loop rather - than using the START_JUCE_APPLICATION macro, call this function before making any - Juce calls, to make sure things are initialised correctly. - - Note that if you're creating a Juce DLL for Windows, you may also need to call the - PlatformUtilities::setCurrentModuleInstanceHandle() method. - - @see shutdownJuce_GUI(), initialiseJuce_NonGUI() -*/ -void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI(); - -/** Clears up any static data being used by Juce's GUI classes. - - If you're embedding Juce into an application that uses its own event-loop rather - than using the START_JUCE_APPLICATION macro, call this function in your shutdown - code to clean up any juce objects that might be lying around. - - @see initialiseJuce_GUI(), initialiseJuce_NonGUI() -*/ -void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); - -/** Initialises the core parts of Juce. - - If you're embedding Juce into either a command-line program, call this function - at the start of your main() function to make sure that Juce is initialised correctly. - - Note that if you're creating a Juce DLL for Windows, you may also need to call the - PlatformUtilities::setCurrentModuleInstanceHandle() method. - - @see shutdownJuce_NonGUI, initialiseJuce_GUI -*/ -void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI(); - -/** Clears up any static data being used by Juce's non-gui core classes. - - If you're embedding Juce into either a command-line program, call this function - at the end of your main() function if you want to make sure any Juce objects are - cleaned up correctly. - - @see initialiseJuce_NonGUI, initialiseJuce_GUI -*/ -void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI(); - -#endif // __JUCE_INITIALISATION_JUCEHEADER__ -/********* End of inlined file: juce_Initialisation.h *********/ - -#endif -#ifndef __JUCE_LOGGER_JUCEHEADER__ - -#endif -#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ - -/********* Start of inlined file: juce_PlatformUtilities.h *********/ -#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ -#define __JUCE_PLATFORMUTILITIES_JUCEHEADER__ - -/** - A collection of miscellaneous platform-specific utilities. - -*/ -class JUCE_API PlatformUtilities -{ -public: - - /** Plays the operating system's default alert 'beep' sound. */ - static void beep(); - - static bool launchEmailWithAttachments (const String& targetEmailAddress, - const String& emailSubject, - const String& bodyText, - const StringArray& filesToAttach); - -#if JUCE_MAC || JUCE_IPHONE || DOXYGEN - - /** MAC ONLY - Turns a Core CF String into a juce one. */ - static const String cfStringToJuceString (CFStringRef cfString); - - /** MAC ONLY - Turns a juce string into a Core CF one. */ - static CFStringRef juceStringToCFString (const String& s); - - /** MAC ONLY - Turns a file path into an FSRef, returning true if it succeeds. */ - static bool makeFSRefFromPath (FSRef* destFSRef, const String& path); - - /** MAC ONLY - Turns an FSRef into a juce string path. */ - static const String makePathFromFSRef (FSRef* file); - - /** MAC ONLY - Converts any decomposed unicode characters in a string into - their precomposed equivalents. - */ - static const String convertToPrecomposedUnicode (const String& s); - - /** MAC ONLY - Gets the type of a file from the file's resources. */ - static OSType getTypeOfFile (const String& filename); - - /** MAC ONLY - Returns true if this file is actually a bundle. */ - static bool isBundle (const String& filename); - - /** MAC ONLY - Adds an item to the dock */ - static void addItemToDock (const File& file); - - /** MAC ONLY - Returns the current OS version number. - E.g. if it's running on 10.4, this will be 4, 10.5 will return 5, etc. - */ - static int getOSXMinorVersionNumber() throw(); -#endif - -#if JUCE_WINDOWS || DOXYGEN - - // Some registry helper functions: - - /** WIN32 ONLY - Returns a string from the registry. - - The path is a string for the entire path of a value in the registry, - e.g. "HKEY_CURRENT_USER\Software\foo\bar" - */ - static const String getRegistryValue (const String& regValuePath, - const String& defaultValue = String::empty); - - /** WIN32 ONLY - Sets a registry value as a string. - - This will take care of creating any groups needed to get to the given - registry value. - */ - static void setRegistryValue (const String& regValuePath, - const String& value); - - /** WIN32 ONLY - Returns true if the given value exists in the registry. */ - static bool registryValueExists (const String& regValuePath); - - /** WIN32 ONLY - Deletes a registry value. */ - static void deleteRegistryValue (const String& regValuePath); - - /** WIN32 ONLY - Deletes a registry key (which is registry-talk for 'folder'). */ - static void deleteRegistryKey (const String& regKeyPath); - - /** WIN32 ONLY - Creates a file association in the registry. - - This lets you set the exe that should be launched by a given file extension. - @param fileExtension the file extension to associate, including the - initial dot, e.g. ".txt" - @param symbolicDescription a space-free short token to identify the file type - @param fullDescription a human-readable description of the file type - @param targetExecutable the executable that should be launched - @param iconResourceNumber the icon that gets displayed for the file type will be - found by looking up this resource number in the - executable. Pass 0 here to not use an icon - */ - static void registerFileAssociation (const String& fileExtension, - const String& symbolicDescription, - const String& fullDescription, - const File& targetExecutable, - int iconResourceNumber); - - /** WIN32 ONLY - This returns the HINSTANCE of the current module. - - In a normal Juce application this will be set to the module handle - of the application executable. - - If you're writing a DLL using Juce and plan to use any Juce messaging or - windows, you'll need to make sure you use the setCurrentModuleInstanceHandle() - to set the correct module handle in your DllMain() function, because - the win32 system relies on the correct instance handle when opening windows. - */ - static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() throw(); - - /** WIN32 ONLY - Sets a new module handle to be used by the library. - - @see getCurrentModuleInstanceHandle() - */ - static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) throw(); - - /** WIN32 ONLY - Gets the command-line params as a string. - - This is needed to avoid unicode problems with the argc type params. - */ - static const String JUCE_CALLTYPE getCurrentCommandLineParams() throw(); -#endif - - /** Clears the floating point unit's flags. - - Only has an effect under win32, currently. - */ - static void fpuReset(); - -#if JUCE_LINUX || JUCE_WINDOWS - - /** Loads a dynamically-linked library into the process's address space. - - @param pathOrFilename the platform-dependent name and search path - @returns a handle which can be used by getProcedureEntryPoint(), or - zero if it fails. - @see freeDynamicLibrary, getProcedureEntryPoint - */ - static void* loadDynamicLibrary (const String& pathOrFilename); - - /** Frees a dynamically-linked library. - - @param libraryHandle a handle created by loadDynamicLibrary - @see loadDynamicLibrary, getProcedureEntryPoint - */ - static void freeDynamicLibrary (void* libraryHandle); - - /** Finds a procedure call in a dynamically-linked library. - - @param libraryHandle a library handle returned by loadDynamicLibrary - @param procedureName the name of the procedure call to try to load - @returns a pointer to the function if found, or 0 if it fails - @see loadDynamicLibrary - */ - static void* getProcedureEntryPoint (void* libraryHandle, - const String& procedureName); -#endif - -#if JUCE_LINUX || DOXYGEN - -#endif -}; - -#if JUCE_MAC || JUCE_IPHONE - -/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object - using RAII. -*/ -class ScopedAutoReleasePool -{ -public: - ScopedAutoReleasePool(); - ~ScopedAutoReleasePool(); - -private: - void* pool; - - ScopedAutoReleasePool (const ScopedAutoReleasePool&); - const ScopedAutoReleasePool& operator= (const ScopedAutoReleasePool&); -}; - -#endif - -#if JUCE_MAC - -/** - A wrapper class for picking up events from an Apple IR remote control device. - - To use it, just create a subclass of this class, implementing the buttonPressed() - callback, then call start() and stop() to start or stop receiving events. -*/ -class JUCE_API AppleRemoteDevice -{ -public: - - AppleRemoteDevice(); - virtual ~AppleRemoteDevice(); - - /** The set of buttons that may be pressed. - @see buttonPressed - */ - enum ButtonType - { - menuButton = 0, /**< The menu button (if it's held for a short time). */ - playButton, /**< The play button. */ - plusButton, /**< The plus or volume-up button. */ - minusButton, /**< The minus or volume-down button. */ - rightButton, /**< The right button (if it's held for a short time). */ - leftButton, /**< The left button (if it's held for a short time). */ - rightButton_Long, /**< The right button (if it's held for a long time). */ - leftButton_Long, /**< The menu button (if it's held for a long time). */ - menuButton_Long, /**< The menu button (if it's held for a long time). */ - playButtonSleepMode, - switched - }; - - /** Override this method to receive the callback about a button press. - - The callback will happen on the application's message thread. - - Some buttons trigger matching up and down events, in which the isDown parameter - will be true and then false. Others only send a single event when the - button is pressed. - */ - virtual void buttonPressed (const ButtonType buttonId, const bool isDown) = 0; - - /** Starts the device running and responding to events. - - Returns true if it managed to open the device. - - @param inExclusiveMode if true, the remote will be grabbed exclusively for this app, - and will not be available to any other part of the system. If - false, it will be shared with other apps. - @see stop - */ - bool start (const bool inExclusiveMode) throw(); - - /** Stops the device running. - @see start - */ - void stop() throw(); - - /** Returns true if the device has been started successfully. - */ - bool isActive() const throw(); - - /** Returns the ID number of the remote, if it has sent one. - */ - int getRemoteId() const throw() { return remoteId; } - - juce_UseDebuggingNewOperator - - /** @internal */ - void handleCallbackInternal(); - -private: - void* device; - void* queue; - int remoteId; - - bool open (const bool openInExclusiveMode) throw(); - - AppleRemoteDevice (const AppleRemoteDevice&); - const AppleRemoteDevice& operator= (const AppleRemoteDevice&); -}; - -#endif - -#endif // __JUCE_PLATFORMUTILITIES_JUCEHEADER__ -/********* End of inlined file: juce_PlatformUtilities.h *********/ - -#endif -#ifndef __JUCE_MEMORY_JUCEHEADER__ - -#endif -#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ - -/********* Start of inlined file: juce_PerformanceCounter.h *********/ -#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ -#define __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ - -/** A timer for measuring performance of code and dumping the results to a file. - - e.g. @code - - PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt"); - - for (;;) - { - pc.start(); - - doSomethingFishy(); - - pc.stop(); - } - @endcode - - In this example, the time of each period between calling start/stop will be - measured and averaged over 50 runs, and the results printed to a file - every 50 times round the loop. -*/ -class JUCE_API PerformanceCounter -{ -public: - - /** Creates a PerformanceCounter object. - - @param counterName the name used when printing out the statistics - @param runsPerPrintout the number of start/stop iterations before calling - printStatistics() - @param loggingFile a file to dump the results to - if this is File::nonexistent, - the results are just written to the debugger output - */ - PerformanceCounter (const String& counterName, - int runsPerPrintout = 100, - const File& loggingFile = File::nonexistent); - - /** Destructor. */ - ~PerformanceCounter(); - - /** Starts timing. - - @see stop - */ - void start(); - - /** Stops timing and prints out the results. - - The number of iterations before doing a printout of the - results is set in the constructor. - - @see start - */ - void stop(); - - /** Dumps the current metrics to the debugger output and to a file. - - As well as using Logger::outputDebugString to print the results, - this will write then to the file specified in the constructor (if - this was valid). - */ - void printStatistics(); - - juce_UseDebuggingNewOperator - -private: - - String name; - int numRuns, runsPerPrint; - double totalTime; - int64 started; - File outputFile; -}; - -#endif // __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ -/********* End of inlined file: juce_PerformanceCounter.h *********/ - -#endif -#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ - -#endif -#ifndef __JUCE_SINGLETON_JUCEHEADER__ - -/********* Start of inlined file: juce_Singleton.h *********/ -#ifndef __JUCE_SINGLETON_JUCEHEADER__ -#define __JUCE_SINGLETON_JUCEHEADER__ - -/********* Start of inlined file: juce_ScopedLock.h *********/ -#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__ -#define __JUCE_SCOPEDLOCK_JUCEHEADER__ - -/** - Automatically locks and unlocks a CriticalSection object. - - Use one of these as a local variable to control access to a CriticalSection. - - e.g. @code - - CriticalSection myCriticalSection; - - for (;;) - { - const ScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked - - ...do some stuff... - - // myCriticalSection gets unlocked here. - } - @endcode - - @see CriticalSection, ScopedUnlock -*/ -class JUCE_API ScopedLock -{ -public: - - /** Creates a ScopedLock. - - As soon as it is created, this will lock the CriticalSection, and - when the ScopedLock object is deleted, the CriticalSection will - be unlocked. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); } - - /** Destructor. - - The CriticalSection will be unlocked when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~ScopedLock() throw() { lock_.exit(); } - -private: - - const CriticalSection& lock_; - - ScopedLock (const ScopedLock&); - const ScopedLock& operator= (const ScopedLock&); -}; - -/** - Automatically unlocks and re-locks a CriticalSection object. - - This is the reverse of a ScopedLock object - instead of locking the critical - section for the lifetime of this object, it unlocks it. - - Make sure you don't try to unlock critical sections that aren't actually locked! - - e.g. @code - - CriticalSection myCriticalSection; - - for (;;) - { - const ScopedLock myScopedLock (myCriticalSection); - // myCriticalSection is now locked - - ... do some stuff with it locked .. - - while (xyz) - { - ... do some stuff with it locked .. - - const ScopedUnlock unlocker (myCriticalSection); - - // myCriticalSection is now unlocked for the remainder of this block, - // and re-locked at the end. - - ...do some stuff with it unlocked ... - } - - // myCriticalSection gets unlocked here. - } - @endcode - - @see CriticalSection, ScopedLock -*/ -class ScopedUnlock -{ -public: - - /** Creates a ScopedUnlock. - - As soon as it is created, this will unlock the CriticalSection, and - when the ScopedLock object is deleted, the CriticalSection will - be re-locked. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! Best just to use it - as a local stack object, rather than creating one with the new() operator. - */ - inline ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); } - - /** Destructor. - - The CriticalSection will be unlocked when the destructor is called. - - Make sure this object is created and deleted by the same thread, - otherwise there are no guarantees what will happen! - */ - inline ~ScopedUnlock() throw() { lock_.enter(); } - -private: - - const CriticalSection& lock_; - - ScopedUnlock (const ScopedLock&); - const ScopedUnlock& operator= (const ScopedUnlock&); -}; - -#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__ -/********* End of inlined file: juce_ScopedLock.h *********/ - -/** - Macro to declare member variables and methods for a singleton class. - - To use this, add the line juce_DeclareSingleton (MyClass, doNotRecreateAfterDeletion) - to the class's definition. - - Then put a macro juce_ImplementSingleton (MyClass) along with the class's - implementation code. - - It's also a very good idea to also add the call clearSingletonInstance() in your class's - destructor, in case it is deleted by other means than deleteInstance() - - Clients can then call the static method MyClass::getInstance() to get a pointer - to the singleton, or MyClass::getInstanceWithoutCreating() which will return 0 if - no instance currently exists. - - e.g. @code - - class MySingleton - { - public: - MySingleton() - { - } - - ~MySingleton() - { - // this ensures that no dangling pointers are left when the - // singleton is deleted. - clearSingletonInstance(); - } - - juce_DeclareSingleton (MySingleton, false) - }; - - juce_ImplementSingleton (MySingleton) - - // example of usage: - MySingleton* m = MySingleton::getInstance(); // creates the singleton if there isn't already one. - - ... - - MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created). - - @endcode - - If doNotRecreateAfterDeletion = true, it won't allow the object to be created more - than once during the process's lifetime - i.e. after you've created and deleted the - object, getInstance() will refuse to create another one. This can be useful to stop - objects being accidentally re-created during your app's shutdown code. - - If you know that your object will only be created and deleted by a single thread, you - can use the slightly more efficient juce_DeclareSingleton_SingleThreaded() macro instead - of this one. - - @see juce_ImplementSingleton, juce_DeclareSingleton_SingleThreaded -*/ -#define juce_DeclareSingleton(classname, doNotRecreateAfterDeletion) \ -\ - static classname* _singletonInstance; \ - static JUCE_NAMESPACE::CriticalSection _singletonLock; \ -\ - static classname* getInstance() \ - { \ - if (_singletonInstance == 0) \ - {\ - const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ -\ - if (_singletonInstance == 0) \ - { \ - static bool alreadyInside = false; \ - static bool createdOnceAlready = false; \ -\ - const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ - jassert (! problem); \ - if (! problem) \ - { \ - createdOnceAlready = true; \ - alreadyInside = true; \ - classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ - alreadyInside = false; \ -\ - _singletonInstance = newObject; \ - } \ - } \ - } \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() throw() \ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ - if (_singletonInstance != 0) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = 0; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() throw() \ - { \ - if (_singletonInstance == this) \ - _singletonInstance = 0; \ - } - -/** This is a counterpart to the juce_DeclareSingleton macro. - - After adding the juce_DeclareSingleton to the class definition, this macro has - to be used in the cpp file. -*/ -#define juce_ImplementSingleton(classname) \ -\ - classname* classname::_singletonInstance = 0; \ - JUCE_NAMESPACE::CriticalSection classname::_singletonLock; - -/** - Macro to declare member variables and methods for a singleton class. - - This is exactly the same as juce_DeclareSingleton, but doesn't use a critical - section to make access to it thread-safe. If you know that your object will - only ever be created or deleted by a single thread, then this is a - more efficient version to use. - - If doNotRecreateAfterDeletion = true, it won't allow the object to be created more - than once during the process's lifetime - i.e. after you've created and deleted the - object, getInstance() will refuse to create another one. This can be useful to stop - objects being accidentally re-created during your app's shutdown code. - - See the documentation for juce_DeclareSingleton for more information about - how to use it, the only difference being that you have to use - juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. - - @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal -*/ -#define juce_DeclareSingleton_SingleThreaded(classname, doNotRecreateAfterDeletion) \ -\ - static classname* _singletonInstance; \ -\ - static classname* getInstance() \ - { \ - if (_singletonInstance == 0) \ - { \ - static bool alreadyInside = false; \ - static bool createdOnceAlready = false; \ -\ - const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ - jassert (! problem); \ - if (! problem) \ - { \ - createdOnceAlready = true; \ - alreadyInside = true; \ - classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ - alreadyInside = false; \ -\ - _singletonInstance = newObject; \ - } \ - } \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() throw() \ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - if (_singletonInstance != 0) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = 0; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() throw() \ - { \ - if (_singletonInstance == this) \ - _singletonInstance = 0; \ - } - -/** - Macro to declare member variables and methods for a singleton class. - - This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking - for recursion or repeated instantiation. It's intended for use as a lightweight - version of a singleton, where you're using it in very straightforward - circumstances and don't need the extra checking. - - Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart - to this declaration, as you would with juce_DeclareSingleton_SingleThreaded. - - See the documentation for juce_DeclareSingleton for more information about - how to use it, the only difference being that you have to use - juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. - - @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton -*/ -#define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \ -\ - static classname* _singletonInstance; \ -\ - static classname* getInstance() \ - { \ - if (_singletonInstance == 0) \ - _singletonInstance = new classname(); \ -\ - return _singletonInstance; \ - } \ -\ - static inline classname* getInstanceWithoutCreating() throw() \ - { \ - return _singletonInstance; \ - } \ -\ - static void deleteInstance() \ - { \ - if (_singletonInstance != 0) \ - { \ - classname* const old = _singletonInstance; \ - _singletonInstance = 0; \ - delete old; \ - } \ - } \ -\ - void clearSingletonInstance() throw() \ - { \ - if (_singletonInstance == this) \ - _singletonInstance = 0; \ - } - -/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. - - After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal - to the class definition, this macro has to be used somewhere in the cpp file. -*/ -#define juce_ImplementSingleton_SingleThreaded(classname) \ -\ - classname* classname::_singletonInstance = 0; - -#endif // __JUCE_SINGLETON_JUCEHEADER__ -/********* End of inlined file: juce_Singleton.h *********/ - -#endif -#ifndef __JUCE_RANDOM_JUCEHEADER__ - -/********* Start of inlined file: juce_Random.h *********/ -#ifndef __JUCE_RANDOM_JUCEHEADER__ -#define __JUCE_RANDOM_JUCEHEADER__ - -/********* Start of inlined file: juce_BitArray.h *********/ -#ifndef __JUCE_BITARRAY_JUCEHEADER__ -#define __JUCE_BITARRAY_JUCEHEADER__ - -class MemoryBlock; - -/** - An array of on/off bits, also usable to store large binary integers. - - A BitArray acts like an arbitrarily large integer whose bits can be set or - cleared, and some basic mathematical operations can be done on the number as - a whole. -*/ -class JUCE_API BitArray -{ -public: - - /** Creates an empty BitArray */ - BitArray() throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with this value. - */ - BitArray (const unsigned int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 32 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (const int value) throw(); - - /** Creates a BitArray containing an integer value in its low bits. - - The low 64 bits of the array are initialised with the absolute value - passed in, and its sign is set to reflect the sign of the number. - */ - BitArray (int64 value) throw(); - - /** Creates a copy of another BitArray. */ - BitArray (const BitArray& other) throw(); - - /** Destructor. */ - ~BitArray() throw(); - - /** Copies another BitArray onto this one. */ - const BitArray& operator= (const BitArray& other) throw(); - - /** Two arrays are the same if the same bits are set. */ - bool operator== (const BitArray& other) const throw(); - /** Two arrays are the same if the same bits are set. */ - bool operator!= (const BitArray& other) const throw(); - - /** Clears all bits in the BitArray to 0. */ - void clear() throw(); - - /** Clears a particular bit in the array. */ - void clearBit (const int bitNumber) throw(); - - /** Sets a specified bit to 1. - - If the bit number is high, this will grow the array to accomodate it. - */ - void setBit (const int bitNumber) throw(); - - /** Sets or clears a specified bit. */ - void setBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Sets a range of bits to be either on or off. - - @param startBit the first bit to change - @param numBits the number of bits to change - @param shouldBeSet whether to turn these bits on or off - */ - void setRange (int startBit, - int numBits, - const bool shouldBeSet) throw(); - - /** Inserts a bit an a given position, shifting up any bits above it. */ - void insertBit (const int bitNumber, - const bool shouldBeSet) throw(); - - /** Returns the value of a specified bit in the array. - - If the index is out-of-range, the result will be false. - */ - bool operator[] (const int bit) const throw(); - - /** Returns true if no bits are set. */ - bool isEmpty() const throw(); - - /** Returns a range of bits in the array as a new BitArray. - - e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits. - @see getBitRangeAsInt - */ - const BitArray getBitRange (int startBit, int numBits) const throw(); - - /** Returns a range of bits in the array as an integer value. - - e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits. - - Asking for more than 32 bits isn't allowed (obviously) - for that, use - getBitRange(). - */ - int getBitRangeAsInt (int startBit, int numBits) const throw(); - - /** Sets a range of bits in the array based on an integer value. - - Copies the given integer into the array, starting at startBit, - and only using up to numBits of the available bits. - */ - void setBitRangeAsInt (int startBit, int numBits, - unsigned int valueToSet) throw(); - - /** Performs a bitwise OR with another BitArray. - - The result ends up in this array. - */ - void orWith (const BitArray& other) throw(); - - /** Performs a bitwise AND with another BitArray. - - The result ends up in this array. - */ - void andWith (const BitArray& other) throw(); - - /** Performs a bitwise XOR with another BitArray. - - The result ends up in this array. - */ - void xorWith (const BitArray& other) throw(); - - /** Adds another BitArray's value to this one. - - Treating the two arrays as large positive integers, this - adds them up and puts the result in this array. - */ - void add (const BitArray& other) throw(); - - /** Subtracts another BitArray's value from this one. - - Treating the two arrays as large positive integers, this - subtracts them and puts the result in this array. - - Note that if the result should be negative, this won't be - handled correctly. - */ - void subtract (const BitArray& other) throw(); - - /** Multiplies another BitArray's value with this one. - - Treating the two arrays as large positive integers, this - multiplies them and puts the result in this array. - */ - void multiplyBy (const BitArray& other) throw(); - - /** Divides another BitArray's value into this one and also produces a remainder. - - Treating the two arrays as large positive integers, this - divides this value by the other, leaving the quotient in this - array, and the remainder is copied into the other BitArray passed in. - */ - void divideBy (const BitArray& divisor, BitArray& remainder) throw(); - - /** Returns the largest value that will divide both this value and the one - passed-in. - */ - const BitArray findGreatestCommonDivisor (BitArray other) const throw(); - - /** Performs a modulo operation on this value. - - The result is stored in this value. - */ - void modulo (const BitArray& divisor) throw(); - - /** Performs a combined exponent and modulo operation. - - This BitArray's value becomes (this ^ exponent) % modulus. - */ - void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw(); - - /** Performs an inverse modulo on the value. - - i.e. the result is (this ^ -1) mod (modulus). - */ - void inverseModulo (const BitArray& modulus) throw(); - - /** Shifts a section of bits left or right. - - @param howManyBitsLeft how far to move the bits (+ve numbers shift it left, -ve numbers shift it right). - @param startBit the first bit to affect - if this is > 0, only bits above that index will be affected. - */ - void shiftBits (int howManyBitsLeft, - int startBit = 0) throw(); - - /** Does a signed comparison of two BitArrays. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compare (const BitArray& other) const throw(); - - /** Compares the magnitudes of two BitArrays, ignoring their signs. - - Return values are: - - 0 if the numbers are the same - - < 0 if this number is smaller than the other - - > 0 if this number is bigger than the other - */ - int compareAbsolute (const BitArray& other) const throw(); - - /** Returns true if the value is less than zero. - - @see setNegative, negate - */ - bool isNegative() const throw(); - - /** Changes the sign of the number to be positive or negative. - - @see isNegative, negate - */ - void setNegative (const bool shouldBeNegative) throw(); - - /** Inverts the sign of the number. - - @see isNegative, setNegative - */ - void negate() throw(); - - /** Counts the total number of set bits in the array. */ - int countNumberOfSetBits() const throw(); - - /** Looks for the index of the next set bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first set bit, - and returns its index. - - If no set bits are found, it returns -1. - */ - int findNextSetBit (int startIndex = 0) const throw(); - - /** Looks for the index of the next clear bit after a given starting point. - - searches from startIndex (inclusive) upwards for the first clear bit, - and returns its index. - */ - int findNextClearBit (int startIndex = 0) const throw(); - - /** Returns the index of the highest set bit in the array. - - If the array is empty, this will return -1. - */ - int getHighestBit() const throw(); - - /** Converts the array to a number string. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - - If minuimumNumCharacters is greater than 0, the returned string will be - padded with leading zeros to reach at least that length. - */ - const String toString (const int base, const int minimumNumCharacters = 1) const throw(); - - /** Converts a number string to an array. - - Any non-valid characters will be ignored. - - Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex). - */ - void parseString (const String& text, - const int base) throw(); - - /** Turns the array into a block of binary data. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. - - @see loadFromMemoryBlock - */ - const MemoryBlock toMemoryBlock() const throw(); - - /** Copies a block of raw data onto this array. - - The data is arranged as little-endian, so the first byte of data is the low 8 bits - of the array, and so on. - - @see toMemoryBlock - */ - void loadFromMemoryBlock (const MemoryBlock& data) throw(); - - juce_UseDebuggingNewOperator - -private: - void ensureSize (const int numVals) throw(); - unsigned int* values; - int numValues, highestBit; - bool negative; -}; - -#endif // __JUCE_BITARRAY_JUCEHEADER__ -/********* End of inlined file: juce_BitArray.h *********/ - -/** - A simple pseudo-random number generator. -*/ -class JUCE_API Random -{ -public: - - /** Creates a Random object based on a seed value. - - For a given seed value, the subsequent numbers generated by this object - will be predictable, so a good idea is to set this value based - on the time, e.g. - - new Random (Time::currentTimeMillis()) - */ - Random (const int64 seedValue) throw(); - - /** Destructor. */ - ~Random() throw(); - - /** Returns the next random 32 bit integer. - - @returns a random integer from the full range 0x80000000 to 0x7fffffff - */ - int nextInt() throw(); - - /** Returns the next random number, limited to a given range. - - @returns a random integer between 0 (inclusive) and maxValue (exclusive). - */ - int nextInt (const int maxValue) throw(); - - /** Returns the next 64-bit random number. - - @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff - */ - int64 nextInt64() throw(); - - /** Returns the next random floating-point number. - - @returns a random value in the range 0 to 1.0 - */ - float nextFloat() throw(); - - /** Returns the next random floating-point number. - - @returns a random value in the range 0 to 1.0 - */ - double nextDouble() throw(); - - /** Returns the next random boolean value. - */ - bool nextBool() throw(); - - /** Returns a BitArray containing a random number. - - @returns a random value in the range 0 to (maximumValue - 1). - */ - const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); - - /** Sets a range of bits in a BitArray to random values. */ - void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); - - /** To avoid the overhead of having to create a new Random object whenever - you need a number, this is a shared application-wide object that - can be used. - - It's not thread-safe though, so threads should use their own Random object. - */ - static Random& getSystemRandom() throw(); - - /** Resets this Random object to a given seed value. */ - void setSeed (const int64 newSeed) throw(); - - /** Reseeds this generator using a value generated from various semi-random system - properties like the current time, etc. - - Because this function convolves the time with the last seed value, calling - it repeatedly will increase the randomness of the final result. - */ - void setSeedRandomly(); - - juce_UseDebuggingNewOperator - -private: - int64 seed; -}; - -#endif // __JUCE_RANDOM_JUCEHEADER__ -/********* End of inlined file: juce_Random.h *********/ - -#endif -#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ - -#endif -#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ - -/********* Start of inlined file: juce_SystemStats.h *********/ -#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ -#define __JUCE_SYSTEMSTATS_JUCEHEADER__ - -/** - Contains methods for finding out about the current hardware and OS configuration. -*/ -class JUCE_API SystemStats -{ -public: - - /** Returns the current version of JUCE, - - (just in case you didn't already know at compile-time.) - - See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros. - */ - static const String getJUCEVersion() throw(); - - /** The set of possible results of the getOperatingSystemType() method. - */ - enum OperatingSystemType - { - UnknownOS = 0, - - MacOSX = 0x1000, - Linux = 0x2000, - - Win95 = 0x4001, - Win98 = 0x4002, - WinNT351 = 0x4103, - WinNT40 = 0x4104, - Win2000 = 0x4105, - WinXP = 0x4106, - WinVista = 0x4107, - Windows7 = 0x4108, - - Windows = 0x4000, /**< To test whether any version of Windows is running, - you can use the expression ((getOperatingSystemType() & Windows) != 0). */ - WindowsNT = 0x0100, /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98), - you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */ - }; - - /** Returns the type of operating system we're running on. - - @returns one of the values from the OperatingSystemType enum. - @see getOperatingSystemName - */ - static OperatingSystemType getOperatingSystemType() throw(); - - /** Returns the name of the type of operating system we're running on. - - @returns a string describing the OS type. - @see getOperatingSystemType - */ - static const String getOperatingSystemName() throw(); - - /** Returns true if the OS is 64-bit, or false for a 32-bit OS. - */ - static bool isOperatingSystem64Bit() throw(); - - // CPU and memory information.. - - /** Returns the approximate CPU speed. - - @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on - what year you're reading this...) - */ - static int getCpuSpeedInMegaherz() throw(); - - /** Returns a string to indicate the CPU vendor. - - Might not be known on some systems. - */ - static const String getCpuVendor() throw(); - - /** Checks whether Intel MMX instructions are available. */ - static bool hasMMX() throw(); - - /** Checks whether Intel SSE instructions are available. */ - static bool hasSSE() throw(); - - /** Checks whether Intel SSE2 instructions are available. */ - static bool hasSSE2() throw(); - - /** Checks whether AMD 3DNOW instructions are available. */ - static bool has3DNow() throw(); - - /** Returns the number of CPUs. - */ - static int getNumCpus() throw(); - - /** Returns a clock-cycle tick counter, if available. - - If the machine can do it, this will return a tick-count - where each tick is one cpu clock cycle - used for profiling - code. - - @returns the tick count, or zero if not available. - */ - static int64 getClockCycleCounter() throw(); - - /** Finds out how much RAM is in the machine. - - @returns the approximate number of megabytes of memory, or zero if - something goes wrong when finding out. - */ - static int getMemorySizeInMegabytes() throw(); - - /** Returns the system page-size. - - This is only used by programmers with beards. - */ - static int getPageSize() throw(); - - /** Returns a list of MAC addresses found on this machine. - - @param addresses an array into which the MAC addresses should be copied - @param maxNum the number of elements in this array - @param littleEndian the endianness of the numbers to return. If this is true, - the least-significant byte of each number is the first byte - of the mac address. If false, the least significant byte is - the last number. Note that the default values of this parameter - are different on Mac/PC to avoid breaking old software that was - written before this parameter was added (when the two systems - defaulted to using different endiannesses). In newer - software you probably want to specify an explicit value - for this. - @returns the number of MAC addresses that were found - */ - static int getMACAddresses (int64* addresses, int maxNum, -#if JUCE_MAC - const bool littleEndian = true) throw(); -#else - const bool littleEndian = false) throw(); -#endif - - // not-for-public-use platform-specific method gets called at startup to initialise things. - static void initialiseStats() throw(); -}; - -#endif // __JUCE_SYSTEMSTATS_JUCEHEADER__ -/********* End of inlined file: juce_SystemStats.h *********/ - -#endif -#ifndef __JUCE_TIME_JUCEHEADER__ - -#endif -#ifndef __JUCE_UUID_JUCEHEADER__ - -/********* Start of inlined file: juce_Uuid.h *********/ -#ifndef __JUCE_UUID_JUCEHEADER__ -#define __JUCE_UUID_JUCEHEADER__ - -/** - A universally unique 128-bit identifier. - - This class generates very random unique numbers based on the system time - and MAC addresses if any are available. It's extremely unlikely that two identical - UUIDs would ever be created by chance. - - The class includes methods for saving the ID as a string or as raw binary data. -*/ -class JUCE_API Uuid -{ -public: - - /** Creates a new unique ID. */ - Uuid(); - - /** Destructor. */ - ~Uuid() throw(); - - /** Creates a copy of another UUID. */ - Uuid (const Uuid& other); - - /** Copies another UUID. */ - Uuid& operator= (const Uuid& other); - - /** Returns true if the ID is zero. */ - bool isNull() const throw(); - - /** Compares two UUIDs. */ - bool operator== (const Uuid& other) const; - - /** Compares two UUIDs. */ - bool operator!= (const Uuid& other) const; - - /** Returns a stringified version of this UUID. - - A Uuid object can later be reconstructed from this string using operator= or - the constructor that takes a string parameter. - - @returns a 32 character hex string. - */ - const String toString() const; - - /** Creates an ID from an encoded string version. - - @see toString - */ - Uuid (const String& uuidString); - - /** Copies from a stringified UUID. - - The string passed in should be one that was created with the toString() method. - */ - Uuid& operator= (const String& uuidString); - - /** Returns a pointer to the internal binary representation of the ID. - - This is an array of 16 bytes. To reconstruct a Uuid from its data, use - the constructor or operator= method that takes an array of uint8s. - */ - const uint8* getRawData() const throw() { return value.asBytes; } - - /** Creates a UUID from a 16-byte array. - - @see getRawData - */ - Uuid (const uint8* const rawData); - - /** Sets this UUID from 16-bytes of raw data. */ - Uuid& operator= (const uint8* const rawData); - - juce_UseDebuggingNewOperator - -private: - union - { - uint8 asBytes [16]; - int asInt[4]; - int64 asInt64[2]; - - } value; -}; - -#endif // __JUCE_UUID_JUCEHEADER__ -/********* End of inlined file: juce_Uuid.h *********/ - -#endif -#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ - -#endif -#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__ - -#endif -#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ - -#endif -#ifndef __JUCE_ARRAY_JUCEHEADER__ - -#endif -#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ - -#endif -#ifndef __JUCE_VARIANT_JUCEHEADER__ - -/********* Start of inlined file: juce_Variant.h *********/ -#ifndef __JUCE_VARIANT_JUCEHEADER__ -#define __JUCE_VARIANT_JUCEHEADER__ - -/********* Start of inlined file: juce_ReferenceCountedObject.h *********/ -#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ -#define __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ - -/** - Adds reference-counting to an object. - - To add reference-counting to a class, derive it from this class, and - use the ReferenceCountedObjectPtr class to point to it. - - e.g. @code - class MyClass : public ReferenceCountedObject - { - void foo(); - - // This is a neat way of declaring a typedef for a pointer class, - // rather than typing out the full templated name each time.. - typedef ReferenceCountedObjectPtr Ptr; - }; - - MyClass::Ptr p = new MyClass(); - MyClass::Ptr p2 = p; - p = 0; - p2->foo(); - @endcode - - Once a new ReferenceCountedObject has been assigned to a pointer, be - careful not to delete the object manually. - - @see ReferenceCountedObjectPtr, ReferenceCountedArray -*/ -class JUCE_API ReferenceCountedObject -{ -public: - - /** Increments the object's reference count. - - This is done automatically by the smart pointer, but is public just - in case it's needed for nefarious purposes. - */ - inline void incReferenceCount() throw() - { - atomicIncrement (refCounts); - - jassert (refCounts > 0); - } - - /** Decreases the object's reference count. - - If the count gets to zero, the object will be deleted. - */ - inline void decReferenceCount() throw() - { - jassert (refCounts > 0); - - if (atomicDecrementAndReturn (refCounts) == 0) - delete this; - } - - /** Returns the object's current reference count. */ - inline int getReferenceCount() const throw() - { - return refCounts; - } - -protected: - - /** Creates the reference-counted object (with an initial ref count of zero). */ - ReferenceCountedObject() - : refCounts (0) - { - } - - /** Destructor. */ - virtual ~ReferenceCountedObject() - { - // it's dangerous to delete an object that's still referenced by something else! - jassert (refCounts == 0); - } - -private: - - int refCounts; -}; - -/** - Used to point to an object of type ReferenceCountedObject. - - It's wise to use a typedef instead of typing out the templated name - each time - e.g. - - typedef ReferenceCountedObjectPtr MyClassPtr; - - @see ReferenceCountedObject, ReferenceCountedObjectArray -*/ -template -class ReferenceCountedObjectPtr -{ -public: - - /** Creates a pointer to a null object. */ - inline ReferenceCountedObjectPtr() throw() - : referencedObject (0) - { - } - - /** Creates a pointer to an object. - - This will increment the object's reference-count if it is non-null. - */ - inline ReferenceCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) throw() - : referencedObject (refCountedObject) - { - if (refCountedObject != 0) - refCountedObject->incReferenceCount(); - } - - /** Copies another pointer. - - This will increment the object's reference-count (if it is non-null). - */ - inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) throw() - : referencedObject (other.referencedObject) - { - if (referencedObject != 0) - referencedObject->incReferenceCount(); - } - - /** Changes this pointer to point at a different object. - - The reference count of the old object is decremented, and it might be - deleted if it hits zero. The new object's count is incremented. - */ - const ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) - { - ReferenceCountedObjectClass* const newObject = other.referencedObject; - - if (newObject != referencedObject) - { - if (newObject != 0) - newObject->incReferenceCount(); - - ReferenceCountedObjectClass* const oldObject = referencedObject; - referencedObject = newObject; - - if (oldObject != 0) - oldObject->decReferenceCount(); - } - - return *this; - } - - /** Changes this pointer to point at a different object. - - The reference count of the old object is decremented, and it might be - deleted if it hits zero. The new object's count is incremented. - */ - const ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) - { - if (referencedObject != newObject) - { - if (newObject != 0) - newObject->incReferenceCount(); - - ReferenceCountedObjectClass* const oldObject = referencedObject; - referencedObject = newObject; - - if (oldObject != 0) - oldObject->decReferenceCount(); - } - - return *this; - } - - /** Destructor. - - This will decrement the object's reference-count, and may delete it if it - gets to zero. - */ - inline ~ReferenceCountedObjectPtr() - { - if (referencedObject != 0) - referencedObject->decReferenceCount(); - } - - /** Returns the object that this pointer references. - - The pointer returned may be zero, of course. - */ - inline operator ReferenceCountedObjectClass*() const throw() - { - return referencedObject; - } - - /** Returns true if this pointer refers to the given object. */ - inline bool operator== (ReferenceCountedObjectClass* const object) const throw() - { - return referencedObject == object; - } - - /** Returns true if this pointer doesn't refer to the given object. */ - inline bool operator!= (ReferenceCountedObjectClass* const object) const throw() - { - return referencedObject != object; - } - - // the -> operator is called on the referenced object - inline ReferenceCountedObjectClass* operator->() const throw() - { - return referencedObject; - } - -private: - - ReferenceCountedObjectClass* referencedObject; -}; - -#endif // __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ -/********* End of inlined file: juce_ReferenceCountedObject.h *********/ - -/********* Start of inlined file: juce_OutputStream.h *********/ -#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__ -#define __JUCE_OUTPUTSTREAM_JUCEHEADER__ - -/********* Start of inlined file: juce_InputStream.h *********/ -#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__ -#define __JUCE_INPUTSTREAM_JUCEHEADER__ - -/** The base class for streams that read data. - - Input and output streams are used throughout the library - subclasses can override - some or all of the virtual functions to implement their behaviour. - - @see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream -*/ -class JUCE_API InputStream -{ -public: - /** Destructor. */ - virtual ~InputStream() {} - - /** Returns the total number of bytes available for reading in this stream. - - Note that this is the number of bytes available from the start of the - stream, not from the current position. - - If the size of the stream isn't actually known, this may return -1. - */ - virtual int64 getTotalLength() = 0; - - /** Returns true if the stream has no more data to read. */ - virtual bool isExhausted() = 0; - - /** Reads a set of bytes from the stream into a memory buffer. - - This is the only read method that subclasses actually need to implement, as the - InputStream base class implements the other read methods in terms of this one (although - it's often more efficient for subclasses to implement them directly). - - @param destBuffer the destination buffer for the data - @param maxBytesToRead the maximum number of bytes to read - make sure the - memory block passed in is big enough to contain this - many bytes. - - @returns the actual number of bytes that were read, which may be less than - maxBytesToRead if the stream is exhausted before it gets that far - */ - virtual int read (void* destBuffer, - int maxBytesToRead) = 0; - - /** Reads a byte from the stream. - - If the stream is exhausted, this will return zero. - - @see OutputStream::writeByte - */ - virtual char readByte(); - - /** Reads a boolean from the stream. - - The bool is encoded as a single byte - 1 for true, 0 for false. - - If the stream is exhausted, this will return false. - - @see OutputStream::writeBool - */ - virtual bool readBool(); - - /** Reads two bytes from the stream as a little-endian 16-bit value. - - If the next two bytes read are byte1 and byte2, this returns - (byte1 | (byte2 << 8)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeShort, readShortBigEndian - */ - virtual short readShort(); - - /** Reads two bytes from the stream as a little-endian 16-bit value. - - If the next two bytes read are byte1 and byte2, this returns - (byte2 | (byte1 << 8)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeShortBigEndian, readShort - */ - virtual short readShortBigEndian(); - - /** Reads four bytes from the stream as a little-endian 32-bit value. - - If the next four bytes are byte1 to byte4, this returns - (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt, readIntBigEndian - */ - virtual int readInt(); - - /** Reads four bytes from the stream as a big-endian 32-bit value. - - If the next four bytes are byte1 to byte4, this returns - (byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeIntBigEndian, readInt - */ - virtual int readIntBigEndian(); - - /** Reads eight bytes from the stream as a little-endian 64-bit value. - - If the next eight bytes are byte1 to byte8, this returns - (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt64, readInt64BigEndian - */ - virtual int64 readInt64(); - - /** Reads eight bytes from the stream as a big-endian 64-bit value. - - If the next eight bytes are byte1 to byte8, this returns - (byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)). - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeInt64BigEndian, readInt64 - */ - virtual int64 readInt64BigEndian(); - - /** Reads four bytes as a 32-bit floating point value. - - The raw 32-bit encoding of the float is read from the stream as a little-endian int. - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeFloat, readDouble - */ - virtual float readFloat(); - - /** Reads four bytes as a 32-bit floating point value. - - The raw 32-bit encoding of the float is read from the stream as a big-endian int. - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeFloatBigEndian, readDoubleBigEndian - */ - virtual float readFloatBigEndian(); - - /** Reads eight bytes as a 64-bit floating point value. - - The raw 64-bit encoding of the double is read from the stream as a little-endian int64. - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeDouble, readFloat - */ - virtual double readDouble(); - - /** Reads eight bytes as a 64-bit floating point value. - - The raw 64-bit encoding of the double is read from the stream as a big-endian int64. - - If the stream is exhausted partway through reading the bytes, this will return zero. - - @see OutputStream::writeDoubleBigEndian, readFloatBigEndian - */ - virtual double readDoubleBigEndian(); - - /** Reads an encoded 32-bit number from the stream using a space-saving compressed format. - - For small values, this is more space-efficient than using readInt() and OutputStream::writeInt() - - The format used is: number of significant bytes + up to 4 bytes in little-endian order. - - @see OutputStream::writeCompressedInt() - */ - virtual int readCompressedInt(); - - /** Reads a UTF8 string from the stream, up to the next linefeed or carriage return. - - This will read up to the next "\n" or "\r\n" or end-of-stream. - - After this call, the stream's position will be left pointing to the next character - following the line-feed, but the linefeeds aren't included in the string that - is returned. - */ - virtual const String readNextLine(); - - /** Reads a zero-terminated UTF8 string from the stream. - - This will read characters from the stream until it hits a zero character or - end-of-stream. - - @see OutputStream::writeString, readEntireStreamAsString - */ - virtual const String readString(); - - /** Tries to read the whole stream and turn it into a string. - - This will read from the stream's current position until the end-of-stream, and - will try to make an educated guess about whether it's unicode or an 8-bit encoding. - */ - virtual const String readEntireStreamAsString(); - - /** Reads from the stream and appends the data to a MemoryBlock. - - @param destBlock the block to append the data onto - @param maxNumBytesToRead if this is a positive value, it sets a limit to the number - of bytes that will be read - if it's negative, data - will be read until the stream is exhausted. - @returns the number of bytes that were added to the memory block - */ - virtual int readIntoMemoryBlock (MemoryBlock& destBlock, - int maxNumBytesToRead = -1); - - /** Returns the offset of the next byte that will be read from the stream. - - @see setPosition - */ - virtual int64 getPosition() = 0; - - /** Tries to move the current read position of the stream. - - The position is an absolute number of bytes from the stream's start. - - Some streams might not be able to do this, in which case they should do - nothing and return false. Others might be able to manage it by resetting - themselves and skipping to the correct position, although this is - obviously a bit slow. - - @returns true if the stream manages to reposition itself correctly - @see getPosition - */ - virtual bool setPosition (int64 newPosition) = 0; - - /** Reads and discards a number of bytes from the stream. - - Some input streams might implement this efficiently, but the base - class will just keep reading data until the requisite number of bytes - have been done. - */ - virtual void skipNextBytes (int64 numBytesToSkip); - - juce_UseDebuggingNewOperator - -protected: - - InputStream() throw() {} -}; - -#endif // __JUCE_INPUTSTREAM_JUCEHEADER__ -/********* End of inlined file: juce_InputStream.h *********/ - -/** - The base class for streams that write data to some kind of destination. - - Input and output streams are used throughout the library - subclasses can override - some or all of the virtual functions to implement their behaviour. - - @see InputStream, MemoryOutputStream, FileOutputStream -*/ -class JUCE_API OutputStream -{ -public: - /** Destructor. - - Some subclasses might want to do things like call flush() during their - destructors. - */ - virtual ~OutputStream(); - - /** If the stream is using a buffer, this will ensure it gets written - out to the destination. */ - virtual void flush() = 0; - - /** Tries to move the stream's output position. - - Not all streams will be able to seek to a new position - this will return - false if it fails to work. - - @see getPosition - */ - virtual bool setPosition (int64 newPosition) = 0; - - /** Returns the stream's current position. - - @see setPosition - */ - virtual int64 getPosition() = 0; - - /** Writes a block of data to the stream. - - When creating a subclass of OutputStream, this is the only write method - that needs to be overloaded - the base class has methods for writing other - types of data which use this to do the work. - - @returns false if the write operation fails for some reason - */ - virtual bool write (const void* dataToWrite, - int howManyBytes) = 0; - - /** Writes a single byte to the stream. - - @see InputStream::readByte - */ - virtual void writeByte (char byte); - - /** Writes a boolean to the stream. - - This is encoded as a byte - either 1 or 0. - - @see InputStream::readBool - */ - virtual void writeBool (bool boolValue); - - /** Writes a 16-bit integer to the stream in a little-endian byte order. - - This will write two bytes to the stream: (value & 0xff), then (value >> 8). - - @see InputStream::readShort - */ - virtual void writeShort (short value); - - /** Writes a 16-bit integer to the stream in a big-endian byte order. - - This will write two bytes to the stream: (value >> 8), then (value & 0xff). - - @see InputStream::readShortBigEndian - */ - virtual void writeShortBigEndian (short value); - - /** Writes a 32-bit integer to the stream in a little-endian byte order. - - @see InputStream::readInt - */ - virtual void writeInt (int value); - - /** Writes a 32-bit integer to the stream in a big-endian byte order. - - @see InputStream::readIntBigEndian - */ - virtual void writeIntBigEndian (int value); - - /** Writes a 64-bit integer to the stream in a little-endian byte order. - - @see InputStream::readInt64 - */ - virtual void writeInt64 (int64 value); - - /** Writes a 64-bit integer to the stream in a big-endian byte order. - - @see InputStream::readInt64BigEndian - */ - virtual void writeInt64BigEndian (int64 value); - - /** Writes a 32-bit floating point value to the stream. - - The binary 32-bit encoding of the float is written as a little-endian int. - - @see InputStream::readFloat - */ - virtual void writeFloat (float value); - - /** Writes a 32-bit floating point value to the stream. - - The binary 32-bit encoding of the float is written as a big-endian int. - - @see InputStream::readFloatBigEndian - */ - virtual void writeFloatBigEndian (float value); - - /** Writes a 64-bit floating point value to the stream. - - The eight raw bytes of the double value are written out as a little-endian 64-bit int. - - @see InputStream::readDouble - */ - virtual void writeDouble (double value); - - /** Writes a 64-bit floating point value to the stream. - - The eight raw bytes of the double value are written out as a big-endian 64-bit int. - - @see InputStream::readDoubleBigEndian - */ - virtual void writeDoubleBigEndian (double value); - - /** Writes a condensed encoding of a 32-bit integer. - - If you're storing a lot of integers which are unlikely to have very large values, - this can save a lot of space, because values under 0xff will only take up 2 bytes, - under 0xffff only 3 bytes, etc. - - The format used is: number of significant bytes + up to 4 bytes in little-endian order. - - @see InputStream::readCompressedInt - */ - virtual void writeCompressedInt (int value); - - /** Stores a string in the stream. - - This isn't the method to use if you're trying to append text to the end of a - text-file! It's intended for storing a string for later retrieval - by InputStream::readString. - - It writes the string to the stream as UTF8, with a null character terminating it. - - For appending text to a file, instead use writeText, printf, or operator<< - - @see InputStream::readString, writeText, printf, operator<< - */ - virtual void writeString (const String& text); - - /** Writes a string of text to the stream. - - It can either write it as 8-bit system-encoded characters, or as unicode, and - can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this - should only be done at the start of a file). - - The method also replaces '\\n' characters in the text with '\\r\\n'. - */ - virtual void writeText (const String& text, - const bool asUnicode, - const bool writeUnicodeHeaderBytes); - - /** Writes a string of text to the stream. - - @see writeText - */ - virtual void printf (const char* format, ...); - - /** Reads data from an input stream and writes it to this stream. - - @param source the stream to read from - @param maxNumBytesToWrite the number of bytes to read from the stream (if this is - less than zero, it will keep reading until the input - is exhausted) - */ - virtual int writeFromInputStream (InputStream& source, - int maxNumBytesToWrite); - - /** Writes a number to the stream as 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const int number); - - /** Writes a number to the stream as 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const double number); - - /** Writes a character to the stream. */ - virtual OutputStream& operator<< (const char character); - - /** Writes a null-terminated string to the stream. */ - virtual OutputStream& operator<< (const char* const text); - - /** Writes a null-terminated unicode text string to the stream, converting it - to 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const juce_wchar* const text); - - /** Writes a string to the stream as 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const String& text); - - juce_UseDebuggingNewOperator - -protected: - - OutputStream() throw(); -}; - -#endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ -/********* End of inlined file: juce_OutputStream.h *********/ - -class JUCE_API DynamicObject; - -/** - A variant class, that can be used to hold a range of primitive values. - - A var object can hold a range of simple primitive values, strings, or - a reference-counted pointer to a DynamicObject. The var class is intended - to act like the values used in dynamic scripting languages. - - @see DynamicObject -*/ -class JUCE_API var -{ -public: - - typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments); - - /** Creates a void variant. */ - var() throw(); - - /** Destructor. */ - ~var(); - - var (const var& valueToCopy) throw(); - var (const int value) throw(); - var (const bool value) throw(); - var (const double value) throw(); - var (const char* const value) throw(); - var (const juce_wchar* const value) throw(); - var (const String& value) throw(); - var (DynamicObject* const object) throw(); - var (MethodFunction method) throw(); - - const var& operator= (const var& valueToCopy) throw(); - const var& operator= (const int value) throw(); - const var& operator= (const bool value) throw(); - const var& operator= (const double value) throw(); - const var& operator= (const char* const value) throw(); - const var& operator= (const juce_wchar* const value) throw(); - const var& operator= (const String& value) throw(); - const var& operator= (DynamicObject* const object) throw(); - const var& operator= (MethodFunction method) throw(); - - operator int() const throw(); - operator bool() const throw(); - operator float() const throw(); - operator double() const throw(); - operator const String() const throw(); - const String toString() const throw(); - DynamicObject* getObject() const throw(); - - bool isVoid() const throw() { return type == voidType; } - bool isInt() const throw() { return type == intType; } - bool isBool() const throw() { return type == boolType; } - bool isDouble() const throw() { return type == doubleType; } - bool isString() const throw() { return type == stringType; } - bool isObject() const throw() { return type == objectType; } - bool isMethod() const throw() { return type == methodType; } - - bool operator== (const var& other) const throw(); - bool operator!= (const var& other) const throw(); - - /** Writes a binary representation of this value to a stream. - The data can be read back later using readFromStream(). - */ - void writeToStream (OutputStream& output) const throw(); - - /** Reads back a stored binary representation of a value. - The data in the stream must have been written using writeToStream(), or this - will have unpredictable results. - */ - static const var readFromStream (InputStream& input) throw(); - - class JUCE_API identifier - { - public: - identifier (const char* const name) throw(); - identifier (const String& name) throw(); - ~identifier() throw(); - - bool operator== (const identifier& other) const throw() - { - jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions - return hashCode == other.hashCode; - } - - String name; - int hashCode; - }; - - /** If this variant is an object, this returns one of its properties. */ - const var operator[] (const identifier& propertyName) const throw(); - - /** If this variant is an object, this invokes one of its methods with no arguments. */ - const var call (const identifier& method) const; - /** If this variant is an object, this invokes one of its methods with one argument. */ - const var call (const identifier& method, const var& arg1) const; - /** If this variant is an object, this invokes one of its methods with 2 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2) const; - /** If this variant is an object, this invokes one of its methods with 3 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); - /** If this variant is an object, this invokes one of its methods with 4 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; - /** If this variant is an object, this invokes one of its methods with 5 arguments. */ - const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; - - /** If this variant is an object, this invokes one of its methods with a list of arguments. */ - const var invoke (const identifier& method, const var* arguments, int numArguments) const; - - /** If this variant is a method pointer, this invokes it on a target object. */ - const var invoke (const var& targetObject, const var* arguments, int numArguments) const; - - juce_UseDebuggingNewOperator - -private: - enum Type - { - voidType = 0, - intType, - boolType, - doubleType, - stringType, - objectType, - methodType - }; - - Type type; - - union - { - int intValue; - bool boolValue; - double doubleValue; - String* stringValue; - DynamicObject* objectValue; - MethodFunction methodValue; - } value; - - void releaseValue() throw(); -}; - -/** - Represents a dynamically implemented object. - - An instance of this class can be used to store named properties, and - by subclassing hasMethod() and invokeMethod(), you can give your object - methods. - - This is intended for use as a wrapper for scripting language objects. -*/ -class JUCE_API DynamicObject : public ReferenceCountedObject -{ -public: - - DynamicObject(); - - /** Destructor. */ - virtual ~DynamicObject(); - - /** Returns true if the object has a property with this name. - Note that if the property is actually a method, this will return false. - */ - virtual bool hasProperty (const var::identifier& propertyName) const; - - /** Returns a named property. - - This returns a void if no such property exists. - */ - virtual const var getProperty (const var::identifier& propertyName) const; - - /** Sets a named property. */ - virtual void setProperty (const var::identifier& propertyName, const var& newValue); - - /** Removes a named property. */ - virtual void removeProperty (const var::identifier& propertyName); - - /** Checks whether this object has the specified method. - - The default implementation of this just checks whether there's a property - with this name that's actually a method, but this can be overridden for - building objects with dynamic invocation. - */ - virtual bool hasMethod (const var::identifier& methodName) const; - - /** Invokes a named method on this object. - - The default implementation looks up the named property, and if it's a method - call, then it invokes it. - - This method is virtual to allow more dynamic invocation to used for objects - where the methods may not already be set as properies. - */ - virtual const var invokeMethod (const var::identifier& methodName, - const var* parameters, - int numParameters); - - /** Sets up a method. - - This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but - helps to avoid accidentally invoking the wrong type of var constructor. It also makes - the code easier to read, - - The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g. - @code - setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething); - @endcode - */ - void setMethod (const var::identifier& methodName, - var::MethodFunction methodFunction); - - /** Removes all properties and methods from the object. */ - void clear(); - - juce_UseDebuggingNewOperator - -private: - Array propertyIds; - OwnedArray propertyValues; -}; - -#endif // __JUCE_VARIANT_JUCEHEADER__ -/********* End of inlined file: juce_Variant.h *********/ - -#endif -#ifndef __JUCE_BITARRAY_JUCEHEADER__ - -#endif -#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ - -#endif -#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ - -#endif -#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__ - -#endif -#ifndef __JUCE_PROPERTYSET_JUCEHEADER__ - -/********* Start of inlined file: juce_PropertySet.h *********/ -#ifndef __JUCE_PROPERTYSET_JUCEHEADER__ -#define __JUCE_PROPERTYSET_JUCEHEADER__ - -/********* Start of inlined file: juce_StringPairArray.h *********/ -#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__ -#define __JUCE_STRINGPAIRARRAY_JUCEHEADER__ - -/** - A container for holding a set of strings which are keyed by another string. - - @see StringArray -*/ -class JUCE_API StringPairArray -{ -public: - - /** Creates an empty array */ - StringPairArray (const bool ignoreCaseWhenComparingKeys = true) throw(); - - /** Creates a copy of another array */ - StringPairArray (const StringPairArray& other) throw(); - - /** Destructor. */ - ~StringPairArray() throw(); - - /** Copies the contents of another string array into this one */ - const StringPairArray& operator= (const StringPairArray& other) throw(); - - /** Compares two arrays. - - Comparisons are case-sensitive. - - @returns true only if the other array contains exactly the same strings with the same keys - */ - bool operator== (const StringPairArray& other) const throw(); - - /** Compares two arrays. - - Comparisons are case-sensitive. - - @returns false if the other array contains exactly the same strings with the same keys - */ - bool operator!= (const StringPairArray& other) const throw(); - - /** Finds the value corresponding to a key string. - - If no such key is found, this will just return an empty string. To check whether - a given key actually exists (because it might actually be paired with an empty string), use - the getAllKeys() method to obtain a list. - - Obviously the reference returned shouldn't be stored for later use, as the - string it refers to may disappear when the array changes. - - @see getValue - */ - const String& operator[] (const String& key) const throw(); - - /** Finds the value corresponding to a key string. - - If no such key is found, this will just return the value provided as a default. - - @see operator[] - */ - const String getValue (const String& key, const String& defaultReturnValue) const; - - /** Returns a list of all keys in the array. */ - const StringArray& getAllKeys() const throw() { return keys; } - - /** Returns a list of all values in the array. */ - const StringArray& getAllValues() const throw() { return values; } - - /** Returns the number of strings in the array */ - inline int size() const throw() { return keys.size(); }; - - /** Adds or amends a key/value pair. - - If a value already exists with this key, its value will be overwritten, - otherwise the key/value pair will be added to the array. - */ - void set (const String& key, - const String& value) throw(); - - /** Adds the items from another array to this one. - - This is equivalent to using set() to add each of the pairs from the other array. - */ - void addArray (const StringPairArray& other); - - /** Removes all elements from the array. */ - void clear() throw(); - - /** Removes a string from the array based on its key. - - If the key isn't found, nothing will happen. - */ - void remove (const String& key) throw(); - - /** Removes a string from the array based on its index. - - If the index is out-of-range, no action will be taken. - */ - void remove (const int index) throw(); - - /** Indicates whether to use a case-insensitive search when looking up a key string. - */ - void setIgnoresCase (const bool shouldIgnoreCase) throw(); - - /** Returns a descriptive string containing the items. - - This is handy for dumping the contents of an array. - */ - const String getDescription() const; - - /** Reduces the amount of storage being used by the array. - - Arrays typically allocate slightly more storage than they need, and after - removing elements, they may have quite a lot of unused space allocated. - This method will reduce the amount of allocated storage to a minimum. - */ - void minimiseStorageOverheads() throw(); - - juce_UseDebuggingNewOperator - -private: - StringArray keys, values; - bool ignoreCase; -}; - -#endif // __JUCE_STRINGPAIRARRAY_JUCEHEADER__ -/********* End of inlined file: juce_StringPairArray.h *********/ - -/********* Start of inlined file: juce_XmlElement.h *********/ -#ifndef __JUCE_XMLELEMENT_JUCEHEADER__ -#define __JUCE_XMLELEMENT_JUCEHEADER__ - /** A handy macro to make it easy to iterate all the child elements in an XmlElement. The parentXmlElement should be a reference to the parent XML, and the childElementVariableName @@ -10169,10 +8526,10 @@ public: if (num > 1) { - XmlElement** const elems = getChildElementsAsArray (num); - sortArray (comparator, elems, 0, num - 1, retainOrderOfEquivalentItems); + HeapBlock elems (num); + getChildElementsAsArray (elems); + sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems); reorderChildElements (elems, num); - delete[] elems; } } @@ -10278,7 +8635,7 @@ private: const int indentationLevel, const int lineWrapLength) const throw(); - XmlElement** getChildElementsAsArray (const int) const throw(); + void getChildElementsAsArray (XmlElement**) const throw(); void reorderChildElements (XmlElement** const, const int) throw(); }; @@ -10503,6 +8860,411 @@ private: #ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__ #define __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__ +/********* Start of inlined file: juce_ReferenceCountedObject.h *********/ +#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ +#define __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ + +/********* Start of inlined file: juce_Atomic.h *********/ +#ifndef __JUCE_ATOMIC_JUCEHEADER__ +#define __JUCE_ATOMIC_JUCEHEADER__ + +// Atomic increment/decrement operations.. + +#if (JUCE_MAC || JUCE_IPHONE) && ! DOXYGEN + + #include + static forcedinline void atomicIncrement (int& variable) throw() { OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline int atomicIncrementAndReturn (int& variable) throw() { return OSAtomicIncrement32 ((int32_t*) &variable); } + static forcedinline void atomicDecrement (int& variable) throw() { OSAtomicDecrement32 ((int32_t*) &variable); } + static forcedinline int atomicDecrementAndReturn (int& variable) throw() { return OSAtomicDecrement32 ((int32_t*) &variable); } + +#elif JUCE_GCC + + #if JUCE_USE_GCC_ATOMIC_INTRINSICS + forcedinline void atomicIncrement (int& variable) throw() { __sync_add_and_fetch (&variable, 1); } + forcedinline int atomicIncrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, 1); } + forcedinline void atomicDecrement (int& variable) throw() { __sync_add_and_fetch (&variable, -1); } + forcedinline int atomicDecrementAndReturn (int& variable) throw() { return __sync_add_and_fetch (&variable, -1); } + #else + + /** Increments an integer in a thread-safe way. */ + forcedinline void atomicIncrement (int& variable) throw() + { + __asm__ __volatile__ ( + #if JUCE_64BIT + "lock incl (%%rax)" + : + : "a" (&variable) + : "cc", "memory"); + #else + "lock incl %0" + : "=m" (variable) + : "m" (variable)); + #endif + } + + /** Increments an integer in a thread-safe way and returns the incremented value. */ + forcedinline int atomicIncrementAndReturn (int& variable) throw() + { + int result; + + __asm__ __volatile__ ( + #if JUCE_64BIT + "lock xaddl %%ebx, (%%rax) \n\ + incl %%ebx" + : "=b" (result) + : "a" (&variable), "b" (1) + : "cc", "memory"); + #else + "lock xaddl %%eax, (%%ecx) \n\ + incl %%eax" + : "=a" (result) + : "c" (&variable), "a" (1) + : "memory"); + #endif + + return result; + } + + /** Decrememts an integer in a thread-safe way. */ + forcedinline void atomicDecrement (int& variable) throw() + { + __asm__ __volatile__ ( + #if JUCE_64BIT + "lock decl (%%rax)" + : + : "a" (&variable) + : "cc", "memory"); + #else + "lock decl %0" + : "=m" (variable) + : "m" (variable)); + #endif + } + + /** Decrememts an integer in a thread-safe way and returns the incremented value. */ + forcedinline int atomicDecrementAndReturn (int& variable) throw() + { + int result; + + __asm__ __volatile__ ( + #if JUCE_64BIT + "lock xaddl %%ebx, (%%rax) \n\ + decl %%ebx" + : "=b" (result) + : "a" (&variable), "b" (-1) + : "cc", "memory"); + #else + "lock xaddl %%eax, (%%ecx) \n\ + decl %%eax" + : "=a" (result) + : "c" (&variable), "a" (-1) + : "memory"); + #endif + return result; + } + #endif + +#elif JUCE_USE_INTRINSICS + + #pragma intrinsic (_InterlockedIncrement) + #pragma intrinsic (_InterlockedDecrement) + + /** Increments an integer in a thread-safe way. */ + forcedinline void __fastcall atomicIncrement (int& variable) throw() + { + _InterlockedIncrement (reinterpret_cast (&variable)); + } + + /** Increments an integer in a thread-safe way and returns the incremented value. */ + forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw() + { + return _InterlockedIncrement (reinterpret_cast (&variable)); + } + + /** Decrememts an integer in a thread-safe way. */ + forcedinline void __fastcall atomicDecrement (int& variable) throw() + { + _InterlockedDecrement (reinterpret_cast (&variable)); + } + + /** Decrememts an integer in a thread-safe way and returns the incremented value. */ + forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw() + { + return _InterlockedDecrement (reinterpret_cast (&variable)); + } +#else + + /** Increments an integer in a thread-safe way. */ + forcedinline void __fastcall atomicIncrement (int& variable) throw() + { + __asm { + mov ecx, dword ptr [variable] + lock inc dword ptr [ecx] + } + } + + /** Increments an integer in a thread-safe way and returns the incremented value. */ + forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw() + { + int result; + + __asm { + mov ecx, dword ptr [variable] + mov eax, 1 + lock xadd dword ptr [ecx], eax + inc eax + mov result, eax + } + + return result; + } + + /** Decrememts an integer in a thread-safe way. */ + forcedinline void __fastcall atomicDecrement (int& variable) throw() + { + __asm { + mov ecx, dword ptr [variable] + lock dec dword ptr [ecx] + } + } + + /** Decrememts an integer in a thread-safe way and returns the incremented value. */ + forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw() + { + int result; + + __asm { + mov ecx, dword ptr [variable] + mov eax, -1 + lock xadd dword ptr [ecx], eax + dec eax + mov result, eax + } + + return result; + } +#endif + +#endif // __JUCE_ATOMIC_JUCEHEADER__ +/********* End of inlined file: juce_Atomic.h *********/ + +/** + Adds reference-counting to an object. + + To add reference-counting to a class, derive it from this class, and + use the ReferenceCountedObjectPtr class to point to it. + + e.g. @code + class MyClass : public ReferenceCountedObject + { + void foo(); + + // This is a neat way of declaring a typedef for a pointer class, + // rather than typing out the full templated name each time.. + typedef ReferenceCountedObjectPtr Ptr; + }; + + MyClass::Ptr p = new MyClass(); + MyClass::Ptr p2 = p; + p = 0; + p2->foo(); + @endcode + + Once a new ReferenceCountedObject has been assigned to a pointer, be + careful not to delete the object manually. + + @see ReferenceCountedObjectPtr, ReferenceCountedArray +*/ +class JUCE_API ReferenceCountedObject +{ +public: + + /** Increments the object's reference count. + + This is done automatically by the smart pointer, but is public just + in case it's needed for nefarious purposes. + */ + inline void incReferenceCount() throw() + { + atomicIncrement (refCounts); + + jassert (refCounts > 0); + } + + /** Decreases the object's reference count. + + If the count gets to zero, the object will be deleted. + */ + inline void decReferenceCount() throw() + { + jassert (refCounts > 0); + + if (atomicDecrementAndReturn (refCounts) == 0) + delete this; + } + + /** Returns the object's current reference count. */ + inline int getReferenceCount() const throw() + { + return refCounts; + } + +protected: + + /** Creates the reference-counted object (with an initial ref count of zero). */ + ReferenceCountedObject() + : refCounts (0) + { + } + + /** Destructor. */ + virtual ~ReferenceCountedObject() + { + // it's dangerous to delete an object that's still referenced by something else! + jassert (refCounts == 0); + } + +private: + + int refCounts; +}; + +/** + Used to point to an object of type ReferenceCountedObject. + + It's wise to use a typedef instead of typing out the templated name + each time - e.g. + + typedef ReferenceCountedObjectPtr MyClassPtr; + + @see ReferenceCountedObject, ReferenceCountedObjectArray +*/ +template +class ReferenceCountedObjectPtr +{ +public: + + /** Creates a pointer to a null object. */ + inline ReferenceCountedObjectPtr() throw() + : referencedObject (0) + { + } + + /** Creates a pointer to an object. + + This will increment the object's reference-count if it is non-null. + */ + inline ReferenceCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) throw() + : referencedObject (refCountedObject) + { + if (refCountedObject != 0) + refCountedObject->incReferenceCount(); + } + + /** Copies another pointer. + + This will increment the object's reference-count (if it is non-null). + */ + inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) throw() + : referencedObject (other.referencedObject) + { + if (referencedObject != 0) + referencedObject->incReferenceCount(); + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + const ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) + { + ReferenceCountedObjectClass* const newObject = other.referencedObject; + + if (newObject != referencedObject) + { + if (newObject != 0) + newObject->incReferenceCount(); + + ReferenceCountedObjectClass* const oldObject = referencedObject; + referencedObject = newObject; + + if (oldObject != 0) + oldObject->decReferenceCount(); + } + + return *this; + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + const ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) + { + if (referencedObject != newObject) + { + if (newObject != 0) + newObject->incReferenceCount(); + + ReferenceCountedObjectClass* const oldObject = referencedObject; + referencedObject = newObject; + + if (oldObject != 0) + oldObject->decReferenceCount(); + } + + return *this; + } + + /** Destructor. + + This will decrement the object's reference-count, and may delete it if it + gets to zero. + */ + inline ~ReferenceCountedObjectPtr() + { + if (referencedObject != 0) + referencedObject->decReferenceCount(); + } + + /** Returns the object that this pointer references. + + The pointer returned may be zero, of course. + */ + inline operator ReferenceCountedObjectClass*() const throw() + { + return referencedObject; + } + + /** Returns true if this pointer refers to the given object. */ + inline bool operator== (ReferenceCountedObjectClass* const object) const throw() + { + return referencedObject == object; + } + + /** Returns true if this pointer doesn't refer to the given object. */ + inline bool operator!= (ReferenceCountedObjectClass* const object) const throw() + { + return referencedObject != object; + } + + // the -> operator is called on the referenced object + inline ReferenceCountedObjectClass* operator->() const throw() + { + return referencedObject; + } + +private: + + ReferenceCountedObjectClass* referencedObject; +}; + +#endif // __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__ +/********* End of inlined file: juce_ReferenceCountedObject.h *********/ + /** Holds a list of objects derived from ReferenceCountedObject. @@ -12191,9 +10953,6 @@ private: #endif // __JUCE_SPARSESET_JUCEHEADER__ /********* End of inlined file: juce_SparseSet.h *********/ -#endif -#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ - #endif #ifndef __JUCE_VALUETREE_JUCEHEADER__ @@ -12201,6 +10960,233 @@ private: #ifndef __JUCE_VALUETREE_JUCEHEADER__ #define __JUCE_VALUETREE_JUCEHEADER__ +/********* Start of inlined file: juce_Variant.h *********/ +#ifndef __JUCE_VARIANT_JUCEHEADER__ +#define __JUCE_VARIANT_JUCEHEADER__ + +class JUCE_API DynamicObject; + +/** + A variant class, that can be used to hold a range of primitive values. + + A var object can hold a range of simple primitive values, strings, or + a reference-counted pointer to a DynamicObject. The var class is intended + to act like the values used in dynamic scripting languages. + + @see DynamicObject +*/ +class JUCE_API var +{ +public: + + typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments); + + /** Creates a void variant. */ + var() throw(); + + /** Destructor. */ + ~var(); + + var (const var& valueToCopy) throw(); + var (const int value) throw(); + var (const bool value) throw(); + var (const double value) throw(); + var (const char* const value) throw(); + var (const juce_wchar* const value) throw(); + var (const String& value) throw(); + var (DynamicObject* const object) throw(); + var (MethodFunction method) throw(); + + const var& operator= (const var& valueToCopy) throw(); + const var& operator= (const int value) throw(); + const var& operator= (const bool value) throw(); + const var& operator= (const double value) throw(); + const var& operator= (const char* const value) throw(); + const var& operator= (const juce_wchar* const value) throw(); + const var& operator= (const String& value) throw(); + const var& operator= (DynamicObject* const object) throw(); + const var& operator= (MethodFunction method) throw(); + + operator int() const throw(); + operator bool() const throw(); + operator float() const throw(); + operator double() const throw(); + operator const String() const throw(); + const String toString() const throw(); + DynamicObject* getObject() const throw(); + + bool isVoid() const throw() { return type == voidType; } + bool isInt() const throw() { return type == intType; } + bool isBool() const throw() { return type == boolType; } + bool isDouble() const throw() { return type == doubleType; } + bool isString() const throw() { return type == stringType; } + bool isObject() const throw() { return type == objectType; } + bool isMethod() const throw() { return type == methodType; } + + bool operator== (const var& other) const throw(); + bool operator!= (const var& other) const throw(); + + /** Writes a binary representation of this value to a stream. + The data can be read back later using readFromStream(). + */ + void writeToStream (OutputStream& output) const throw(); + + /** Reads back a stored binary representation of a value. + The data in the stream must have been written using writeToStream(), or this + will have unpredictable results. + */ + static const var readFromStream (InputStream& input) throw(); + + class JUCE_API identifier + { + public: + identifier (const char* const name) throw(); + identifier (const String& name) throw(); + ~identifier() throw(); + + bool operator== (const identifier& other) const throw() + { + jassert (hashCode != other.hashCode || name == other.name); // check for name hash collisions + return hashCode == other.hashCode; + } + + String name; + int hashCode; + }; + + /** If this variant is an object, this returns one of its properties. */ + const var operator[] (const identifier& propertyName) const throw(); + + /** If this variant is an object, this invokes one of its methods with no arguments. */ + const var call (const identifier& method) const; + /** If this variant is an object, this invokes one of its methods with one argument. */ + const var call (const identifier& method, const var& arg1) const; + /** If this variant is an object, this invokes one of its methods with 2 arguments. */ + const var call (const identifier& method, const var& arg1, const var& arg2) const; + /** If this variant is an object, this invokes one of its methods with 3 arguments. */ + const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3); + /** If this variant is an object, this invokes one of its methods with 4 arguments. */ + const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const; + /** If this variant is an object, this invokes one of its methods with 5 arguments. */ + const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const; + + /** If this variant is an object, this invokes one of its methods with a list of arguments. */ + const var invoke (const identifier& method, const var* arguments, int numArguments) const; + + /** If this variant is a method pointer, this invokes it on a target object. */ + const var invoke (const var& targetObject, const var* arguments, int numArguments) const; + + juce_UseDebuggingNewOperator + +private: + enum Type + { + voidType = 0, + intType, + boolType, + doubleType, + stringType, + objectType, + methodType + }; + + Type type; + + union + { + int intValue; + bool boolValue; + double doubleValue; + String* stringValue; + DynamicObject* objectValue; + MethodFunction methodValue; + } value; + + void releaseValue() throw(); +}; + +/** + Represents a dynamically implemented object. + + An instance of this class can be used to store named properties, and + by subclassing hasMethod() and invokeMethod(), you can give your object + methods. + + This is intended for use as a wrapper for scripting language objects. +*/ +class JUCE_API DynamicObject : public ReferenceCountedObject +{ +public: + + DynamicObject(); + + /** Destructor. */ + virtual ~DynamicObject(); + + /** Returns true if the object has a property with this name. + Note that if the property is actually a method, this will return false. + */ + virtual bool hasProperty (const var::identifier& propertyName) const; + + /** Returns a named property. + + This returns a void if no such property exists. + */ + virtual const var getProperty (const var::identifier& propertyName) const; + + /** Sets a named property. */ + virtual void setProperty (const var::identifier& propertyName, const var& newValue); + + /** Removes a named property. */ + virtual void removeProperty (const var::identifier& propertyName); + + /** Checks whether this object has the specified method. + + The default implementation of this just checks whether there's a property + with this name that's actually a method, but this can be overridden for + building objects with dynamic invocation. + */ + virtual bool hasMethod (const var::identifier& methodName) const; + + /** Invokes a named method on this object. + + The default implementation looks up the named property, and if it's a method + call, then it invokes it. + + This method is virtual to allow more dynamic invocation to used for objects + where the methods may not already be set as properies. + */ + virtual const var invokeMethod (const var::identifier& methodName, + const var* parameters, + int numParameters); + + /** Sets up a method. + + This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but + helps to avoid accidentally invoking the wrong type of var constructor. It also makes + the code easier to read, + + The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g. + @code + setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething); + @endcode + */ + void setMethod (const var::identifier& methodName, + var::MethodFunction methodFunction); + + /** Removes all properties and methods from the object. */ + void clear(); + + juce_UseDebuggingNewOperator + +private: + Array propertyIds; + OwnedArray propertyValues; +}; + +#endif // __JUCE_VARIANT_JUCEHEADER__ +/********* End of inlined file: juce_Variant.h *********/ + /********* Start of inlined file: juce_UndoManager.h *********/ #ifndef __JUCE_UNDOMANAGER_JUCEHEADER__ #define __JUCE_UNDOMANAGER_JUCEHEADER__ @@ -12370,6 +11356,138 @@ public: #endif // __JUCE_MESSAGELISTENER_JUCEHEADER__ /********* End of inlined file: juce_MessageListener.h *********/ +/********* Start of inlined file: juce_ScopedLock.h *********/ +#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__ +#define __JUCE_SCOPEDLOCK_JUCEHEADER__ + +/** + Automatically locks and unlocks a CriticalSection object. + + Use one of these as a local variable to control access to a CriticalSection. + + e.g. @code + + CriticalSection myCriticalSection; + + for (;;) + { + const ScopedLock myScopedLock (myCriticalSection); + // myCriticalSection is now locked + + ...do some stuff... + + // myCriticalSection gets unlocked here. + } + @endcode + + @see CriticalSection, ScopedUnlock +*/ +class JUCE_API ScopedLock +{ +public: + + /** Creates a ScopedLock. + + As soon as it is created, this will lock the CriticalSection, and + when the ScopedLock object is deleted, the CriticalSection will + be unlocked. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! Best just to use it + as a local stack object, rather than creating one with the new() operator. + */ + inline ScopedLock (const CriticalSection& lock) throw() : lock_ (lock) { lock.enter(); } + + /** Destructor. + + The CriticalSection will be unlocked when the destructor is called. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! + */ + inline ~ScopedLock() throw() { lock_.exit(); } + +private: + + const CriticalSection& lock_; + + ScopedLock (const ScopedLock&); + const ScopedLock& operator= (const ScopedLock&); +}; + +/** + Automatically unlocks and re-locks a CriticalSection object. + + This is the reverse of a ScopedLock object - instead of locking the critical + section for the lifetime of this object, it unlocks it. + + Make sure you don't try to unlock critical sections that aren't actually locked! + + e.g. @code + + CriticalSection myCriticalSection; + + for (;;) + { + const ScopedLock myScopedLock (myCriticalSection); + // myCriticalSection is now locked + + ... do some stuff with it locked .. + + while (xyz) + { + ... do some stuff with it locked .. + + const ScopedUnlock unlocker (myCriticalSection); + + // myCriticalSection is now unlocked for the remainder of this block, + // and re-locked at the end. + + ...do some stuff with it unlocked ... + } + + // myCriticalSection gets unlocked here. + } + @endcode + + @see CriticalSection, ScopedLock +*/ +class ScopedUnlock +{ +public: + + /** Creates a ScopedUnlock. + + As soon as it is created, this will unlock the CriticalSection, and + when the ScopedLock object is deleted, the CriticalSection will + be re-locked. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! Best just to use it + as a local stack object, rather than creating one with the new() operator. + */ + inline ScopedUnlock (const CriticalSection& lock) throw() : lock_ (lock) { lock.exit(); } + + /** Destructor. + + The CriticalSection will be unlocked when the destructor is called. + + Make sure this object is created and deleted by the same thread, + otherwise there are no guarantees what will happen! + */ + inline ~ScopedUnlock() throw() { lock_.enter(); } + +private: + + const CriticalSection& lock_; + + ScopedUnlock (const ScopedLock&); + const ScopedUnlock& operator= (const ScopedUnlock&); +}; + +#endif // __JUCE_SCOPEDLOCK_JUCEHEADER__ +/********* End of inlined file: juce_ScopedLock.h *********/ + /** A set of ChangeListeners. @@ -12775,7 +11893,7 @@ private: any number of sub-trees. Create ValueTree objects on the stack, and don't be afraid to copy them around, as - they are simply a lightweight reference to a shared data container. Creating a copy + they're simply a lightweight reference to a shared data container. Creating a copy of another ValueTree simply creates a new reference to the same underlying object - to make a separate, deep copy of a tree you should explicitly call createCopy(). @@ -12783,16 +11901,18 @@ private: and much of the structure of a ValueTree is similar to an XmlElement tree. You can convert a ValueTree to and from an XmlElement, and as long as the XML doesn't contain text elements, the conversion works well and makes a good serialisation - format. + format. They can also be serialised to a binary format, which is very fast and compact. All the methods that change data take an optional UndoManager, which will be used to track any changes to the object. For this to work, you have to be careful to consistently always use the same UndoManager for all operations to any node inside the tree. - Nodes can only be a child of one parent at a time, so if you're moving a node from + A ValueTree can only be a child of one parent at a time, so if you're moving one from one tree to another, be careful to always remove it first, before adding it. This - could also mess up your undo/redo chain, so be wary! + could also mess up your undo/redo chain, so be wary! In a debug build you should hit + assertions if you try to do anything dangerous, but there are still plenty of ways it + could go wrong. Listeners can be added to a ValueTree to be told when properies change and when nodes are added or removed. @@ -13076,6 +12196,1418 @@ private: #endif // __JUCE_VALUETREE_JUCEHEADER__ /********* End of inlined file: juce_ValueTree.h *********/ +#endif +#ifndef __JUCE_VARIANT_JUCEHEADER__ + +#endif +#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ + +/********* Start of inlined file: juce_VoidArray.h *********/ +#ifndef __JUCE_VOIDARRAY_JUCEHEADER__ +#define __JUCE_VOIDARRAY_JUCEHEADER__ + +/** + A typedef for an Array of void*'s. + + VoidArrays are used in various places throughout the library instead of + more strongly-typed arrays, to keep code-size low. +*/ +typedef Array VoidArray; + +#endif // __JUCE_VOIDARRAY_JUCEHEADER__ +/********* End of inlined file: juce_VoidArray.h *********/ + +#endif +#ifndef __JUCE_ATOMIC_JUCEHEADER__ + +#endif +#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILELOGGER_JUCEHEADER__ + +/********* Start of inlined file: juce_FileLogger.h *********/ +#ifndef __JUCE_FILELOGGER_JUCEHEADER__ +#define __JUCE_FILELOGGER_JUCEHEADER__ + +/** + A simple implemenation of a Logger that writes to a file. + + @see Logger +*/ +class JUCE_API FileLogger : public Logger +{ +public: + + /** Creates a FileLogger for a given file. + + @param fileToWriteTo the file that to use - new messages will be appended + to the file. If the file doesn't exist, it will be created, + along with any parent directories that are needed. + @param welcomeMessage when opened, the logger will write a header to the log, along + with the current date and time, and this welcome message + @param maxInitialFileSizeBytes if this is zero or greater, then if the file already exists + but is larger than this number of bytes, then the start of the + file will be truncated to keep the size down. This prevents a log + file getting ridiculously large over time. The file will be truncated + at a new-line boundary. If this value is less than zero, no size limit + will be imposed; if it's zero, the file will always be deleted. Note that + the size is only checked once when this object is created - any logging + that is done later will be appended without any checking + */ + FileLogger (const File& fileToWriteTo, + const String& welcomeMessage, + const int maxInitialFileSizeBytes = 128 * 1024); + + /** Destructor. */ + ~FileLogger(); + + void logMessage (const String& message); + + /** Helper function to create a log file in the correct place for this platform. + + On Windows this will return a logger with a path such as: + c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName] + + On the Mac it'll create something like: + ~/Library/Logs/[logFileName] + + The method might return 0 if the file can't be created for some reason. + + @param logFileSubDirectoryName if a subdirectory is needed, this is what it will be called - + it's best to use the something like the name of your application here. + @param logFileName the name of the file to create, e.g. "MyAppLog.txt". Don't just + call it "log.txt" because if it goes in a directory with logs + from other applications (as it will do on the Mac) then no-one + will know which one is yours! + @param welcomeMessage a message that will be written to the log when it's opened. + @param maxInitialFileSizeBytes (see the FileLogger constructor for more info on this) + */ + static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName, + const String& logFileName, + const String& welcomeMessage, + const int maxInitialFileSizeBytes = 128 * 1024); + + juce_UseDebuggingNewOperator + +private: + File logFile; + CriticalSection logLock; + FileOutputStream* logStream; + + void trimFileSize (int maxFileSizeBytes) const; + + FileLogger (const FileLogger&); + const FileLogger& operator= (const FileLogger&); +}; + +#endif // __JUCE_FILELOGGER_JUCEHEADER__ +/********* End of inlined file: juce_FileLogger.h *********/ + +#endif +#ifndef __JUCE_INITIALISATION_JUCEHEADER__ + +/********* Start of inlined file: juce_Initialisation.h *********/ +#ifndef __JUCE_INITIALISATION_JUCEHEADER__ +#define __JUCE_INITIALISATION_JUCEHEADER__ + +/** Initialises Juce's GUI classes. + + If you're embedding Juce into an application that uses its own event-loop rather + than using the START_JUCE_APPLICATION macro, call this function before making any + Juce calls, to make sure things are initialised correctly. + + Note that if you're creating a Juce DLL for Windows, you may also need to call the + PlatformUtilities::setCurrentModuleInstanceHandle() method. + + @see shutdownJuce_GUI(), initialiseJuce_NonGUI() +*/ +void JUCE_PUBLIC_FUNCTION initialiseJuce_GUI(); + +/** Clears up any static data being used by Juce's GUI classes. + + If you're embedding Juce into an application that uses its own event-loop rather + than using the START_JUCE_APPLICATION macro, call this function in your shutdown + code to clean up any juce objects that might be lying around. + + @see initialiseJuce_GUI(), initialiseJuce_NonGUI() +*/ +void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); + +/** Initialises the core parts of Juce. + + If you're embedding Juce into either a command-line program, call this function + at the start of your main() function to make sure that Juce is initialised correctly. + + Note that if you're creating a Juce DLL for Windows, you may also need to call the + PlatformUtilities::setCurrentModuleInstanceHandle() method. + + @see shutdownJuce_NonGUI, initialiseJuce_GUI +*/ +void JUCE_PUBLIC_FUNCTION initialiseJuce_NonGUI(); + +/** Clears up any static data being used by Juce's non-gui core classes. + + If you're embedding Juce into either a command-line program, call this function + at the end of your main() function if you want to make sure any Juce objects are + cleaned up correctly. + + @see initialiseJuce_NonGUI, initialiseJuce_GUI +*/ +void JUCE_PUBLIC_FUNCTION shutdownJuce_NonGUI(); + +#endif // __JUCE_INITIALISATION_JUCEHEADER__ +/********* End of inlined file: juce_Initialisation.h *********/ + +#endif +#ifndef __JUCE_LOGGER_JUCEHEADER__ + +#endif +#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__ + +#endif +#ifndef __JUCE_MEMORY_JUCEHEADER__ + +#endif +#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ + +/********* Start of inlined file: juce_PerformanceCounter.h *********/ +#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ +#define __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ + +/** A timer for measuring performance of code and dumping the results to a file. + + e.g. @code + + PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt"); + + for (;;) + { + pc.start(); + + doSomethingFishy(); + + pc.stop(); + } + @endcode + + In this example, the time of each period between calling start/stop will be + measured and averaged over 50 runs, and the results printed to a file + every 50 times round the loop. +*/ +class JUCE_API PerformanceCounter +{ +public: + + /** Creates a PerformanceCounter object. + + @param counterName the name used when printing out the statistics + @param runsPerPrintout the number of start/stop iterations before calling + printStatistics() + @param loggingFile a file to dump the results to - if this is File::nonexistent, + the results are just written to the debugger output + */ + PerformanceCounter (const String& counterName, + int runsPerPrintout = 100, + const File& loggingFile = File::nonexistent); + + /** Destructor. */ + ~PerformanceCounter(); + + /** Starts timing. + + @see stop + */ + void start(); + + /** Stops timing and prints out the results. + + The number of iterations before doing a printout of the + results is set in the constructor. + + @see start + */ + void stop(); + + /** Dumps the current metrics to the debugger output and to a file. + + As well as using Logger::outputDebugString to print the results, + this will write then to the file specified in the constructor (if + this was valid). + */ + void printStatistics(); + + juce_UseDebuggingNewOperator + +private: + + String name; + int numRuns, runsPerPrint; + double totalTime; + int64 started; + File outputFile; +}; + +#endif // __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ +/********* End of inlined file: juce_PerformanceCounter.h *********/ + +#endif +#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ + +#endif +#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ + +/********* Start of inlined file: juce_PlatformUtilities.h *********/ +#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ +#define __JUCE_PLATFORMUTILITIES_JUCEHEADER__ + +/** + A collection of miscellaneous platform-specific utilities. + +*/ +class JUCE_API PlatformUtilities +{ +public: + + /** Plays the operating system's default alert 'beep' sound. */ + static void beep(); + + static bool launchEmailWithAttachments (const String& targetEmailAddress, + const String& emailSubject, + const String& bodyText, + const StringArray& filesToAttach); + +#if JUCE_MAC || JUCE_IPHONE || DOXYGEN + + /** MAC ONLY - Turns a Core CF String into a juce one. */ + static const String cfStringToJuceString (CFStringRef cfString); + + /** MAC ONLY - Turns a juce string into a Core CF one. */ + static CFStringRef juceStringToCFString (const String& s); + + /** MAC ONLY - Turns a file path into an FSRef, returning true if it succeeds. */ + static bool makeFSRefFromPath (FSRef* destFSRef, const String& path); + + /** MAC ONLY - Turns an FSRef into a juce string path. */ + static const String makePathFromFSRef (FSRef* file); + + /** MAC ONLY - Converts any decomposed unicode characters in a string into + their precomposed equivalents. + */ + static const String convertToPrecomposedUnicode (const String& s); + + /** MAC ONLY - Gets the type of a file from the file's resources. */ + static OSType getTypeOfFile (const String& filename); + + /** MAC ONLY - Returns true if this file is actually a bundle. */ + static bool isBundle (const String& filename); + + /** MAC ONLY - Adds an item to the dock */ + static void addItemToDock (const File& file); + + /** MAC ONLY - Returns the current OS version number. + E.g. if it's running on 10.4, this will be 4, 10.5 will return 5, etc. + */ + static int getOSXMinorVersionNumber() throw(); +#endif + +#if JUCE_WINDOWS || DOXYGEN + + // Some registry helper functions: + + /** WIN32 ONLY - Returns a string from the registry. + + The path is a string for the entire path of a value in the registry, + e.g. "HKEY_CURRENT_USER\Software\foo\bar" + */ + static const String getRegistryValue (const String& regValuePath, + const String& defaultValue = String::empty); + + /** WIN32 ONLY - Sets a registry value as a string. + + This will take care of creating any groups needed to get to the given + registry value. + */ + static void setRegistryValue (const String& regValuePath, + const String& value); + + /** WIN32 ONLY - Returns true if the given value exists in the registry. */ + static bool registryValueExists (const String& regValuePath); + + /** WIN32 ONLY - Deletes a registry value. */ + static void deleteRegistryValue (const String& regValuePath); + + /** WIN32 ONLY - Deletes a registry key (which is registry-talk for 'folder'). */ + static void deleteRegistryKey (const String& regKeyPath); + + /** WIN32 ONLY - Creates a file association in the registry. + + This lets you set the exe that should be launched by a given file extension. + @param fileExtension the file extension to associate, including the + initial dot, e.g. ".txt" + @param symbolicDescription a space-free short token to identify the file type + @param fullDescription a human-readable description of the file type + @param targetExecutable the executable that should be launched + @param iconResourceNumber the icon that gets displayed for the file type will be + found by looking up this resource number in the + executable. Pass 0 here to not use an icon + */ + static void registerFileAssociation (const String& fileExtension, + const String& symbolicDescription, + const String& fullDescription, + const File& targetExecutable, + int iconResourceNumber); + + /** WIN32 ONLY - This returns the HINSTANCE of the current module. + + In a normal Juce application this will be set to the module handle + of the application executable. + + If you're writing a DLL using Juce and plan to use any Juce messaging or + windows, you'll need to make sure you use the setCurrentModuleInstanceHandle() + to set the correct module handle in your DllMain() function, because + the win32 system relies on the correct instance handle when opening windows. + */ + static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() throw(); + + /** WIN32 ONLY - Sets a new module handle to be used by the library. + + @see getCurrentModuleInstanceHandle() + */ + static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) throw(); + + /** WIN32 ONLY - Gets the command-line params as a string. + + This is needed to avoid unicode problems with the argc type params. + */ + static const String JUCE_CALLTYPE getCurrentCommandLineParams() throw(); +#endif + + /** Clears the floating point unit's flags. + + Only has an effect under win32, currently. + */ + static void fpuReset(); + +#if JUCE_LINUX || JUCE_WINDOWS + + /** Loads a dynamically-linked library into the process's address space. + + @param pathOrFilename the platform-dependent name and search path + @returns a handle which can be used by getProcedureEntryPoint(), or + zero if it fails. + @see freeDynamicLibrary, getProcedureEntryPoint + */ + static void* loadDynamicLibrary (const String& pathOrFilename); + + /** Frees a dynamically-linked library. + + @param libraryHandle a handle created by loadDynamicLibrary + @see loadDynamicLibrary, getProcedureEntryPoint + */ + static void freeDynamicLibrary (void* libraryHandle); + + /** Finds a procedure call in a dynamically-linked library. + + @param libraryHandle a library handle returned by loadDynamicLibrary + @param procedureName the name of the procedure call to try to load + @returns a pointer to the function if found, or 0 if it fails + @see loadDynamicLibrary + */ + static void* getProcedureEntryPoint (void* libraryHandle, + const String& procedureName); +#endif + +#if JUCE_LINUX || DOXYGEN + +#endif +}; + +#if JUCE_MAC || JUCE_IPHONE + +/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object + using RAII. +*/ +class ScopedAutoReleasePool +{ +public: + ScopedAutoReleasePool(); + ~ScopedAutoReleasePool(); + +private: + void* pool; + + ScopedAutoReleasePool (const ScopedAutoReleasePool&); + const ScopedAutoReleasePool& operator= (const ScopedAutoReleasePool&); +}; + +#endif + +#if JUCE_MAC + +/** + A wrapper class for picking up events from an Apple IR remote control device. + + To use it, just create a subclass of this class, implementing the buttonPressed() + callback, then call start() and stop() to start or stop receiving events. +*/ +class JUCE_API AppleRemoteDevice +{ +public: + + AppleRemoteDevice(); + virtual ~AppleRemoteDevice(); + + /** The set of buttons that may be pressed. + @see buttonPressed + */ + enum ButtonType + { + menuButton = 0, /**< The menu button (if it's held for a short time). */ + playButton, /**< The play button. */ + plusButton, /**< The plus or volume-up button. */ + minusButton, /**< The minus or volume-down button. */ + rightButton, /**< The right button (if it's held for a short time). */ + leftButton, /**< The left button (if it's held for a short time). */ + rightButton_Long, /**< The right button (if it's held for a long time). */ + leftButton_Long, /**< The menu button (if it's held for a long time). */ + menuButton_Long, /**< The menu button (if it's held for a long time). */ + playButtonSleepMode, + switched + }; + + /** Override this method to receive the callback about a button press. + + The callback will happen on the application's message thread. + + Some buttons trigger matching up and down events, in which the isDown parameter + will be true and then false. Others only send a single event when the + button is pressed. + */ + virtual void buttonPressed (const ButtonType buttonId, const bool isDown) = 0; + + /** Starts the device running and responding to events. + + Returns true if it managed to open the device. + + @param inExclusiveMode if true, the remote will be grabbed exclusively for this app, + and will not be available to any other part of the system. If + false, it will be shared with other apps. + @see stop + */ + bool start (const bool inExclusiveMode) throw(); + + /** Stops the device running. + @see start + */ + void stop() throw(); + + /** Returns true if the device has been started successfully. + */ + bool isActive() const throw(); + + /** Returns the ID number of the remote, if it has sent one. + */ + int getRemoteId() const throw() { return remoteId; } + + juce_UseDebuggingNewOperator + + /** @internal */ + void handleCallbackInternal(); + +private: + void* device; + void* queue; + int remoteId; + + bool open (const bool openInExclusiveMode) throw(); + + AppleRemoteDevice (const AppleRemoteDevice&); + const AppleRemoteDevice& operator= (const AppleRemoteDevice&); +}; + +#endif + +#endif // __JUCE_PLATFORMUTILITIES_JUCEHEADER__ +/********* End of inlined file: juce_PlatformUtilities.h *********/ + +#endif +#ifndef __JUCE_RANDOM_JUCEHEADER__ + +/********* Start of inlined file: juce_Random.h *********/ +#ifndef __JUCE_RANDOM_JUCEHEADER__ +#define __JUCE_RANDOM_JUCEHEADER__ + +/** + A simple pseudo-random number generator. +*/ +class JUCE_API Random +{ +public: + + /** Creates a Random object based on a seed value. + + For a given seed value, the subsequent numbers generated by this object + will be predictable, so a good idea is to set this value based + on the time, e.g. + + new Random (Time::currentTimeMillis()) + */ + Random (const int64 seedValue) throw(); + + /** Destructor. */ + ~Random() throw(); + + /** Returns the next random 32 bit integer. + + @returns a random integer from the full range 0x80000000 to 0x7fffffff + */ + int nextInt() throw(); + + /** Returns the next random number, limited to a given range. + + @returns a random integer between 0 (inclusive) and maxValue (exclusive). + */ + int nextInt (const int maxValue) throw(); + + /** Returns the next 64-bit random number. + + @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff + */ + int64 nextInt64() throw(); + + /** Returns the next random floating-point number. + + @returns a random value in the range 0 to 1.0 + */ + float nextFloat() throw(); + + /** Returns the next random floating-point number. + + @returns a random value in the range 0 to 1.0 + */ + double nextDouble() throw(); + + /** Returns the next random boolean value. + */ + bool nextBool() throw(); + + /** Returns a BitArray containing a random number. + + @returns a random value in the range 0 to (maximumValue - 1). + */ + const BitArray nextLargeNumber (const BitArray& maximumValue) throw(); + + /** Sets a range of bits in a BitArray to random values. */ + void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw(); + + /** To avoid the overhead of having to create a new Random object whenever + you need a number, this is a shared application-wide object that + can be used. + + It's not thread-safe though, so threads should use their own Random object. + */ + static Random& getSystemRandom() throw(); + + /** Resets this Random object to a given seed value. */ + void setSeed (const int64 newSeed) throw(); + + /** Reseeds this generator using a value generated from various semi-random system + properties like the current time, etc. + + Because this function convolves the time with the last seed value, calling + it repeatedly will increase the randomness of the final result. + */ + void setSeedRandomly(); + + juce_UseDebuggingNewOperator + +private: + int64 seed; +}; + +#endif // __JUCE_RANDOM_JUCEHEADER__ +/********* End of inlined file: juce_Random.h *********/ + +#endif +#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ + +#endif +#ifndef __JUCE_SINGLETON_JUCEHEADER__ + +/********* Start of inlined file: juce_Singleton.h *********/ +#ifndef __JUCE_SINGLETON_JUCEHEADER__ +#define __JUCE_SINGLETON_JUCEHEADER__ + +/** + Macro to declare member variables and methods for a singleton class. + + To use this, add the line juce_DeclareSingleton (MyClass, doNotRecreateAfterDeletion) + to the class's definition. + + Then put a macro juce_ImplementSingleton (MyClass) along with the class's + implementation code. + + It's also a very good idea to also add the call clearSingletonInstance() in your class's + destructor, in case it is deleted by other means than deleteInstance() + + Clients can then call the static method MyClass::getInstance() to get a pointer + to the singleton, or MyClass::getInstanceWithoutCreating() which will return 0 if + no instance currently exists. + + e.g. @code + + class MySingleton + { + public: + MySingleton() + { + } + + ~MySingleton() + { + // this ensures that no dangling pointers are left when the + // singleton is deleted. + clearSingletonInstance(); + } + + juce_DeclareSingleton (MySingleton, false) + }; + + juce_ImplementSingleton (MySingleton) + + // example of usage: + MySingleton* m = MySingleton::getInstance(); // creates the singleton if there isn't already one. + + ... + + MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created). + + @endcode + + If doNotRecreateAfterDeletion = true, it won't allow the object to be created more + than once during the process's lifetime - i.e. after you've created and deleted the + object, getInstance() will refuse to create another one. This can be useful to stop + objects being accidentally re-created during your app's shutdown code. + + If you know that your object will only be created and deleted by a single thread, you + can use the slightly more efficient juce_DeclareSingleton_SingleThreaded() macro instead + of this one. + + @see juce_ImplementSingleton, juce_DeclareSingleton_SingleThreaded +*/ +#define juce_DeclareSingleton(classname, doNotRecreateAfterDeletion) \ +\ + static classname* _singletonInstance; \ + static JUCE_NAMESPACE::CriticalSection _singletonLock; \ +\ + static classname* getInstance() \ + { \ + if (_singletonInstance == 0) \ + {\ + const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ +\ + if (_singletonInstance == 0) \ + { \ + static bool alreadyInside = false; \ + static bool createdOnceAlready = false; \ +\ + const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ + jassert (! problem); \ + if (! problem) \ + { \ + createdOnceAlready = true; \ + alreadyInside = true; \ + classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ + alreadyInside = false; \ +\ + _singletonInstance = newObject; \ + } \ + } \ + } \ +\ + return _singletonInstance; \ + } \ +\ + static inline classname* getInstanceWithoutCreating() throw() \ + { \ + return _singletonInstance; \ + } \ +\ + static void deleteInstance() \ + { \ + const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \ + if (_singletonInstance != 0) \ + { \ + classname* const old = _singletonInstance; \ + _singletonInstance = 0; \ + delete old; \ + } \ + } \ +\ + void clearSingletonInstance() throw() \ + { \ + if (_singletonInstance == this) \ + _singletonInstance = 0; \ + } + +/** This is a counterpart to the juce_DeclareSingleton macro. + + After adding the juce_DeclareSingleton to the class definition, this macro has + to be used in the cpp file. +*/ +#define juce_ImplementSingleton(classname) \ +\ + classname* classname::_singletonInstance = 0; \ + JUCE_NAMESPACE::CriticalSection classname::_singletonLock; + +/** + Macro to declare member variables and methods for a singleton class. + + This is exactly the same as juce_DeclareSingleton, but doesn't use a critical + section to make access to it thread-safe. If you know that your object will + only ever be created or deleted by a single thread, then this is a + more efficient version to use. + + If doNotRecreateAfterDeletion = true, it won't allow the object to be created more + than once during the process's lifetime - i.e. after you've created and deleted the + object, getInstance() will refuse to create another one. This can be useful to stop + objects being accidentally re-created during your app's shutdown code. + + See the documentation for juce_DeclareSingleton for more information about + how to use it, the only difference being that you have to use + juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. + + @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal +*/ +#define juce_DeclareSingleton_SingleThreaded(classname, doNotRecreateAfterDeletion) \ +\ + static classname* _singletonInstance; \ +\ + static classname* getInstance() \ + { \ + if (_singletonInstance == 0) \ + { \ + static bool alreadyInside = false; \ + static bool createdOnceAlready = false; \ +\ + const bool problem = alreadyInside || ((doNotRecreateAfterDeletion) && createdOnceAlready); \ + jassert (! problem); \ + if (! problem) \ + { \ + createdOnceAlready = true; \ + alreadyInside = true; \ + classname* newObject = new classname(); /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \ + alreadyInside = false; \ +\ + _singletonInstance = newObject; \ + } \ + } \ +\ + return _singletonInstance; \ + } \ +\ + static inline classname* getInstanceWithoutCreating() throw() \ + { \ + return _singletonInstance; \ + } \ +\ + static void deleteInstance() \ + { \ + if (_singletonInstance != 0) \ + { \ + classname* const old = _singletonInstance; \ + _singletonInstance = 0; \ + delete old; \ + } \ + } \ +\ + void clearSingletonInstance() throw() \ + { \ + if (_singletonInstance == this) \ + _singletonInstance = 0; \ + } + +/** + Macro to declare member variables and methods for a singleton class. + + This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking + for recursion or repeated instantiation. It's intended for use as a lightweight + version of a singleton, where you're using it in very straightforward + circumstances and don't need the extra checking. + + Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart + to this declaration, as you would with juce_DeclareSingleton_SingleThreaded. + + See the documentation for juce_DeclareSingleton for more information about + how to use it, the only difference being that you have to use + juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton. + + @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton +*/ +#define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \ +\ + static classname* _singletonInstance; \ +\ + static classname* getInstance() \ + { \ + if (_singletonInstance == 0) \ + _singletonInstance = new classname(); \ +\ + return _singletonInstance; \ + } \ +\ + static inline classname* getInstanceWithoutCreating() throw() \ + { \ + return _singletonInstance; \ + } \ +\ + static void deleteInstance() \ + { \ + if (_singletonInstance != 0) \ + { \ + classname* const old = _singletonInstance; \ + _singletonInstance = 0; \ + delete old; \ + } \ + } \ +\ + void clearSingletonInstance() throw() \ + { \ + if (_singletonInstance == this) \ + _singletonInstance = 0; \ + } + +/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro. + + After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal + to the class definition, this macro has to be used somewhere in the cpp file. +*/ +#define juce_ImplementSingleton_SingleThreaded(classname) \ +\ + classname* classname::_singletonInstance = 0; + +#endif // __JUCE_SINGLETON_JUCEHEADER__ +/********* End of inlined file: juce_Singleton.h *********/ + +#endif +#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ + +#endif +#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ + +/********* Start of inlined file: juce_SystemStats.h *********/ +#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ +#define __JUCE_SYSTEMSTATS_JUCEHEADER__ + +/** + Contains methods for finding out about the current hardware and OS configuration. +*/ +class JUCE_API SystemStats +{ +public: + + /** Returns the current version of JUCE, + + (just in case you didn't already know at compile-time.) + + See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros. + */ + static const String getJUCEVersion() throw(); + + /** The set of possible results of the getOperatingSystemType() method. + */ + enum OperatingSystemType + { + UnknownOS = 0, + + MacOSX = 0x1000, + Linux = 0x2000, + + Win95 = 0x4001, + Win98 = 0x4002, + WinNT351 = 0x4103, + WinNT40 = 0x4104, + Win2000 = 0x4105, + WinXP = 0x4106, + WinVista = 0x4107, + Windows7 = 0x4108, + + Windows = 0x4000, /**< To test whether any version of Windows is running, + you can use the expression ((getOperatingSystemType() & Windows) != 0). */ + WindowsNT = 0x0100, /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98), + you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */ + }; + + /** Returns the type of operating system we're running on. + + @returns one of the values from the OperatingSystemType enum. + @see getOperatingSystemName + */ + static OperatingSystemType getOperatingSystemType() throw(); + + /** Returns the name of the type of operating system we're running on. + + @returns a string describing the OS type. + @see getOperatingSystemType + */ + static const String getOperatingSystemName() throw(); + + /** Returns true if the OS is 64-bit, or false for a 32-bit OS. + */ + static bool isOperatingSystem64Bit() throw(); + + // CPU and memory information.. + + /** Returns the approximate CPU speed. + + @returns the speed in megahertz, e.g. 1500, 2500, 32000 (depending on + what year you're reading this...) + */ + static int getCpuSpeedInMegaherz() throw(); + + /** Returns a string to indicate the CPU vendor. + + Might not be known on some systems. + */ + static const String getCpuVendor() throw(); + + /** Checks whether Intel MMX instructions are available. */ + static bool hasMMX() throw(); + + /** Checks whether Intel SSE instructions are available. */ + static bool hasSSE() throw(); + + /** Checks whether Intel SSE2 instructions are available. */ + static bool hasSSE2() throw(); + + /** Checks whether AMD 3DNOW instructions are available. */ + static bool has3DNow() throw(); + + /** Returns the number of CPUs. + */ + static int getNumCpus() throw(); + + /** Returns a clock-cycle tick counter, if available. + + If the machine can do it, this will return a tick-count + where each tick is one cpu clock cycle - used for profiling + code. + + @returns the tick count, or zero if not available. + */ + static int64 getClockCycleCounter() throw(); + + /** Finds out how much RAM is in the machine. + + @returns the approximate number of megabytes of memory, or zero if + something goes wrong when finding out. + */ + static int getMemorySizeInMegabytes() throw(); + + /** Returns the system page-size. + + This is only used by programmers with beards. + */ + static int getPageSize() throw(); + + /** Returns a list of MAC addresses found on this machine. + + @param addresses an array into which the MAC addresses should be copied + @param maxNum the number of elements in this array + @param littleEndian the endianness of the numbers to return. If this is true, + the least-significant byte of each number is the first byte + of the mac address. If false, the least significant byte is + the last number. Note that the default values of this parameter + are different on Mac/PC to avoid breaking old software that was + written before this parameter was added (when the two systems + defaulted to using different endiannesses). In newer + software you probably want to specify an explicit value + for this. + @returns the number of MAC addresses that were found + */ + static int getMACAddresses (int64* addresses, int maxNum, +#if JUCE_MAC + const bool littleEndian = true) throw(); +#else + const bool littleEndian = false) throw(); +#endif + + // not-for-public-use platform-specific method gets called at startup to initialise things. + static void initialiseStats() throw(); +}; + +#endif // __JUCE_SYSTEMSTATS_JUCEHEADER__ +/********* End of inlined file: juce_SystemStats.h *********/ + +#endif +#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ + +#endif +#ifndef __JUCE_TIME_JUCEHEADER__ + +#endif +#ifndef __JUCE_UUID_JUCEHEADER__ + +/********* Start of inlined file: juce_Uuid.h *********/ +#ifndef __JUCE_UUID_JUCEHEADER__ +#define __JUCE_UUID_JUCEHEADER__ + +/** + A universally unique 128-bit identifier. + + This class generates very random unique numbers based on the system time + and MAC addresses if any are available. It's extremely unlikely that two identical + UUIDs would ever be created by chance. + + The class includes methods for saving the ID as a string or as raw binary data. +*/ +class JUCE_API Uuid +{ +public: + + /** Creates a new unique ID. */ + Uuid(); + + /** Destructor. */ + ~Uuid() throw(); + + /** Creates a copy of another UUID. */ + Uuid (const Uuid& other); + + /** Copies another UUID. */ + Uuid& operator= (const Uuid& other); + + /** Returns true if the ID is zero. */ + bool isNull() const throw(); + + /** Compares two UUIDs. */ + bool operator== (const Uuid& other) const; + + /** Compares two UUIDs. */ + bool operator!= (const Uuid& other) const; + + /** Returns a stringified version of this UUID. + + A Uuid object can later be reconstructed from this string using operator= or + the constructor that takes a string parameter. + + @returns a 32 character hex string. + */ + const String toString() const; + + /** Creates an ID from an encoded string version. + + @see toString + */ + Uuid (const String& uuidString); + + /** Copies from a stringified UUID. + + The string passed in should be one that was created with the toString() method. + */ + Uuid& operator= (const String& uuidString); + + /** Returns a pointer to the internal binary representation of the ID. + + This is an array of 16 bytes. To reconstruct a Uuid from its data, use + the constructor or operator= method that takes an array of uint8s. + */ + const uint8* getRawData() const throw() { return value.asBytes; } + + /** Creates a UUID from a 16-byte array. + + @see getRawData + */ + Uuid (const uint8* const rawData); + + /** Sets this UUID from 16-bytes of raw data. */ + Uuid& operator= (const uint8* const rawData); + + juce_UseDebuggingNewOperator + +private: + union + { + uint8 asBytes [16]; + int asInt[4]; + int64 asInt64[2]; + + } value; +}; + +#endif // __JUCE_UUID_JUCEHEADER__ +/********* End of inlined file: juce_Uuid.h *********/ + +#endif +#ifndef __JUCE_BLOWFISH_JUCEHEADER__ + +/********* Start of inlined file: juce_BlowFish.h *********/ +#ifndef __JUCE_BLOWFISH_JUCEHEADER__ +#define __JUCE_BLOWFISH_JUCEHEADER__ + +/** + BlowFish encryption class. + +*/ +class JUCE_API BlowFish +{ +public: + + /** Creates an object that can encode/decode based on the specified key. + + The key data can be up to 72 bytes long. + */ + BlowFish (const uint8* keyData, int keyBytes); + + /** Creates a copy of another blowfish object. */ + BlowFish (const BlowFish& other); + + /** Copies another blowfish object. */ + const BlowFish& operator= (const BlowFish& other); + + /** Destructor. */ + ~BlowFish(); + + /** Encrypts a pair of 32-bit integers. */ + void encrypt (uint32& data1, uint32& data2) const; + + /** Decrypts a pair of 32-bit integers. */ + void decrypt (uint32& data1, uint32& data2) const; + + juce_UseDebuggingNewOperator + +private: + uint32 p[18]; + HeapBlock s[4]; + + uint32 F (uint32 x) const; +}; + +#endif // __JUCE_BLOWFISH_JUCEHEADER__ +/********* End of inlined file: juce_BlowFish.h *********/ + +#endif +#ifndef __JUCE_MD5_JUCEHEADER__ + +/********* Start of inlined file: juce_MD5.h *********/ +#ifndef __JUCE_MD5_JUCEHEADER__ +#define __JUCE_MD5_JUCEHEADER__ + +/** + MD5 checksum class. + + Create one of these with a block of source data or a string, and it calculates the + MD5 checksum of that data. + + You can then retrieve this checksum as a 16-byte block, or as a hex string. +*/ +class JUCE_API MD5 +{ +public: + + /** Creates a null MD5 object. */ + MD5(); + + /** Creates a copy of another MD5. */ + MD5 (const MD5& other); + + /** Copies another MD5. */ + const MD5& operator= (const MD5& other); + + /** Creates a checksum for a block of binary data. */ + MD5 (const MemoryBlock& data); + + /** Creates a checksum for a block of binary data. */ + MD5 (const char* data, const int numBytes); + + /** Creates a checksum for a string. + + Note that this operates on the string as a block of unicode characters, so the + result you get will differ from the value you'd get if the string was treated + as a block of utf8 or ascii. Bear this in mind if you're comparing the result + of this method with a checksum created by a different framework, which may have + used a different encoding. + */ + MD5 (const String& text); + + /** Creates a checksum for the input from a stream. + + This will read up to the given number of bytes from the stream, and produce the + checksum of that. If the number of bytes to read is negative, it'll read + until the stream is exhausted. + */ + MD5 (InputStream& input, int numBytesToRead = -1); + + /** Creates a checksum for a file. */ + MD5 (const File& file); + + /** Destructor. */ + ~MD5(); + + /** Returns the checksum as a 16-byte block of data. */ + const MemoryBlock getRawChecksumData() const; + + /** Returns the checksum as a 32-digit hex string. */ + const String toHexString() const; + + /** Compares this to another MD5. */ + bool operator== (const MD5& other) const; + + /** Compares this to another MD5. */ + bool operator!= (const MD5& other) const; + + juce_UseDebuggingNewOperator + +private: + uint8 result [16]; + + struct ProcessContext + { + uint8 buffer [64]; + uint32 state [4]; + uint32 count [2]; + + ProcessContext(); + + void processBlock (const uint8* const data, int dataSize); + void transform (const uint8* const buffer); + void finish (uint8* const result); + }; + + void processStream (InputStream& input, int numBytesToRead); +}; + +#endif // __JUCE_MD5_JUCEHEADER__ +/********* End of inlined file: juce_MD5.h *********/ + +#endif +#ifndef __JUCE_PRIMES_JUCEHEADER__ + +/********* Start of inlined file: juce_Primes.h *********/ +#ifndef __JUCE_PRIMES_JUCEHEADER__ +#define __JUCE_PRIMES_JUCEHEADER__ + +/** + Prime number creation class. + + This class contains static methods for generating and testing prime numbers. + + @see BitArray +*/ +class JUCE_API Primes +{ +public: + + /** Creates a random prime number with a given bit-length. + + The certainty parameter specifies how many iterations to use when testing + for primality. A safe value might be anything over about 20-30. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. + */ + static const BitArray createProbablePrime (int bitLength, + int certainty, + const int* randomSeeds = 0, + int numRandomSeeds = 0) throw(); + + /** Tests a number to see if it's prime. + + This isn't a bulletproof test, it uses a Miller-Rabin test to determine + whether the number is prime. + + The certainty parameter specifies how many iterations to use when testing - a + safe value might be anything over about 20-30. + */ + static bool isProbablyPrime (const BitArray& number, + int certainty) throw(); +}; + +#endif // __JUCE_PRIMES_JUCEHEADER__ +/********* End of inlined file: juce_Primes.h *********/ + +#endif +#ifndef __JUCE_RSAKEY_JUCEHEADER__ + +/********* Start of inlined file: juce_RSAKey.h *********/ +#ifndef __JUCE_RSAKEY_JUCEHEADER__ +#define __JUCE_RSAKEY_JUCEHEADER__ + +/** + RSA public/private key-pair encryption class. + + An object of this type makes up one half of a public/private RSA key pair. Use the + createKeyPair() method to create a matching pair for encoding/decoding. +*/ +class JUCE_API RSAKey +{ +public: + + /** Creates a null key object. + + Initialise a pair of objects for use with the createKeyPair() method. + */ + RSAKey() throw(); + + /** Loads a key from an encoded string representation. + + This reloads a key from a string created by the toString() method. + */ + RSAKey (const String& stringRepresentation) throw(); + + /** Destructor. */ + ~RSAKey() throw(); + + /** Turns the key into a string representation. + + This can be reloaded using the constructor that takes a string. + */ + const String toString() const throw(); + + /** Encodes or decodes a value. + + Call this on the public key object to encode some data, then use the matching + private key object to decode it. + + Returns false if the operation couldn't be completed, e.g. if this key hasn't been + initialised correctly. + + NOTE: This method dumbly applies this key to this data. If you encode some data + and then try to decode it with a key that doesn't match, this method will still + happily do its job and return true, but the result won't be what you were expecting. + It's your responsibility to check that the result is what you wanted. + */ + bool applyToValue (BitArray& value) const throw(); + + /** Creates a public/private key-pair. + + Each key will perform one-way encryption that can only be reversed by + using the other key. + + The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger + sizes are more secure, but this method will take longer to execute. + + The randomSeeds parameter lets you optionally pass it a set of values with + which to seed the random number generation, improving the security of the + keys generated. + */ + static void createKeyPair (RSAKey& publicKey, + RSAKey& privateKey, + const int numBits, + const int* randomSeeds = 0, + const int numRandomSeeds = 0) throw(); + + juce_UseDebuggingNewOperator + +protected: + BitArray part1, part2; +}; + +#endif // __JUCE_RSAKEY_JUCEHEADER__ +/********* End of inlined file: juce_RSAKey.h *********/ + #endif #ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__ @@ -13273,7 +13805,7 @@ private: void* fileHandle; int64 currentPosition; int bufferSize, bytesInBuffer; - char* buffer; + HeapBlock buffer; }; #endif // __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__ @@ -13684,275 +14216,6 @@ private: #endif // __JUCE_ZIPFILE_JUCEHEADER__ /********* End of inlined file: juce_ZipFile.h *********/ -#endif -#ifndef __JUCE_BLOWFISH_JUCEHEADER__ - -/********* Start of inlined file: juce_BlowFish.h *********/ -#ifndef __JUCE_BLOWFISH_JUCEHEADER__ -#define __JUCE_BLOWFISH_JUCEHEADER__ - -/** - BlowFish encryption class. - -*/ -class JUCE_API BlowFish -{ -public: - - /** Creates an object that can encode/decode based on the specified key. - - The key data can be up to 72 bytes long. - */ - BlowFish (const uint8* keyData, int keyBytes); - - /** Creates a copy of another blowfish object. */ - BlowFish (const BlowFish& other); - - /** Copies another blowfish object. */ - const BlowFish& operator= (const BlowFish& other); - - /** Destructor. */ - ~BlowFish(); - - /** Encrypts a pair of 32-bit integers. */ - void encrypt (uint32& data1, uint32& data2) const; - - /** Decrypts a pair of 32-bit integers. */ - void decrypt (uint32& data1, uint32& data2) const; - - juce_UseDebuggingNewOperator - -private: - uint32 p[18]; - uint32* s[4]; - - uint32 F (uint32 x) const; -}; - -#endif // __JUCE_BLOWFISH_JUCEHEADER__ -/********* End of inlined file: juce_BlowFish.h *********/ - -#endif -#ifndef __JUCE_MD5_JUCEHEADER__ - -/********* Start of inlined file: juce_MD5.h *********/ -#ifndef __JUCE_MD5_JUCEHEADER__ -#define __JUCE_MD5_JUCEHEADER__ - -/** - MD5 checksum class. - - Create one of these with a block of source data or a string, and it calculates the - MD5 checksum of that data. - - You can then retrieve this checksum as a 16-byte block, or as a hex string. -*/ -class JUCE_API MD5 -{ -public: - - /** Creates a null MD5 object. */ - MD5(); - - /** Creates a copy of another MD5. */ - MD5 (const MD5& other); - - /** Copies another MD5. */ - const MD5& operator= (const MD5& other); - - /** Creates a checksum for a block of binary data. */ - MD5 (const MemoryBlock& data); - - /** Creates a checksum for a block of binary data. */ - MD5 (const char* data, const int numBytes); - - /** Creates a checksum for a string. - - Note that this operates on the string as a block of unicode characters, so the - result you get will differ from the value you'd get if the string was treated - as a block of utf8 or ascii. Bear this in mind if you're comparing the result - of this method with a checksum created by a different framework, which may have - used a different encoding. - */ - MD5 (const String& text); - - /** Creates a checksum for the input from a stream. - - This will read up to the given number of bytes from the stream, and produce the - checksum of that. If the number of bytes to read is negative, it'll read - until the stream is exhausted. - */ - MD5 (InputStream& input, int numBytesToRead = -1); - - /** Creates a checksum for a file. */ - MD5 (const File& file); - - /** Destructor. */ - ~MD5(); - - /** Returns the checksum as a 16-byte block of data. */ - const MemoryBlock getRawChecksumData() const; - - /** Returns the checksum as a 32-digit hex string. */ - const String toHexString() const; - - /** Compares this to another MD5. */ - bool operator== (const MD5& other) const; - - /** Compares this to another MD5. */ - bool operator!= (const MD5& other) const; - - juce_UseDebuggingNewOperator - -private: - uint8 result [16]; - - struct ProcessContext - { - uint8 buffer [64]; - uint32 state [4]; - uint32 count [2]; - - ProcessContext(); - - void processBlock (const uint8* const data, int dataSize); - void transform (const uint8* const buffer); - void finish (uint8* const result); - }; - - void processStream (InputStream& input, int numBytesToRead); -}; - -#endif // __JUCE_MD5_JUCEHEADER__ -/********* End of inlined file: juce_MD5.h *********/ - -#endif -#ifndef __JUCE_PRIMES_JUCEHEADER__ - -/********* Start of inlined file: juce_Primes.h *********/ -#ifndef __JUCE_PRIMES_JUCEHEADER__ -#define __JUCE_PRIMES_JUCEHEADER__ - -/** - Prime number creation class. - - This class contains static methods for generating and testing prime numbers. - - @see BitArray -*/ -class JUCE_API Primes -{ -public: - - /** Creates a random prime number with a given bit-length. - - The certainty parameter specifies how many iterations to use when testing - for primality. A safe value might be anything over about 20-30. - - The randomSeeds parameter lets you optionally pass it a set of values with - which to seed the random number generation, improving the security of the - keys generated. - */ - static const BitArray createProbablePrime (int bitLength, - int certainty, - const int* randomSeeds = 0, - int numRandomSeeds = 0) throw(); - - /** Tests a number to see if it's prime. - - This isn't a bulletproof test, it uses a Miller-Rabin test to determine - whether the number is prime. - - The certainty parameter specifies how many iterations to use when testing - a - safe value might be anything over about 20-30. - */ - static bool isProbablyPrime (const BitArray& number, - int certainty) throw(); -}; - -#endif // __JUCE_PRIMES_JUCEHEADER__ -/********* End of inlined file: juce_Primes.h *********/ - -#endif -#ifndef __JUCE_RSAKEY_JUCEHEADER__ - -/********* Start of inlined file: juce_RSAKey.h *********/ -#ifndef __JUCE_RSAKEY_JUCEHEADER__ -#define __JUCE_RSAKEY_JUCEHEADER__ - -/** - RSA public/private key-pair encryption class. - - An object of this type makes up one half of a public/private RSA key pair. Use the - createKeyPair() method to create a matching pair for encoding/decoding. -*/ -class JUCE_API RSAKey -{ -public: - - /** Creates a null key object. - - Initialise a pair of objects for use with the createKeyPair() method. - */ - RSAKey() throw(); - - /** Loads a key from an encoded string representation. - - This reloads a key from a string created by the toString() method. - */ - RSAKey (const String& stringRepresentation) throw(); - - /** Destructor. */ - ~RSAKey() throw(); - - /** Turns the key into a string representation. - - This can be reloaded using the constructor that takes a string. - */ - const String toString() const throw(); - - /** Encodes or decodes a value. - - Call this on the public key object to encode some data, then use the matching - private key object to decode it. - - Returns false if the operation couldn't be completed, e.g. if this key hasn't been - initialised correctly. - - NOTE: This method dumbly applies this key to this data. If you encode some data - and then try to decode it with a key that doesn't match, this method will still - happily do its job and return true, but the result won't be what you were expecting. - It's your responsibility to check that the result is what you wanted. - */ - bool applyToValue (BitArray& value) const throw(); - - /** Creates a public/private key-pair. - - Each key will perform one-way encryption that can only be reversed by - using the other key. - - The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger - sizes are more secure, but this method will take longer to execute. - - The randomSeeds parameter lets you optionally pass it a set of values with - which to seed the random number generation, improving the security of the - keys generated. - */ - static void createKeyPair (RSAKey& publicKey, - RSAKey& privateKey, - const int numBits, - const int* randomSeeds = 0, - const int numRandomSeeds = 0) throw(); - - juce_UseDebuggingNewOperator - -protected: - BitArray part1, part2; -}; - -#endif // __JUCE_RSAKEY_JUCEHEADER__ -/********* End of inlined file: juce_RSAKey.h *********/ - #endif #ifndef __JUCE_SOCKET_JUCEHEADER__ @@ -14529,7 +14792,7 @@ private: const bool deleteSourceWhenDestroyed; int bufferSize; int64 position, lastReadPos, bufferStart, bufferOverlap; - char* buffer; + HeapBlock buffer; void ensureBuffered(); BufferedInputStream (const BufferedInputStream&); @@ -14621,7 +14884,7 @@ public: private: OutputStream* const destStream; const bool deleteDestStream; - uint8* buffer; + HeapBlock buffer; void* helper; bool doNextBlock(); @@ -14686,7 +14949,7 @@ private: bool isEof; int activeBufferSize; int64 originalSourcePos, currentPos; - uint8* buffer; + HeapBlock buffer; void* helper; GZIPDecompressorInputStream (const GZIPDecompressorInputStream&); @@ -14887,6 +15150,9 @@ private: #endif // __JUCE_SUBREGIONSTREAM_JUCEHEADER__ /********* End of inlined file: juce_SubregionStream.h *********/ +#endif +#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ + #endif #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ @@ -15053,9 +15319,6 @@ private: #endif #ifndef __JUCE_STRING_JUCEHEADER__ -#endif -#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ - #endif #ifndef __JUCE_STRINGARRAY_JUCEHEADER__ @@ -16236,7 +16499,7 @@ public: private: const int numThreads, threadStopTimeout; int priority; - Thread** threads; + HeapBlock threads; VoidArray jobs; CriticalSection lock; @@ -18092,6 +18355,7 @@ private: #define __JUCE_EDGETABLE_JUCEHEADER__ class Path; +class RectangleList; class Image; /** @@ -18120,6 +18384,10 @@ public: */ EdgeTable (const Rectangle& rectangleToAdd) throw(); + /** Creates an edge table containing a rectangle list. + */ + EdgeTable (const RectangleList& rectanglesToAdd) throw(); + /** Creates an edge table containing a rectangle. */ EdgeTable (const float x, const float y, @@ -18246,7 +18514,7 @@ public: private: // table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc - int* table; + HeapBlock table; Rectangle bounds; int maxEdgesPerLine, lineStrideElements; bool needToCheckEmptinesss; @@ -18254,6 +18522,7 @@ private: void addEdgePoint (const int x, const int y, const int winding) throw(); void remapTableForNumEdges (const int newNumEdgesPerLine) throw(); void intersectWithEdgeTableLine (const int y, const int* otherLine) throw(); + void sanitiseLevels (const bool useNonZeroWinding) throw(); }; #endif // __JUCE_EDGETABLE_JUCEHEADER__ @@ -20775,10 +21044,10 @@ public: const Colour getColourAtPosition (const float position) const throw(); /** Creates a set of interpolated premultiplied ARGB values. - - The caller must delete the array that is returned using juce_free(). + This will resize the HeapBlock, fill it with the colours, and will return the number of + colours that it added. */ - PixelARGB* createLookupTable (const AffineTransform& transform, int& numEntries) const throw(); + int createLookupTable (const AffineTransform& transform, HeapBlock & resultLookupTable) const throw(); /** Returns true if all colours are opaque. */ bool isOpaque() const throw(); @@ -26276,11 +26545,3359 @@ private: /********* End of inlined file: juce_ApplicationProperties.h *********/ #endif -#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ +#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ -/********* Start of inlined file: juce_MidiBuffer.h *********/ -#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ -#define __JUCE_MIDIBUFFER_JUCEHEADER__ +/********* Start of inlined file: juce_AiffAudioFormat.h *********/ +#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioFormat.h *********/ +#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ +#define __JUCE_AUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioFormatReader.h *********/ +#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ +#define __JUCE_AUDIOFORMATREADER_JUCEHEADER__ + +class AudioFormat; + +/** + Reads samples from an audio file stream. + + A subclass that reads a specific type of audio format will be created by + an AudioFormat object. + + @see AudioFormat, AudioFormatWriter +*/ +class JUCE_API AudioFormatReader +{ +protected: + + /** Creates an AudioFormatReader object. + + @param sourceStream the stream to read from - this will be deleted + by this object when it is no longer needed. (Some + specialised readers might not use this parameter and + can leave it as 0). + @param formatName the description that will be returned by the getFormatName() + method + */ + AudioFormatReader (InputStream* const sourceStream, + const String& formatName); + +public: + /** Destructor. */ + virtual ~AudioFormatReader(); + + /** Returns a description of what type of format this is. + + E.g. "AIFF" + */ + const String getFormatName() const throw() { return formatName; } + + /** Reads samples from the stream. + + @param destSamples an array of buffers into which the sample data for each + channel will be written. + If the format is fixed-point, each channel will be written + as an array of 32-bit signed integers using the full + range -0x80000000 to 0x7fffffff, regardless of the source's + bit-depth. If it is a floating-point format, you should cast + the resulting array to a (float**) to get the values (in the + range -1.0 to 1.0 or beyond) + If the format is stereo, then destSamples[0] is the left channel + data, and destSamples[1] is the right channel. + The numDestChannels parameter indicates how many pointers this array + contains, but some of these pointers can be null if you don't want to + read data for some of the channels + @param numDestChannels the number of array elements in the destChannels array + @param startSampleInSource the position in the audio file or stream at which the samples + should be read, as a number of samples from the start of the + stream. It's ok for this to be beyond the start or end of the + available data - any samples that are out-of-range will be returned + as zeros. + @param numSamplesToRead the number of samples to read. If this is greater than the number + of samples that the file or stream contains. the result will be padded + with zeros + @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available + for some of the channels that you pass in, then they should be filled with + copies of valid source channels. + E.g. if you're reading a mono file and you pass 2 channels to this method, then + if fillLeftoverChannelsWithCopies is true, both destination channels will be filled + with the same data from the file's single channel. If fillLeftoverChannelsWithCopies + was false, then only the first channel would be filled with the file's contents, and + the second would be cleared. If there are many channels, e.g. you try to read 4 channels + from a stereo file, then the last 3 would all end up with copies of the same data. + @returns true if the operation succeeded, false if there was an error. Note + that reading sections of data beyond the extent of the stream isn't an + error - the reader should just return zeros for these regions + @see readMaxLevels + */ + bool read (int** destSamples, + int numDestChannels, + int64 startSampleInSource, + int numSamplesToRead, + const bool fillLeftoverChannelsWithCopies); + + /** Finds the highest and lowest sample levels from a section of the audio stream. + + This will read a block of samples from the stream, and measure the + highest and lowest sample levels from the channels in that section, returning + these as normalised floating-point levels. + + @param startSample the offset into the audio stream to start reading from. It's + ok for this to be beyond the start or end of the stream. + @param numSamples how many samples to read + @param lowestLeft on return, this is the lowest absolute sample from the left channel + @param highestLeft on return, this is the highest absolute sample from the left channel + @param lowestRight on return, this is the lowest absolute sample from the right + channel (if there is one) + @param highestRight on return, this is the highest absolute sample from the right + channel (if there is one) + @see read + */ + virtual void readMaxLevels (int64 startSample, + int64 numSamples, + float& lowestLeft, + float& highestLeft, + float& lowestRight, + float& highestRight); + + /** Scans the source looking for a sample whose magnitude is in a specified range. + + This will read from the source, either forwards or backwards between two sample + positions, until it finds a sample whose magnitude lies between two specified levels. + + If it finds a suitable sample, it returns its position; if not, it will return -1. + + There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing + points when you're searching for a continuous range of samples + + @param startSample the first sample to look at + @param numSamplesToSearch the number of samples to scan. If this value is negative, + the search will go backwards + @param magnitudeRangeMinimum the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0 + @param magnitudeRangeMaximum the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0 + @param minimumConsecutiveSamples if this is > 0, the method will only look for a sequence + of this many consecutive samples, all of which lie + within the target range. When it finds such a sequence, + it returns the position of the first in-range sample + it found (i.e. the earliest one if scanning forwards, the + latest one if scanning backwards) + */ + int64 searchForLevel (int64 startSample, + int64 numSamplesToSearch, + const double magnitudeRangeMinimum, + const double magnitudeRangeMaximum, + const int minimumConsecutiveSamples); + + /** The sample-rate of the stream. */ + double sampleRate; + + /** The number of bits per sample, e.g. 16, 24, 32. */ + unsigned int bitsPerSample; + + /** The total number of samples in the audio stream. */ + int64 lengthInSamples; + + /** The total number of channels in the audio stream. */ + unsigned int numChannels; + + /** Indicates whether the data is floating-point or fixed. */ + bool usesFloatingPointData; + + /** A set of metadata values that the reader has pulled out of the stream. + + Exactly what these values are depends on the format, so you can + check out the format implementation code to see what kind of stuff + they understand. + */ + StringPairArray metadataValues; + + /** The input stream, for use by subclasses. */ + InputStream* input; + + /** Subclasses must implement this method to perform the low-level read operation. + + Callers should use read() instead of calling this directly. + + @param destSamples the array of destination buffers to fill. Some of these + pointers may be null + @param numDestChannels the number of items in the destSamples array. This + value is guaranteed not to be greater than the number of + channels that this reader object contains + @param startOffsetInDestBuffer the number of samples from the start of the + dest data at which to begin writing + @param startSampleInFile the number of samples into the source data at which + to begin reading. This value is guaranteed to be >= 0. + @param numSamples the number of samples to read + */ + virtual bool readSamples (int** destSamples, + int numDestChannels, + int startOffsetInDestBuffer, + int64 startSampleInFile, + int numSamples) = 0; + + juce_UseDebuggingNewOperator + +private: + String formatName; + + AudioFormatReader (const AudioFormatReader&); + const AudioFormatReader& operator= (const AudioFormatReader&); +}; + +#endif // __JUCE_AUDIOFORMATREADER_JUCEHEADER__ +/********* End of inlined file: juce_AudioFormatReader.h *********/ + +/********* Start of inlined file: juce_AudioFormatWriter.h *********/ +#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ +#define __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioSource.h *********/ +#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__ +#define __JUCE_AUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioSampleBuffer.h *********/ +#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ +#define __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ + +class AudioFormatReader; +class AudioFormatWriter; + +/** + A multi-channel buffer of 32-bit floating point audio samples. + +*/ +class JUCE_API AudioSampleBuffer +{ +public: + + /** Creates a buffer with a specified number of channels and samples. + + The contents of the buffer will initially be undefined, so use clear() to + set all the samples to zero. + + The buffer will allocate its memory internally, and this will be released + when the buffer is deleted. + */ + AudioSampleBuffer (const int numChannels, + const int numSamples) throw(); + + /** Creates a buffer using a pre-allocated block of memory. + + Note that if the buffer is resized or its number of channels is changed, it + will re-allocate memory internally and copy the existing data to this new area, + so it will then stop directly addressing this memory. + + @param dataToReferTo a pre-allocated array containing pointers to the data + for each channel that should be used by this buffer. The + buffer will only refer to this memory, it won't try to delete + it when the buffer is deleted or resized. + @param numChannels the number of channels to use - this must correspond to the + number of elements in the array passed in + @param numSamples the number of samples to use - this must correspond to the + size of the arrays passed in + */ + AudioSampleBuffer (float** dataToReferTo, + const int numChannels, + const int numSamples) throw(); + + /** Copies another buffer. + + This buffer will make its own copy of the other's data, unless the buffer was created + using an external data buffer, in which case boths buffers will just point to the same + shared block of data. + */ + AudioSampleBuffer (const AudioSampleBuffer& other) throw(); + + /** Copies another buffer onto this one. + + This buffer's size will be changed to that of the other buffer. + */ + const AudioSampleBuffer& operator= (const AudioSampleBuffer& other) throw(); + + /** Destructor. + + This will free any memory allocated by the buffer. + */ + virtual ~AudioSampleBuffer() throw(); + + /** Returns the number of channels of audio data that this buffer contains. + + @see getSampleData + */ + int getNumChannels() const throw() { return numChannels; } + + /** Returns the number of samples allocated in each of the buffer's channels. + + @see getSampleData + */ + int getNumSamples() const throw() { return size; } + + /** Returns a pointer one of the buffer's channels. + + For speed, this doesn't check whether the channel number is out of range, + so be careful when using it! + */ + float* getSampleData (const int channelNumber) const throw() + { + jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); + return channels [channelNumber]; + } + + /** Returns a pointer to a sample in one of the buffer's channels. + + For speed, this doesn't check whether the channel and sample number + are out-of-range, so be careful when using it! + */ + float* getSampleData (const int channelNumber, + const int sampleOffset) const throw() + { + jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); + jassert (((unsigned int) sampleOffset) < (unsigned int) size); + return channels [channelNumber] + sampleOffset; + } + + /** Returns an array of pointers to the channels in the buffer. + + Don't modify any of the pointers that are returned, and bear in mind that + these will become invalid if the buffer is resized. + */ + float** getArrayOfChannels() const throw() { return channels; } + + /** Chages the buffer's size or number of channels. + + This can expand or contract the buffer's length, and add or remove channels. + + If keepExistingContent is true, it will try to preserve as much of the + old data as it can in the new buffer. + + If clearExtraSpace is true, then any extra channels or space that is + allocated will be also be cleared. If false, then this space is left + uninitialised. + + If avoidReallocating is true, then changing the buffer's size won't reduce the + amount of memory that is currently allocated (but it will still increase it if + the new size is bigger than the amount it currently has). If this is false, then + a new allocation will be done so that the buffer uses takes up the minimum amount + of memory that it needs. + */ + void setSize (const int newNumChannels, + const int newNumSamples, + const bool keepExistingContent = false, + const bool clearExtraSpace = false, + const bool avoidReallocating = false) throw(); + + /** Makes this buffer point to a pre-allocated set of channel data arrays. + + There's also a constructor that lets you specify arrays like this, but this + lets you change the channels dynamically. + + Note that if the buffer is resized or its number of channels is changed, it + will re-allocate memory internally and copy the existing data to this new area, + so it will then stop directly addressing this memory. + + @param dataToReferTo a pre-allocated array containing pointers to the data + for each channel that should be used by this buffer. The + buffer will only refer to this memory, it won't try to delete + it when the buffer is deleted or resized. + @param numChannels the number of channels to use - this must correspond to the + number of elements in the array passed in + @param numSamples the number of samples to use - this must correspond to the + size of the arrays passed in + */ + void setDataToReferTo (float** dataToReferTo, + const int numChannels, + const int numSamples) throw(); + + /** Clears all the samples in all channels. */ + void clear() throw(); + + /** Clears a specified region of all the channels. + + For speed, this doesn't check whether the channel and sample number + are in-range, so be careful! + */ + void clear (const int startSample, + const int numSamples) throw(); + + /** Clears a specified region of just one channel. + + For speed, this doesn't check whether the channel and sample number + are in-range, so be careful! + */ + void clear (const int channel, + const int startSample, + const int numSamples) throw(); + + /** Applies a gain multiple to a region of one channel. + + For speed, this doesn't check whether the channel and sample number + are in-range, so be careful! + */ + void applyGain (const int channel, + const int startSample, + int numSamples, + const float gain) throw(); + + /** Applies a gain multiple to a region of all the channels. + + For speed, this doesn't check whether the sample numbers + are in-range, so be careful! + */ + void applyGain (const int startSample, + const int numSamples, + const float gain) throw(); + + /** Applies a range of gains to a region of a channel. + + The gain that is applied to each sample will vary from + startGain on the first sample to endGain on the last Sample, + so it can be used to do basic fades. + + For speed, this doesn't check whether the sample numbers + are in-range, so be careful! + */ + void applyGainRamp (const int channel, + const int startSample, + int numSamples, + float startGain, + float endGain) throw(); + + /** Adds samples from another buffer to this one. + + @param destChannel the channel within this buffer to add the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source buffer to add from + @param sourceChannel the channel within the source buffer to read from + @param sourceStartSample the offset within the source buffer's channel to start reading samples from + @param numSamples the number of samples to process + @param gainToApplyToSource an optional gain to apply to the source samples before they are + added to this buffer's samples + + @see copyFrom + */ + void addFrom (const int destChannel, + const int destStartSample, + const AudioSampleBuffer& source, + const int sourceChannel, + const int sourceStartSample, + int numSamples, + const float gainToApplyToSource = 1.0f) throw(); + + /** Adds samples from an array of floats to one of the channels. + + @param destChannel the channel within this buffer to add the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source data to use + @param numSamples the number of samples to process + @param gainToApplyToSource an optional gain to apply to the source samples before they are + added to this buffer's samples + + @see copyFrom + */ + void addFrom (const int destChannel, + const int destStartSample, + const float* source, + int numSamples, + const float gainToApplyToSource = 1.0f) throw(); + + /** Adds samples from an array of floats, applying a gain ramp to them. + + @param destChannel the channel within this buffer to add the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source data to use + @param numSamples the number of samples to process + @param startGain the gain to apply to the first sample (this is multiplied with + the source samples before they are added to this buffer) + @param endGain the gain to apply to the final sample. The gain is linearly + interpolated between the first and last samples. + */ + void addFromWithRamp (const int destChannel, + const int destStartSample, + const float* source, + int numSamples, + float startGain, + float endGain) throw(); + + /** Copies samples from another buffer to this one. + + @param destChannel the channel within this buffer to copy the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source buffer to read from + @param sourceChannel the channel within the source buffer to read from + @param sourceStartSample the offset within the source buffer's channel to start reading samples from + @param numSamples the number of samples to process + + @see addFrom + */ + void copyFrom (const int destChannel, + const int destStartSample, + const AudioSampleBuffer& source, + const int sourceChannel, + const int sourceStartSample, + int numSamples) throw(); + + /** Copies samples from an array of floats into one of the channels. + + @param destChannel the channel within this buffer to copy the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source buffer to read from + @param numSamples the number of samples to process + + @see addFrom + */ + void copyFrom (const int destChannel, + const int destStartSample, + const float* source, + int numSamples) throw(); + + /** Copies samples from an array of floats into one of the channels, applying a gain to it. + + @param destChannel the channel within this buffer to copy the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source buffer to read from + @param numSamples the number of samples to process + @param gain the gain to apply + + @see addFrom + */ + void copyFrom (const int destChannel, + const int destStartSample, + const float* source, + int numSamples, + const float gain) throw(); + + /** Copies samples from an array of floats into one of the channels, applying a gain ramp. + + @param destChannel the channel within this buffer to copy the samples to + @param destStartSample the start sample within this buffer's channel + @param source the source buffer to read from + @param numSamples the number of samples to process + @param startGain the gain to apply to the first sample (this is multiplied with + the source samples before they are copied to this buffer) + @param endGain the gain to apply to the final sample. The gain is linearly + interpolated between the first and last samples. + + @see addFrom + */ + void copyFromWithRamp (const int destChannel, + const int destStartSample, + const float* source, + int numSamples, + float startGain, + float endGain) throw(); + + /** Finds the highest and lowest sample values in a given range. + + @param channel the channel to read from + @param startSample the start sample within the channel + @param numSamples the number of samples to check + @param minVal on return, the lowest value that was found + @param maxVal on return, the highest value that was found + */ + void findMinMax (const int channel, + const int startSample, + int numSamples, + float& minVal, + float& maxVal) const throw(); + + /** Finds the highest absolute sample value within a region of a channel. + */ + float getMagnitude (const int channel, + const int startSample, + const int numSamples) const throw(); + + /** Finds the highest absolute sample value within a region on all channels. + */ + float getMagnitude (const int startSample, + const int numSamples) const throw(); + + /** Returns the root mean squared level for a region of a channel. + */ + float getRMSLevel (const int channel, + const int startSample, + const int numSamples) const throw(); + + /** Fills a section of the buffer using an AudioReader as its source. + + This will convert the reader's fixed- or floating-point data to + the buffer's floating-point format, and will try to intelligently + cope with mismatches between the number of channels in the reader + and the buffer. + + @see writeToAudioWriter + */ + void readFromAudioReader (AudioFormatReader* reader, + const int startSample, + const int numSamples, + const int readerStartSample, + const bool useReaderLeftChan, + const bool useReaderRightChan) throw(); + + /** Writes a section of this buffer to an audio writer. + + This saves you having to mess about with channels or floating/fixed + point conversion. + + @see readFromAudioReader + */ + void writeToAudioWriter (AudioFormatWriter* writer, + const int startSample, + const int numSamples) const throw(); + + juce_UseDebuggingNewOperator + +private: + int numChannels, size, allocatedBytes; + float** channels; + HeapBlock allocatedData; + float* preallocatedChannelSpace [32]; + + void allocateData(); + void allocateChannels (float** const dataToReferTo); +}; + +#endif // __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ +/********* End of inlined file: juce_AudioSampleBuffer.h *********/ + +/** + Used by AudioSource::getNextAudioBlock(). +*/ +struct JUCE_API AudioSourceChannelInfo +{ + /** The destination buffer to fill with audio data. + + When the AudioSource::getNextAudioBlock() method is called, the active section + of this buffer should be filled with whatever output the source produces. + + Only the samples specified by the startSample and numSamples members of this structure + should be affected by the call. + + The contents of the buffer when it is passed to the the AudioSource::getNextAudioBlock() + method can be treated as the input if the source is performing some kind of filter operation, + but should be cleared if this is not the case - the clearActiveBufferRegion() is + a handy way of doing this. + + The number of channels in the buffer could be anything, so the AudioSource + must cope with this in whatever way is appropriate for its function. + */ + AudioSampleBuffer* buffer; + + /** The first sample in the buffer from which the callback is expected + to write data. */ + int startSample; + + /** The number of samples in the buffer which the callback is expected to + fill with data. */ + int numSamples; + + /** Convenient method to clear the buffer if the source is not producing any data. */ + void clearActiveBufferRegion() const + { + if (buffer != 0) + buffer->clear (startSample, numSamples); + } +}; + +/** + Base class for objects that can produce a continuous stream of audio. + + @see AudioFormatReaderSource, ResamplingAudioSource +*/ +class JUCE_API AudioSource +{ +protected: + + /** Creates an AudioSource. */ + AudioSource() throw() {} + +public: + /** Destructor. */ + virtual ~AudioSource() {} + + /** Tells the source to prepare for playing. + + The source can use this opportunity to initialise anything it needs to. + + Note that this method could be called more than once in succession without + a matching call to releaseResources(), so make sure your code is robust and + can handle that kind of situation. + + @param samplesPerBlockExpected the number of samples that the source + will be expected to supply each time its + getNextAudioBlock() method is called. This + number may vary slightly, because it will be dependent + on audio hardware callbacks, and these aren't + guaranteed to always use a constant block size, so + the source should be able to cope with small variations. + @param sampleRate the sample rate that the output will be used at - this + is needed by sources such as tone generators. + @see releaseResources, getNextAudioBlock + */ + virtual void prepareToPlay (int samplesPerBlockExpected, + double sampleRate) = 0; + + /** Allows the source to release anything it no longer needs after playback has stopped. + + This will be called when the source is no longer going to have its getNextAudioBlock() + method called, so it should release any spare memory, etc. that it might have + allocated during the prepareToPlay() call. + + Note that there's no guarantee that prepareToPlay() will actually have been called before + releaseResources(), and it may be called more than once in succession, so make sure your + code is robust and doesn't make any assumptions about when it will be called. + + @see prepareToPlay, getNextAudioBlock + */ + virtual void releaseResources() = 0; + + /** Called repeatedly to fetch subsequent blocks of audio data. + + After calling the prepareToPlay() method, this callback will be made each + time the audio playback hardware (or whatever other destination the audio + data is going to) needs another block of data. + + It will generally be called on a high-priority system thread, or possibly even + an interrupt, so be careful not to do too much work here, as that will cause + audio glitches! + + @see AudioSourceChannelInfo, prepareToPlay, releaseResources + */ + virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; +}; + +#endif // __JUCE_AUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_AudioSource.h *********/ + +/** + Writes samples to an audio file stream. + + A subclass that writes a specific type of audio format will be created by + an AudioFormat object. + + After creating one of these with the AudioFormat::createWriterFor() method + you can call its write() method to store the samples, and then delete it. + + @see AudioFormat, AudioFormatReader +*/ +class JUCE_API AudioFormatWriter +{ +protected: + + /** Creates an AudioFormatWriter object. + + @param destStream the stream to write to - this will be deleted + by this object when it is no longer needed + @param formatName the description that will be returned by the getFormatName() + method + @param sampleRate the sample rate to use - the base class just stores + this value, it doesn't do anything with it + @param numberOfChannels the number of channels to write - the base class just stores + this value, it doesn't do anything with it + @param bitsPerSample the bit depth of the stream - the base class just stores + this value, it doesn't do anything with it + */ + AudioFormatWriter (OutputStream* const destStream, + const String& formatName, + const double sampleRate, + const unsigned int numberOfChannels, + const unsigned int bitsPerSample); + +public: + /** Destructor. */ + virtual ~AudioFormatWriter(); + + /** Returns a description of what type of format this is. + + E.g. "AIFF file" + */ + const String getFormatName() const throw() { return formatName; } + + /** Writes a set of samples to the audio stream. + + Note that if you're trying to write the contents of an AudioSampleBuffer, you + can use AudioSampleBuffer::writeToAudioWriter(). + + @param samplesToWrite an array of arrays containing the sample data for + each channel to write. This is a zero-terminated + array of arrays, and can contain a different number + of channels than the actual stream uses, and the + writer should do its best to cope with this. + If the format is fixed-point, each channel will be formatted + as an array of signed integers using the full 32-bit + range -0x80000000 to 0x7fffffff, regardless of the source's + bit-depth. If it is a floating-point format, you should treat + the arrays as arrays of floats, and just cast it to an (int**) + to pass it into the method. + @param numSamples the number of samples to write + */ + virtual bool write (const int** samplesToWrite, + int numSamples) = 0; + + /** Reads a section of samples from an AudioFormatReader, and writes these to + the output. + + This will take care of any floating-point conversion that's required to convert + between the two formats. It won't deal with sample-rate conversion, though. + + If numSamplesToRead < 0, it will write the entire length of the reader. + + @returns false if it can't read or write properly during the operation + */ + bool writeFromAudioReader (AudioFormatReader& reader, + int64 startSample, + int64 numSamplesToRead); + + /** Reads some samples from an AudioSource, and writes these to the output. + + The source must already have been initialised with the AudioSource::prepareToPlay() method + + @param source the source to read from + @param numSamplesToRead total number of samples to read and write + @param samplesPerBlock the maximum number of samples to fetch from the source + @returns false if it can't read or write properly during the operation + */ + bool writeFromAudioSource (AudioSource& source, + int numSamplesToRead, + const int samplesPerBlock = 2048); + + /** Returns the sample rate being used. */ + double getSampleRate() const throw() { return sampleRate; } + + /** Returns the number of channels being written. */ + int getNumChannels() const throw() { return numChannels; } + + /** Returns the bit-depth of the data being written. */ + int getBitsPerSample() const throw() { return bitsPerSample; } + + /** Returns true if it's a floating-point format, false if it's fixed-point. */ + bool isFloatingPoint() const throw() { return usesFloatingPointData; } + + juce_UseDebuggingNewOperator + +protected: + /** The sample rate of the stream. */ + double sampleRate; + + /** The number of channels being written to the stream. */ + unsigned int numChannels; + + /** The bit depth of the file. */ + unsigned int bitsPerSample; + + /** True if it's a floating-point format, false if it's fixed-point. */ + bool usesFloatingPointData; + + /** The output stream for Use by subclasses. */ + OutputStream* output; + +private: + String formatName; +}; + +#endif // __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ +/********* End of inlined file: juce_AudioFormatWriter.h *********/ + +/** + Subclasses of AudioFormat are used to read and write different audio + file formats. + + @see AudioFormatReader, AudioFormatWriter, WavAudioFormat, AiffAudioFormat +*/ +class JUCE_API AudioFormat +{ +public: + + /** Destructor. */ + virtual ~AudioFormat(); + + /** Returns the name of this format. + + e.g. "WAV file" or "AIFF file" + */ + const String& getFormatName() const; + + /** Returns all the file extensions that might apply to a file of this format. + + The first item will be the one that's preferred when creating a new file. + + So for a wav file this might just return ".wav"; for an AIFF file it might + return two items, ".aif" and ".aiff" + */ + const StringArray& getFileExtensions() const; + + /** Returns true if this the given file can be read by this format. + + Subclasses shouldn't do too much work here, just check the extension or + file type. The base class implementation just checks the file's extension + against one of the ones that was registered in the constructor. + */ + virtual bool canHandleFile (const File& fileToTest); + + /** Returns a set of sample rates that the format can read and write. */ + virtual const Array getPossibleSampleRates() = 0; + + /** Returns a set of bit depths that the format can read and write. */ + virtual const Array getPossibleBitDepths() = 0; + + /** Returns true if the format can do 2-channel audio. */ + virtual bool canDoStereo() = 0; + + /** Returns true if the format can do 1-channel audio. */ + virtual bool canDoMono() = 0; + + /** Returns true if the format uses compressed data. */ + virtual bool isCompressed(); + + /** Returns a list of different qualities that can be used when writing. + + Non-compressed formats will just return an empty array, but for something + like Ogg-Vorbis or MP3, it might return a list of bit-rates, etc. + + When calling createWriterFor(), an index from this array is passed in to + tell the format which option is required. + */ + virtual const StringArray getQualityOptions(); + + /** Tries to create an object that can read from a stream containing audio + data in this format. + + The reader object that is returned can be used to read from the stream, and + should then be deleted by the caller. + + @param sourceStream the stream to read from - the AudioFormatReader object + that is returned will delete this stream when it no longer + needs it. + @param deleteStreamIfOpeningFails if no reader can be created, this determines whether this method + should delete the stream object that was passed-in. (If a valid + reader is returned, it will always be in charge of deleting the + stream, so this parameter is ignored) + @see AudioFormatReader + */ + virtual AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails) = 0; + + /** Tries to create an object that can write to a stream with this audio format. + + The writer object that is returned can be used to write to the stream, and + should then be deleted by the caller. + + If the stream can't be created for some reason (e.g. the parameters passed in + here aren't suitable), this will return 0. + + @param streamToWriteTo the stream that the data will go to - this will be + deleted by the AudioFormatWriter object when it's no longer + needed. If no AudioFormatWriter can be created by this method, + the stream will NOT be deleted, so that the caller can re-use it + to try to open a different format, etc + @param sampleRateToUse the sample rate for the file, which must be one of the ones + returned by getPossibleSampleRates() + @param numberOfChannels the number of channels - this must be either 1 or 2, and + the choice will depend on the results of canDoMono() and + canDoStereo() + @param bitsPerSample the bits per sample to use - this must be one of the values + returned by getPossibleBitDepths() + @param metadataValues a set of metadata values that the writer should try to write + to the stream. Exactly what these are depends on the format, + and the subclass doesn't actually have to do anything with + them if it doesn't want to. Have a look at the specific format + implementation classes to see possible values that can be + used + @param qualityOptionIndex the index of one of compression qualities returned by the + getQualityOptions() method. If there aren't any quality options + for this format, just pass 0 in this parameter, as it'll be + ignored + @see AudioFormatWriter + */ + virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex) = 0; + +protected: + /** Creates an AudioFormat object. + + @param formatName this sets the value that will be returned by getFormatName() + @param fileExtensions a zero-terminated list of file extensions - this is what will + be returned by getFileExtension() + */ + AudioFormat (const String& formatName, + const tchar** const fileExtensions); + +private: + + String formatName; + StringArray fileExtensions; +}; + +#endif // __JUCE_AUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_AudioFormat.h *********/ + +/** + Reads and Writes AIFF format audio files. + + @see AudioFormat +*/ +class JUCE_API AiffAudioFormat : public AudioFormat +{ +public: + + /** Creates an format object. */ + AiffAudioFormat(); + + /** Destructor. */ + ~AiffAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); +#if JUCE_MAC + bool canHandleFile (const File& fileToTest); +#endif + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif // __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_AiffAudioFormat.h *********/ + +#endif +#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioCDBurner.h *********/ +#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ +#define __JUCE_AUDIOCDBURNER_JUCEHEADER__ + +#if JUCE_USE_CDBURNER + +/** +*/ +class AudioCDBurner +{ +public: + + /** Returns a list of available optical drives. + + Use openDevice() to open one of the items from this list. + */ + static const StringArray findAvailableDevices(); + + /** Tries to open one of the optical drives. + + The deviceIndex is an index into the array returned by findAvailableDevices(). + */ + static AudioCDBurner* openDevice (const int deviceIndex); + + /** Destructor. */ + ~AudioCDBurner(); + + /** Returns true if there's a writable disk in the drive. + */ + bool isDiskPresent() const; + + /** Returns the number of free blocks on the disk. + + There are 75 blocks per second, at 44100Hz. + */ + int getNumAvailableAudioBlocks() const; + + /** Adds a track to be written. + + The source passed-in here will be kept by this object, and it will + be used and deleted at some point in the future, either during the + burn() method or when this AudioCDBurner object is deleted. Your caller + method shouldn't keep a reference to it or use it again after passing + it in here. + */ + bool addAudioTrack (AudioSource* source, int numSamples); + + /** + + Return true to cancel the current burn operation + */ + class BurnProgressListener + { + public: + BurnProgressListener() throw() {} + virtual ~BurnProgressListener() {} + + /** Called at intervals to report on the progress of the AudioCDBurner. + + To cancel the burn, return true from this. + */ + virtual bool audioCDBurnProgress (float proportionComplete) = 0; + }; + + const String burn (BurnProgressListener* listener, + const bool ejectDiscAfterwards, + const bool peformFakeBurnForTesting); + + juce_UseDebuggingNewOperator + +private: + AudioCDBurner (const int deviceIndex); + + void* internal; +}; + +#endif +#endif // __JUCE_AUDIOCDBURNER_JUCEHEADER__ +/********* End of inlined file: juce_AudioCDBurner.h *********/ + +#endif +#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioCDReader.h *********/ +#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ +#define __JUCE_AUDIOCDREADER_JUCEHEADER__ + +#if JUCE_USE_CDREADER + +#if JUCE_MAC + +#endif + +/** + A type of AudioFormatReader that reads from an audio CD. + + One of these can be used to read a CD as if it's one big audio stream. Use the + getPositionOfTrackStart() method to find where the individual tracks are + within the stream. + + @see AudioFormatReader +*/ +class JUCE_API AudioCDReader : public AudioFormatReader +{ +public: + + /** Returns a list of names of Audio CDs currently available for reading. + + If there's a CD drive but no CD in it, this might return an empty list, or + possibly a device that can be opened but which has no tracks, depending + on the platform. + + @see createReaderForCD + */ + static const StringArray getAvailableCDNames(); + + /** Tries to create an AudioFormatReader that can read from an Audio CD. + + @param index the index of one of the available CDs - use getAvailableCDNames() + to find out how many there are. + @returns a new AudioCDReader object, or 0 if it couldn't be created. The + caller will be responsible for deleting the object returned. + */ + static AudioCDReader* createReaderForCD (const int index); + + /** Destructor. */ + ~AudioCDReader(); + + /** Implementation of the AudioFormatReader method. */ + bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, + int64 startSampleInFile, int numSamples); + + /** Checks whether the CD has been removed from the drive. + */ + bool isCDStillPresent() const; + + /** Returns the total number of tracks (audio + data). + */ + int getNumTracks() const; + + /** Finds the sample offset of the start of a track. + + @param trackNum the track number, where 0 is the first track. + */ + int getPositionOfTrackStart (int trackNum) const; + + /** Returns true if a given track is an audio track. + + @param trackNum the track number, where 0 is the first track. + */ + bool isTrackAudio (int trackNum) const; + + /** Refreshes the object's table of contents. + + If the disc has been ejected and a different one put in since this + object was created, this will cause it to update its idea of how many tracks + there are, etc. + */ + void refreshTrackLengths(); + + /** Enables scanning for indexes within tracks. + + @see getLastIndex + */ + void enableIndexScanning (bool enabled); + + /** Returns the index number found during the last read() call. + + Index scanning is turned off by default - turn it on with enableIndexScanning(). + + Then when the read() method is called, if it comes across an index within that + block, the index number is stored and returned by this method. + + Some devices might not support indexes, of course. + + (If you don't know what CD indexes are, it's unlikely you'll ever need them). + + @see enableIndexScanning + */ + int getLastIndex() const; + + /** Scans a track to find the position of any indexes within it. + + @param trackNumber the track to look in, where 0 is the first track on the disc + @returns an array of sample positions of any index points found (not including + the index that marks the start of the track) + */ + const Array findIndexesInTrack (const int trackNumber); + + /** Returns the CDDB id number for the CD. + + It's not a great way of identifying a disc, but it's traditional. + */ + int getCDDBId(); + + /** Tries to eject the disk. + + Of course this might not be possible, if some other process is using it. + */ + void ejectDisk(); + + juce_UseDebuggingNewOperator + +private: + +#if JUCE_MAC + File volumeDir; + OwnedArray tracks; + Array trackStartSamples; + int currentReaderTrack; + AudioFormatReader* reader; + AudioCDReader (const File& volume); +public: + static int compareElements (const File* const, const File* const) throw(); +private: + +#elif JUCE_WINDOWS + int numTracks; + int trackStarts[100]; + bool audioTracks [100]; + void* handle; + bool indexingEnabled; + int lastIndex, firstFrameInBuffer, samplesInBuffer; + MemoryBlock buffer; + AudioCDReader (void* handle); + int getIndexAt (int samplePos); + +#elif JUCE_LINUX + AudioCDReader(); +#endif + + AudioCDReader (const AudioCDReader&); + const AudioCDReader& operator= (const AudioCDReader&); +}; + +#endif +#endif // __JUCE_AUDIOCDREADER_JUCEHEADER__ +/********* End of inlined file: juce_AudioCDReader.h *********/ + +#endif +#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ + +#endif +#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioFormatManager.h *********/ +#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ +#define __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ + +/** + A class for keeping a list of available audio formats, and for deciding which + one to use to open a given file. + + You can either use this class as a singleton object, or create instances of it + yourself. Once created, use its registerFormat() method to tell it which + formats it should use. + + @see AudioFormat +*/ +class JUCE_API AudioFormatManager +{ +public: + + /** Creates an empty format manager. + + Before it'll be any use, you'll need to call registerFormat() with all the + formats you want it to be able to recognise. + */ + AudioFormatManager(); + + /** Destructor. */ + ~AudioFormatManager(); + + juce_DeclareSingleton (AudioFormatManager, false); + + /** Adds a format to the manager's list of available file types. + + The object passed-in will be deleted by this object, so don't keep a pointer + to it! + + If makeThisTheDefaultFormat is true, then the getDefaultFormat() method will + return this one when called. + */ + void registerFormat (AudioFormat* newFormat, + const bool makeThisTheDefaultFormat); + + /** Handy method to make it easy to register the formats that come with Juce. + + Currently, this will add WAV and AIFF to the list. + */ + void registerBasicFormats(); + + /** Clears the list of known formats. */ + void clearFormats(); + + /** Returns the number of currently registered file formats. */ + int getNumKnownFormats() const; + + /** Returns one of the registered file formats. */ + AudioFormat* getKnownFormat (const int index) const; + + /** Looks for which of the known formats is listed as being for a given file + extension. + + The extension may have a dot before it, so e.g. ".wav" or "wav" are both ok. + */ + AudioFormat* findFormatForFileExtension (const String& fileExtension) const; + + /** Returns the format which has been set as the default one. + + You can set a format as being the default when it is registered. It's useful + when you want to write to a file, because the best format may change between + platforms, e.g. AIFF is preferred on the Mac, WAV on Windows. + + If none has been set as the default, this method will just return the first + one in the list. + */ + AudioFormat* getDefaultFormat() const; + + /** Returns a set of wildcards for file-matching that contains the extensions for + all known formats. + + E.g. if might return "*.wav;*.aiff" if it just knows about wavs and aiffs. + */ + const String getWildcardForAllFormats() const; + + /** Searches through the known formats to try to create a suitable reader for + this file. + + If none of the registered formats can open the file, it'll return 0. If it + returns a reader, it's the caller's responsibility to delete the reader. + */ + AudioFormatReader* createReaderFor (const File& audioFile); + + /** Searches through the known formats to try to create a suitable reader for + this stream. + + The stream object that is passed-in will be deleted by this method or by the + reader that is returned, so the caller should not keep any references to it. + + The stream that is passed-in must be capable of being repositioned so + that all the formats can have a go at opening it. + + If none of the registered formats can open the stream, it'll return 0. If it + returns a reader, it's the caller's responsibility to delete the reader. + */ + AudioFormatReader* createReaderFor (InputStream* audioFileStream); + + juce_UseDebuggingNewOperator + +private: + VoidArray knownFormats; + int defaultFormatIndex; +}; + +#endif // __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ +/********* End of inlined file: juce_AudioFormatManager.h *********/ + +#endif +#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ + +#endif +#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ + +#endif +#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioSubsectionReader.h *********/ +#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ +#define __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ + +/** + This class is used to wrap an AudioFormatReader and only read from a + subsection of the file. + + So if you have a reader which can read a 1000 sample file, you could wrap it + in one of these to only access, e.g. samples 100 to 200, and any samples + outside that will come back as 0. Accessing sample 0 from this reader will + actually read the first sample from the other's subsection, which might + be at a non-zero position. + + @see AudioFormatReader +*/ +class JUCE_API AudioSubsectionReader : public AudioFormatReader +{ +public: + + /** Creates a AudioSubsectionReader for a given data source. + + @param sourceReader the source reader from which we'll be taking data + @param subsectionStartSample the sample within the source reader which will be + mapped onto sample 0 for this reader. + @param subsectionLength the number of samples from the source that will + make up the subsection. If this reader is asked for + any samples beyond this region, it will return zero. + @param deleteSourceWhenDeleted if true, the sourceReader object will be deleted when + this object is deleted. + */ + AudioSubsectionReader (AudioFormatReader* const sourceReader, + const int64 subsectionStartSample, + const int64 subsectionLength, + const bool deleteSourceWhenDeleted); + + /** Destructor. */ + ~AudioSubsectionReader(); + + bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, + int64 startSampleInFile, int numSamples); + + void readMaxLevels (int64 startSample, + int64 numSamples, + float& lowestLeft, + float& highestLeft, + float& lowestRight, + float& highestRight); + + juce_UseDebuggingNewOperator + +private: + AudioFormatReader* const source; + int64 startSample, length; + const bool deleteSourceWhenDeleted; + + AudioSubsectionReader (const AudioSubsectionReader&); + const AudioSubsectionReader& operator= (const AudioSubsectionReader&); +}; + +#endif // __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ +/********* End of inlined file: juce_AudioSubsectionReader.h *********/ + +#endif +#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioThumbnail.h *********/ +#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ +#define __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ + +class AudioThumbnailCache; + +/** + Makes it easy to quickly draw scaled views of the waveform shape of an + audio file. + + To use this class, just create an AudioThumbNail class for the file you want + to draw, call setSource to tell it which file or resource to use, then call + drawChannel() to draw it. + + The class will asynchronously scan the wavefile to create its scaled-down view, + so you should make your UI repaint itself as this data comes in. To do this, the + AudioThumbnail is a ChangeBroadcaster, and will broadcast a message when its + listeners should repaint themselves. + + The thumbnail stores an internal low-res version of the wave data, and this can + be loaded and saved to avoid having to scan the file again. + + @see AudioThumbnailCache +*/ +class JUCE_API AudioThumbnail : public ChangeBroadcaster, + public TimeSliceClient, + private Timer +{ +public: + + /** Creates an audio thumbnail. + + @param sourceSamplesPerThumbnailSample when creating a stored, low-res version + of the audio data, this is the scale at which it should be done. (This + number is the number of original samples that will be averaged for each + low-res sample) + @param formatManagerToUse the audio format manager that is used to open the file + @param cacheToUse an instance of an AudioThumbnailCache - this provides a background + thread and storage that is used to by the thumbnail, and the cache + object can be shared between multiple thumbnails + */ + AudioThumbnail (const int sourceSamplesPerThumbnailSample, + AudioFormatManager& formatManagerToUse, + AudioThumbnailCache& cacheToUse); + + /** Destructor. */ + ~AudioThumbnail(); + + /** Specifies the file or stream that contains the audio file. + + For a file, just call + @code + setSource (new FileInputSource (file)) + @endcode + + You can pass a zero in here to clear the thumbnail. + + The source that is passed in will be deleted by this object when it is no + longer needed + */ + void setSource (InputSource* const newSource); + + /** Reloads the low res thumbnail data from an input stream. + + The thumb will automatically attempt to reload itself from its + AudioThumbnailCache. + */ + void loadFrom (InputStream& input); + + /** Saves the low res thumbnail data to an output stream. + + The thumb will automatically attempt to save itself to its + AudioThumbnailCache after it finishes scanning the wave file. + */ + void saveTo (OutputStream& output) const; + + /** Returns the number of channels in the file. + */ + int getNumChannels() const throw(); + + /** Returns the length of the audio file, in seconds. + */ + double getTotalLength() const throw(); + + /** Renders the waveform shape for a channel. + + The waveform will be drawn within the specified rectangle, where startTime + and endTime specify the times within the audio file that should be positioned + at the left and right edges of the rectangle. + + The waveform will be scaled vertically so that a full-volume sample will fill + the rectangle vertically, but you can also specify an extra vertical scale factor + with the verticalZoomFactor parameter. + */ + void drawChannel (Graphics& g, + int x, int y, int w, int h, + double startTimeSeconds, + double endTimeSeconds, + int channelNum, + const float verticalZoomFactor); + + /** Returns true if the low res preview is fully generated. + */ + bool isFullyLoaded() const throw(); + + /** @internal */ + bool useTimeSlice(); + /** @internal */ + void timerCallback(); + + juce_UseDebuggingNewOperator + +private: + AudioFormatManager& formatManagerToUse; + AudioThumbnailCache& cache; + InputSource* source; + + CriticalSection readerLock; + AudioFormatReader* reader; + + MemoryBlock data, cachedLevels; + int orginalSamplesPerThumbnailSample; + + int numChannelsCached, numSamplesCached; + double cachedStart, cachedTimePerPixel; + bool cacheNeedsRefilling; + + void clear(); + + AudioFormatReader* createReader() const; + + void generateSection (AudioFormatReader& reader, + int64 startSample, + int numSamples); + + char* getChannelData (int channel) const; + + void refillCache (const int numSamples, + double startTime, + const double timePerPixel); + + friend class AudioThumbnailCache; + + // true if it needs more callbacks from the readNextBlockFromAudioFile() method + bool initialiseFromAudioFile (AudioFormatReader& reader); + + // returns true if more needs to be read + bool readNextBlockFromAudioFile (AudioFormatReader& reader); +}; + +#endif // __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ +/********* End of inlined file: juce_AudioThumbnail.h *********/ + +#endif +#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioThumbnailCache.h *********/ +#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ +#define __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ + +struct ThumbnailCacheEntry; + +/** + An instance of this class is used to manage multiple AudioThumbnail objects. + + The cache runs a single background thread that is shared by all the thumbnails + that need it, and it maintains a set of low-res previews in memory, to avoid + having to re-scan audio files too often. + + @see AudioThumbnail +*/ +class JUCE_API AudioThumbnailCache : public TimeSliceThread +{ +public: + + /** Creates a cache object. + + The maxNumThumbsToStore parameter lets you specify how many previews should + be kept in memory at once. + */ + AudioThumbnailCache (const int maxNumThumbsToStore); + + /** Destructor. */ + ~AudioThumbnailCache(); + + /** Clears out any stored thumbnails. + */ + void clear(); + + /** Reloads the specified thumb if this cache contains the appropriate stored + data. + + This is called automatically by the AudioThumbnail class, so you shouldn't + normally need to call it directly. + */ + bool loadThumb (AudioThumbnail& thumb, const int64 hashCode); + + /** Stores the cachable data from the specified thumb in this cache. + + This is called automatically by the AudioThumbnail class, so you shouldn't + normally need to call it directly. + */ + void storeThumb (const AudioThumbnail& thumb, const int64 hashCode); + + juce_UseDebuggingNewOperator + +private: + + OwnedArray thumbs; + int maxNumThumbsToStore; + + friend class AudioThumbnail; + void addThumbnail (AudioThumbnail* const thumb); + void removeThumbnail (AudioThumbnail* const thumb); +}; + +#endif // __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ +/********* End of inlined file: juce_AudioThumbnailCache.h *********/ + +#endif +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_FlacAudioFormat.h *********/ +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_USE_FLAC || defined (DOXYGEN) + +/** + Reads and writes the lossless-compression FLAC audio format. + + To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h, + and make sure your include search path and library search path are set up to find + the FLAC header files and static libraries. + + @see AudioFormat +*/ +class JUCE_API FlacAudioFormat : public AudioFormat +{ +public: + + FlacAudioFormat(); + ~FlacAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + bool isCompressed(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_FlacAudioFormat.h *********/ + +#endif +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/ +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_USE_OGGVORBIS || defined (DOXYGEN) + +/** + Reads and writes the Ogg-Vorbis audio format. + + To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h, + and make sure your include search path and library search path are set up to find + the Vorbis and Ogg header files and static libraries. + + @see AudioFormat, +*/ +class JUCE_API OggVorbisAudioFormat : public AudioFormat +{ +public: + + OggVorbisAudioFormat(); + ~OggVorbisAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + bool isCompressed(); + const StringArray getQualityOptions(); + + /** Tries to estimate the quality level of an ogg file based on its size. + + If it can't read the file for some reason, this will just return 1 (medium quality), + otherwise it will return the approximate quality setting that would have been used + to create the file. + + @see getQualityOptions + */ + int estimateOggFileQuality (const File& source); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/ + +#endif +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/ +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + +#if JUCE_QUICKTIME + +/** + Uses QuickTime to read the audio track a movie or media file. + + As well as QuickTime movies, this should also manage to open other audio + files that quicktime can understand, like mp3, m4a, etc. + + @see AudioFormat +*/ +class JUCE_API QuickTimeAudioFormat : public AudioFormat +{ +public: + + /** Creates a format object. */ + QuickTimeAudioFormat(); + + /** Destructor. */ + ~QuickTimeAudioFormat(); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + juce_UseDebuggingNewOperator +}; + +#endif +#endif // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/ + +#endif +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_WavAudioFormat.h *********/ +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ +#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + +/** + Reads and Writes WAV format audio files. + + @see AudioFormat +*/ +class JUCE_API WavAudioFormat : public AudioFormat +{ +public: + + /** Creates a format object. */ + WavAudioFormat(); + + /** Destructor. */ + ~WavAudioFormat(); + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavDescription; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginator; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginatorRef; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + Date format is: yyyy-mm-dd + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginationDate; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + Time format is: hh-mm-ss + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavOriginationTime; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + This is the number of samples from the start of an edit that the + file is supposed to begin at. Seems like an obvious mistake to + only allow a file to occur in an edit once, but that's the way + it is.. + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavTimeReference; + + /** Metadata property name used by wav readers and writers for adding + a BWAV chunk to the file. + + This is a + + @see AudioFormatReader::metadataValues, createWriterFor + */ + static const tchar* const bwavCodingHistory; + + /** Utility function to fill out the appropriate metadata for a BWAV file. + + This just makes it easier than using the property names directly, and it + fills out the time and date in the right format. + */ + static const StringPairArray createBWAVMetadata (const String& description, + const String& originator, + const String& originatorRef, + const Time& dateAndTime, + const int64 timeReferenceSamples, + const String& codingHistory); + + const Array getPossibleSampleRates(); + const Array getPossibleBitDepths(); + bool canDoStereo(); + bool canDoMono(); + + AudioFormatReader* createReaderFor (InputStream* sourceStream, + const bool deleteStreamIfOpeningFails); + + AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, + double sampleRateToUse, + unsigned int numberOfChannels, + int bitsPerSample, + const StringPairArray& metadataValues, + int qualityOptionIndex); + + /** Utility function to replace the metadata in a wav file with a new set of values. + + If possible, this cheats by overwriting just the metadata region of the file, rather + than by copying the whole file again. + */ + bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); + + juce_UseDebuggingNewOperator +}; + +#endif // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_WavAudioFormat.h *********/ + +#endif +#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioFormatReaderSource.h *********/ +#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ +#define __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_PositionableAudioSource.h *********/ +#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ + +/** + A type of AudioSource which can be repositioned. + + The basic AudioSource just streams continuously with no idea of a current + time or length, so the PositionableAudioSource is used for a finite stream + that has a current read position. + + @see AudioSource, AudioTransportSource +*/ +class JUCE_API PositionableAudioSource : public AudioSource +{ +protected: + + /** Creates the PositionableAudioSource. */ + PositionableAudioSource() throw() {} + +public: + /** Destructor */ + ~PositionableAudioSource() {} + + /** Tells the stream to move to a new position. + + Calling this indicates that the next call to AudioSource::getNextAudioBlock() + should return samples from this position. + + Note that this may be called on a different thread to getNextAudioBlock(), + so the subclass should make sure it's synchronised. + */ + virtual void setNextReadPosition (int newPosition) = 0; + + /** Returns the position from which the next block will be returned. + + @see setNextReadPosition + */ + virtual int getNextReadPosition() const = 0; + + /** Returns the total length of the stream (in samples). */ + virtual int getTotalLength() const = 0; + + /** Returns true if this source is actually playing in a loop. */ + virtual bool isLooping() const = 0; +}; + +#endif // __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_PositionableAudioSource.h *********/ + +/** + A type of AudioSource that will read from an AudioFormatReader. + + @see PositionableAudioSource, AudioTransportSource, BufferingAudioSource +*/ +class JUCE_API AudioFormatReaderSource : public PositionableAudioSource +{ +public: + + /** Creates an AudioFormatReaderSource for a given reader. + + @param sourceReader the reader to use as the data source + @param deleteReaderWhenThisIsDeleted if true, the reader passed-in will be deleted + when this object is deleted; if false it will be + left up to the caller to manage its lifetime + */ + AudioFormatReaderSource (AudioFormatReader* const sourceReader, + const bool deleteReaderWhenThisIsDeleted); + + /** Destructor. */ + ~AudioFormatReaderSource(); + + /** Toggles loop-mode. + + If set to true, it will continuously loop the input source. If false, + it will just emit silence after the source has finished. + + @see isLooping + */ + void setLooping (const bool shouldLoop) throw(); + + /** Returns whether loop-mode is turned on or not. */ + bool isLooping() const { return looping; } + + /** Returns the reader that's being used. */ + AudioFormatReader* getAudioFormatReader() const throw() { return reader; } + + /** Implementation of the AudioSource method. */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + + /** Implementation of the AudioSource method. */ + void releaseResources(); + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + /** Implements the PositionableAudioSource method. */ + void setNextReadPosition (int newPosition); + + /** Implements the PositionableAudioSource method. */ + int getNextReadPosition() const; + + /** Implements the PositionableAudioSource method. */ + int getTotalLength() const; + + juce_UseDebuggingNewOperator + +private: + AudioFormatReader* reader; + bool deleteReader; + + int volatile nextPlayPos; + bool volatile looping; + + void readBufferSection (int start, int length, AudioSampleBuffer& buffer, int startSample); + + AudioFormatReaderSource (const AudioFormatReaderSource&); + const AudioFormatReaderSource& operator= (const AudioFormatReaderSource&); +}; + +#endif // __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_AudioFormatReaderSource.h *********/ + +#endif +#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__ + +#endif +#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioSourcePlayer.h *********/ +#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ +#define __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioIODevice.h *********/ +#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__ +#define __JUCE_AUDIOIODEVICE_JUCEHEADER__ + +class AudioIODevice; + +/** + One of these is passed to an AudioIODevice object to stream the audio data + in and out. + + The AudioIODevice will repeatedly call this class's audioDeviceIOCallback() + method on its own high-priority audio thread, when it needs to send or receive + the next block of data. + + @see AudioIODevice, AudioDeviceManager +*/ +class JUCE_API AudioIODeviceCallback +{ +public: + /** Destructor. */ + virtual ~AudioIODeviceCallback() {} + + /** Processes a block of incoming and outgoing audio data. + + The subclass's implementation should use the incoming audio for whatever + purposes it needs to, and must fill all the output channels with the next + block of output data before returning. + + The channel data is arranged with the same array indices as the channel name + array returned by AudioIODevice::getOutputChannelNames(), but those channels + that aren't specified in AudioIODevice::open() will have a null pointer for their + associated channel, so remember to check for this. + + @param inputChannelData a set of arrays containing the audio data for each + incoming channel - this data is valid until the function + returns. There will be one channel of data for each input + channel that was enabled when the audio device was opened + (see AudioIODevice::open()) + @param numInputChannels the number of pointers to channel data in the + inputChannelData array. + @param outputChannelData a set of arrays which need to be filled with the data + that should be sent to each outgoing channel of the device. + There will be one channel of data for each output channel + that was enabled when the audio device was opened (see + AudioIODevice::open()) + The initial contents of the array is undefined, so the + callback function must fill all the channels with zeros if + its output is silence. Failing to do this could cause quite + an unpleasant noise! + @param numOutputChannels the number of pointers to channel data in the + outputChannelData array. + @param numSamples the number of samples in each channel of the input and + output arrays. The number of samples will depend on the + audio device's buffer size and will usually remain constant, + although this isn't guaranteed, so make sure your code can + cope with reasonable changes in the buffer size from one + callback to the next. + */ + virtual void audioDeviceIOCallback (const float** inputChannelData, + int numInputChannels, + float** outputChannelData, + int numOutputChannels, + int numSamples) = 0; + + /** Called to indicate that the device is about to start calling back. + + This will be called just before the audio callbacks begin, either when this + callback has just been added to an audio device, or after the device has been + restarted because of a sample-rate or block-size change. + + You can use this opportunity to find out the sample rate and block size + that the device is going to use by calling the AudioIODevice::getCurrentSampleRate() + and AudioIODevice::getCurrentBufferSizeSamples() on the supplied pointer. + + @param device the audio IO device that will be used to drive the callback. + Note that if you're going to store this this pointer, it is + only valid until the next time that audioDeviceStopped is called. + */ + virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; + + /** Called to indicate that the device has stopped. + */ + virtual void audioDeviceStopped() = 0; +}; + +/** + Base class for an audio device with synchronised input and output channels. + + Subclasses of this are used to implement different protocols such as DirectSound, + ASIO, CoreAudio, etc. + + To create one of these, you'll need to use the AudioIODeviceType class - see the + documentation for that class for more info. + + For an easier way of managing audio devices and their settings, have a look at the + AudioDeviceManager class. + + @see AudioIODeviceType, AudioDeviceManager +*/ +class JUCE_API AudioIODevice +{ +public: + /** Destructor. */ + virtual ~AudioIODevice(); + + /** Returns the device's name, (as set in the constructor). */ + const String& getName() const throw() { return name; } + + /** Returns the type of the device. + + E.g. "CoreAudio", "ASIO", etc. - this comes from the AudioIODeviceType that created it. + */ + const String& getTypeName() const throw() { return typeName; } + + /** Returns the names of all the available output channels on this device. + To find out which of these are currently in use, call getActiveOutputChannels(). + */ + virtual const StringArray getOutputChannelNames() = 0; + + /** Returns the names of all the available input channels on this device. + To find out which of these are currently in use, call getActiveInputChannels(). + */ + virtual const StringArray getInputChannelNames() = 0; + + /** Returns the number of sample-rates this device supports. + + To find out which rates are available on this device, use this method to + find out how many there are, and getSampleRate() to get the rates. + + @see getSampleRate + */ + virtual int getNumSampleRates() = 0; + + /** Returns one of the sample-rates this device supports. + + To find out which rates are available on this device, use getNumSampleRates() to + find out how many there are, and getSampleRate() to get the individual rates. + + The sample rate is set by the open() method. + + (Note that for DirectSound some rates might not work, depending on combinations + of i/o channels that are being opened). + + @see getNumSampleRates + */ + virtual double getSampleRate (int index) = 0; + + /** Returns the number of sizes of buffer that are available. + + @see getBufferSizeSamples, getDefaultBufferSize + */ + virtual int getNumBufferSizesAvailable() = 0; + + /** Returns one of the possible buffer-sizes. + + @param index the index of the buffer-size to use, from 0 to getNumBufferSizesAvailable() - 1 + @returns a number of samples + @see getNumBufferSizesAvailable, getDefaultBufferSize + */ + virtual int getBufferSizeSamples (int index) = 0; + + /** Returns the default buffer-size to use. + + @returns a number of samples + @see getNumBufferSizesAvailable, getBufferSizeSamples + */ + virtual int getDefaultBufferSize() = 0; + + /** Tries to open the device ready to play. + + @param inputChannels a BitArray in which a set bit indicates that the corresponding + input channel should be enabled + @param outputChannels a BitArray in which a set bit indicates that the corresponding + output channel should be enabled + @param sampleRate the sample rate to try to use - to find out which rates are + available, see getNumSampleRates() and getSampleRate() + @param bufferSizeSamples the size of i/o buffer to use - to find out the available buffer + sizes, see getNumBufferSizesAvailable() and getBufferSizeSamples() + @returns an error description if there's a problem, or an empty string if it succeeds in + opening the device + @see close + */ + virtual const String open (const BitArray& inputChannels, + const BitArray& outputChannels, + double sampleRate, + int bufferSizeSamples) = 0; + + /** Closes and releases the device if it's open. */ + virtual void close() = 0; + + /** Returns true if the device is still open. + + A device might spontaneously close itself if something goes wrong, so this checks if + it's still open. + */ + virtual bool isOpen() = 0; + + /** Starts the device actually playing. + + This must be called after the device has been opened. + + @param callback the callback to use for streaming the data. + @see AudioIODeviceCallback, open + */ + virtual void start (AudioIODeviceCallback* callback) = 0; + + /** Stops the device playing. + + Once a device has been started, this will stop it. Any pending calls to the + callback class will be flushed before this method returns. + */ + virtual void stop() = 0; + + /** Returns true if the device is still calling back. + + The device might mysteriously stop, so this checks whether it's + still playing. + */ + virtual bool isPlaying() = 0; + + /** Returns the last error that happened if anything went wrong. */ + virtual const String getLastError() = 0; + + /** Returns the buffer size that the device is currently using. + + If the device isn't actually open, this value doesn't really mean much. + */ + virtual int getCurrentBufferSizeSamples() = 0; + + /** Returns the sample rate that the device is currently using. + + If the device isn't actually open, this value doesn't really mean much. + */ + virtual double getCurrentSampleRate() = 0; + + /** Returns the device's current physical bit-depth. + + If the device isn't actually open, this value doesn't really mean much. + */ + virtual int getCurrentBitDepth() = 0; + + /** Returns a mask showing which of the available output channels are currently + enabled. + @see getOutputChannelNames + */ + virtual const BitArray getActiveOutputChannels() const = 0; + + /** Returns a mask showing which of the available input channels are currently + enabled. + @see getInputChannelNames + */ + virtual const BitArray getActiveInputChannels() const = 0; + + /** Returns the device's output latency. + + This is the delay in samples between a callback getting a block of data, and + that data actually getting played. + */ + virtual int getOutputLatencyInSamples() = 0; + + /** Returns the device's input latency. + + This is the delay in samples between some audio actually arriving at the soundcard, + and the callback getting passed this block of data. + */ + virtual int getInputLatencyInSamples() = 0; + + /** True if this device can show a pop-up control panel for editing its settings. + + This is generally just true of ASIO devices. If true, you can call showControlPanel() + to display it. + */ + virtual bool hasControlPanel() const; + + /** Shows a device-specific control panel if there is one. + + This should only be called for devices which return true from hasControlPanel(). + */ + virtual bool showControlPanel(); + +protected: + /** Creates a device, setting its name and type member variables. */ + AudioIODevice (const String& deviceName, + const String& typeName); + + /** @internal */ + String name, typeName; +}; + +#endif // __JUCE_AUDIOIODEVICE_JUCEHEADER__ +/********* End of inlined file: juce_AudioIODevice.h *********/ + +/** + Wrapper class to continuously stream audio from an audio source to an + AudioIODevice. + + This object acts as an AudioIODeviceCallback, so can be attached to an + output device, and will stream audio from an AudioSource. +*/ +class JUCE_API AudioSourcePlayer : public AudioIODeviceCallback +{ +public: + + /** Creates an empty AudioSourcePlayer. */ + AudioSourcePlayer(); + + /** Destructor. + + Make sure this object isn't still being used by an AudioIODevice before + deleting it! + */ + virtual ~AudioSourcePlayer(); + + /** Changes the current audio source to play from. + + If the source passed in is already being used, this method will do nothing. + If the source is not null, its prepareToPlay() method will be called + before it starts being used for playback. + + If there's another source currently playing, its releaseResources() method + will be called after it has been swapped for the new one. + + @param newSource the new source to use - this will NOT be deleted + by this object when no longer needed, so it's the + caller's responsibility to manage it. + */ + void setSource (AudioSource* newSource); + + /** Returns the source that's playing. + + May return 0 if there's no source. + */ + AudioSource* getCurrentSource() const throw() { return source; } + + /** Sets a gain to apply to the audio data. */ + void setGain (const float newGain) throw(); + + /** Implementation of the AudioIODeviceCallback method. */ + void audioDeviceIOCallback (const float** inputChannelData, + int totalNumInputChannels, + float** outputChannelData, + int totalNumOutputChannels, + int numSamples); + + /** Implementation of the AudioIODeviceCallback method. */ + void audioDeviceAboutToStart (AudioIODevice* device); + + /** Implementation of the AudioIODeviceCallback method. */ + void audioDeviceStopped(); + + juce_UseDebuggingNewOperator + +private: + + CriticalSection readLock; + AudioSource* source; + double sampleRate; + int bufferSize; + float* channels [128]; + float* outputChans [128]; + const float* inputChans [128]; + AudioSampleBuffer tempBuffer; + float lastGain, gain; + + AudioSourcePlayer (const AudioSourcePlayer&); + const AudioSourcePlayer& operator= (const AudioSourcePlayer&); +}; + +#endif // __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ +/********* End of inlined file: juce_AudioSourcePlayer.h *********/ + +#endif +#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioTransportSource.h *********/ +#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ +#define __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_BufferingAudioSource.h *********/ +#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ + +/** + An AudioSource which takes another source as input, and buffers it using a thread. + + Create this as a wrapper around another thread, and it will read-ahead with + a background thread to smooth out playback. You can either create one of these + directly, or use it indirectly using an AudioTransportSource. + + @see PositionableAudioSource, AudioTransportSource +*/ +class JUCE_API BufferingAudioSource : public PositionableAudioSource +{ +public: + + /** Creates a BufferingAudioSource. + + @param source the input source to read from + @param deleteSourceWhenDeleted if true, then the input source object will + be deleted when this object is deleted + @param numberOfSamplesToBuffer the size of buffer to use for reading ahead + */ + BufferingAudioSource (PositionableAudioSource* source, + const bool deleteSourceWhenDeleted, + int numberOfSamplesToBuffer); + + /** Destructor. + + The input source may be deleted depending on whether the deleteSourceWhenDeleted + flag was set in the constructor. + */ + ~BufferingAudioSource(); + + /** Implementation of the AudioSource method. */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + + /** Implementation of the AudioSource method. */ + void releaseResources(); + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + /** Implements the PositionableAudioSource method. */ + void setNextReadPosition (int newPosition); + + /** Implements the PositionableAudioSource method. */ + int getNextReadPosition() const; + + /** Implements the PositionableAudioSource method. */ + int getTotalLength() const { return source->getTotalLength(); } + + /** Implements the PositionableAudioSource method. */ + bool isLooping() const { return source->isLooping(); } + + juce_UseDebuggingNewOperator + +private: + + PositionableAudioSource* source; + bool deleteSourceWhenDeleted; + int numberOfSamplesToBuffer; + AudioSampleBuffer buffer; + CriticalSection bufferStartPosLock; + int volatile bufferValidStart, bufferValidEnd, nextPlayPos; + bool wasSourceLooping; + double volatile sampleRate; + + friend class SharedBufferingAudioSourceThread; + bool readNextBufferChunk(); + void readBufferSection (int start, int length, int bufferOffset); + + BufferingAudioSource (const BufferingAudioSource&); + const BufferingAudioSource& operator= (const BufferingAudioSource&); +}; + +#endif // __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_BufferingAudioSource.h *********/ + +/********* Start of inlined file: juce_ResamplingAudioSource.h *********/ +#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ + +/** + A type of AudioSource that takes an input source and changes its sample rate. + + @see AudioSource +*/ +class JUCE_API ResamplingAudioSource : public AudioSource +{ +public: + + /** Creates a ResamplingAudioSource for a given input source. + + @param inputSource the input source to read from + @param deleteInputWhenDeleted if true, the input source will be deleted when + this object is deleted + */ + ResamplingAudioSource (AudioSource* const inputSource, + const bool deleteInputWhenDeleted); + + /** Destructor. */ + ~ResamplingAudioSource(); + + /** Changes the resampling ratio. + + (This value can be changed at any time, even while the source is running). + + @param samplesInPerOutputSample if set to 1.0, the input is passed through; higher + values will speed it up; lower values will slow it + down. The ratio must be greater than 0 + */ + void setResamplingRatio (const double samplesInPerOutputSample); + + /** Returns the current resampling ratio. + + This is the value that was set by setResamplingRatio(). + */ + double getResamplingRatio() const throw() { return ratio; } + + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + void releaseResources(); + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + juce_UseDebuggingNewOperator + +private: + AudioSource* const input; + const bool deleteInputWhenDeleted; + double ratio, lastRatio; + AudioSampleBuffer buffer; + int bufferPos, sampsInBuffer; + double subSampleOffset; + double coefficients[6]; + CriticalSection ratioLock; + + void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6); + void createLowPass (const double proportionalRate); + + struct FilterState + { + double x1, x2, y1, y2; + }; + + FilterState filterStates[2]; + void resetFilters(); + + void applyFilter (float* samples, int num, FilterState& fs); + + ResamplingAudioSource (const ResamplingAudioSource&); + const ResamplingAudioSource& operator= (const ResamplingAudioSource&); +}; + +#endif // __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_ResamplingAudioSource.h *********/ + +/** + An AudioSource that takes a PositionableAudioSource and allows it to be + played, stopped, started, etc. + + This can also be told use a buffer and background thread to read ahead, and + if can correct for different sample-rates. + + You may want to use one of these along with an AudioSourcePlayer and AudioIODevice + to control playback of an audio file. + + @see AudioSource, AudioSourcePlayer +*/ +class JUCE_API AudioTransportSource : public PositionableAudioSource, + public ChangeBroadcaster +{ +public: + + /** Creates an AudioTransportSource. + + After creating one of these, use the setSource() method to select an input source. + */ + AudioTransportSource(); + + /** Destructor. */ + ~AudioTransportSource(); + + /** Sets the reader that is being used as the input source. + + This will stop playback, reset the position to 0 and change to the new reader. + + The source passed in will not be deleted by this object, so must be managed by + the caller. + + @param newSource the new input source to use. This may be zero + @param readAheadBufferSize a size of buffer to use for reading ahead. If this + is zero, no reading ahead will be done; if it's + greater than zero, a BufferingAudioSource will be used + to do the reading-ahead + @param sourceSampleRateToCorrectFor if this is non-zero, it specifies the sample + rate of the source, and playback will be sample-rate + adjusted to maintain playback at the correct pitch. If + this is 0, no sample-rate adjustment will be performed + */ + void setSource (PositionableAudioSource* const newSource, + int readAheadBufferSize = 0, + double sourceSampleRateToCorrectFor = 0.0); + + /** Changes the current playback position in the source stream. + + The next time the getNextAudioBlock() method is called, this + is the time from which it'll read data. + + @see getPosition + */ + void setPosition (double newPosition); + + /** Returns the position that the next data block will be read from + + This is a time in seconds. + */ + double getCurrentPosition() const; + + /** Returns true if the player has stopped because its input stream ran out of data. + */ + bool hasStreamFinished() const throw() { return inputStreamEOF; } + + /** Starts playing (if a source has been selected). + + If it starts playing, this will send a message to any ChangeListeners + that are registered with this object. + */ + void start(); + + /** Stops playing. + + If it's actually playing, this will send a message to any ChangeListeners + that are registered with this object. + */ + void stop(); + + /** Returns true if it's currently playing. */ + bool isPlaying() const throw() { return playing; } + + /** Changes the gain to apply to the output. + + @param newGain a factor by which to multiply the outgoing samples, + so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc. + */ + void setGain (const float newGain) throw(); + + /** Returns the current gain setting. + + @see setGain + */ + float getGain() const throw() { return gain; } + + /** Implementation of the AudioSource method. */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + + /** Implementation of the AudioSource method. */ + void releaseResources(); + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + /** Implements the PositionableAudioSource method. */ + void setNextReadPosition (int newPosition); + + /** Implements the PositionableAudioSource method. */ + int getNextReadPosition() const; + + /** Implements the PositionableAudioSource method. */ + int getTotalLength() const; + + /** Implements the PositionableAudioSource method. */ + bool isLooping() const; + + juce_UseDebuggingNewOperator + +private: + PositionableAudioSource* source; + ResamplingAudioSource* resamplerSource; + BufferingAudioSource* bufferingSource; + PositionableAudioSource* positionableSource; + AudioSource* masterSource; + + CriticalSection callbackLock; + float volatile gain, lastGain; + bool volatile playing, stopped; + double sampleRate, sourceSampleRate; + int blockSize, readAheadBufferSize; + bool isPrepared, inputStreamEOF; + + AudioTransportSource (const AudioTransportSource&); + const AudioTransportSource& operator= (const AudioTransportSource&); +}; + +#endif // __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_AudioTransportSource.h *********/ + +#endif +#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ + +#endif +#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_ChannelRemappingAudioSource.h *********/ +#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ + +/** + An AudioSource that takes the audio from another source, and re-maps its + input and output channels to a different arrangement. + + You can use this to increase or decrease the number of channels that an + audio source uses, or to re-order those channels. + + Call the reset() method before using it to set up a default mapping, and then + the setInputChannelMapping() and setOutputChannelMapping() methods to + create an appropriate mapping, otherwise no channels will be connected and + it'll produce silence. + + @see AudioSource +*/ +class ChannelRemappingAudioSource : public AudioSource +{ +public: + + /** Creates a remapping source that will pass on audio from the given input. + + @param source the input source to use. Make sure that this doesn't + get deleted before the ChannelRemappingAudioSource object + @param deleteSourceWhenDeleted if true, the input source will be deleted + when this object is deleted, if false, the caller is + responsible for its deletion + */ + ChannelRemappingAudioSource (AudioSource* const source, + const bool deleteSourceWhenDeleted); + + /** Destructor. */ + ~ChannelRemappingAudioSource(); + + /** Specifies a number of channels that this audio source must produce from its + getNextAudioBlock() callback. + */ + void setNumberOfChannelsToProduce (const int requiredNumberOfChannels) throw(); + + /** Clears any mapped channels. + + After this, no channels are mapped, so this object will produce silence. Create + some mappings with setInputChannelMapping() and setOutputChannelMapping(). + */ + void clearAllMappings() throw(); + + /** Creates an input channel mapping. + + When the getNextAudioBlock() method is called, the data in channel sourceChannelIndex of the incoming + data will be sent to destChannelIndex of our input source. + + @param destChannelIndex the index of an input channel in our input audio source (i.e. the + source specified when this object was created). + @param sourceChannelIndex the index of the input channel in the incoming audio data buffer + during our getNextAudioBlock() callback + */ + void setInputChannelMapping (const int destChannelIndex, + const int sourceChannelIndex) throw(); + + /** Creates an output channel mapping. + + When the getNextAudioBlock() method is called, the data returned in channel sourceChannelIndex by + our input audio source will be copied to channel destChannelIndex of the final buffer. + + @param sourceChannelIndex the index of an output channel coming from our input audio source + (i.e. the source specified when this object was created). + @param destChannelIndex the index of the output channel in the incoming audio data buffer + during our getNextAudioBlock() callback + */ + void setOutputChannelMapping (const int sourceChannelIndex, + const int destChannelIndex) throw(); + + /** Returns the channel from our input that will be sent to channel inputChannelIndex of + our input audio source. + */ + int getRemappedInputChannel (const int inputChannelIndex) const throw(); + + /** Returns the output channel to which channel outputChannelIndex of our input audio + source will be sent to. + */ + int getRemappedOutputChannel (const int outputChannelIndex) const throw(); + + /** Returns an XML object to encapsulate the state of the mappings. + + @see restoreFromXml + */ + XmlElement* createXml() const throw(); + + /** Restores the mappings from an XML object created by createXML(). + + @see createXml + */ + void restoreFromXml (const XmlElement& e) throw(); + + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + void releaseResources(); + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + juce_UseDebuggingNewOperator + +private: + int requiredNumberOfChannels; + Array remappedInputs, remappedOutputs; + + AudioSource* const source; + const bool deleteSourceWhenDeleted; + + AudioSampleBuffer buffer; + AudioSourceChannelInfo remappedInfo; + + CriticalSection lock; + + ChannelRemappingAudioSource (const ChannelRemappingAudioSource&); + const ChannelRemappingAudioSource& operator= (const ChannelRemappingAudioSource&); +}; + +#endif // __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_ChannelRemappingAudioSource.h *********/ + +#endif +#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_IIRFilterAudioSource.h *********/ +#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_IIRFilter.h *********/ +#ifndef __JUCE_IIRFILTER_JUCEHEADER__ +#define __JUCE_IIRFILTER_JUCEHEADER__ + +/** + An IIR filter that can perform low, high, or band-pass filtering on an + audio signal. + + @see IIRFilterAudioSource +*/ +class JUCE_API IIRFilter +{ +public: + + /** Creates a filter. + + Initially the filter is inactive, so will have no effect on samples that + you process with it. Use the appropriate method to turn it into the type + of filter needed. + */ + IIRFilter() throw(); + + /** Creates a copy of another filter. */ + IIRFilter (const IIRFilter& other) throw(); + + /** Destructor. */ + ~IIRFilter() throw(); + + /** Resets the filter's processing pipeline, ready to start a new stream of data. + + Note that this clears the processing state, but the type of filter and + its coefficients aren't changed. To put a filter into an inactive state, use + the makeInactive() method. + */ + void reset() throw(); + + /** Performs the filter operation on the given set of samples. + */ + void processSamples (float* const samples, + const int numSamples) throw(); + + /** Processes a single sample, without any locking or checking. + + Use this if you need fast processing of a single value, but be aware that + this isn't thread-safe in the way that processSamples() is. + */ + float processSingleSampleRaw (const float sample) throw(); + + /** Sets the filter up to act as a low-pass filter. + */ + void makeLowPass (const double sampleRate, + const double frequency) throw(); + + /** Sets the filter up to act as a high-pass filter. + */ + void makeHighPass (const double sampleRate, + const double frequency) throw(); + + /** Sets the filter up to act as a low-pass shelf filter with variable Q and gain. + + The gain is a scale factor that the low frequencies are multiplied by, so values + greater than 1.0 will boost the low frequencies, values less than 1.0 will + attenuate them. + */ + void makeLowShelf (const double sampleRate, + const double cutOffFrequency, + const double Q, + const float gainFactor) throw(); + + /** Sets the filter up to act as a high-pass shelf filter with variable Q and gain. + + The gain is a scale factor that the high frequencies are multiplied by, so values + greater than 1.0 will boost the high frequencies, values less than 1.0 will + attenuate them. + */ + void makeHighShelf (const double sampleRate, + const double cutOffFrequency, + const double Q, + const float gainFactor) throw(); + + /** Sets the filter up to act as a band pass filter centred around a + frequency, with a variable Q and gain. + + The gain is a scale factor that the centre frequencies are multiplied by, so + values greater than 1.0 will boost the centre frequencies, values less than + 1.0 will attenuate them. + */ + void makeBandPass (const double sampleRate, + const double centreFrequency, + const double Q, + const float gainFactor) throw(); + + /** Clears the filter's coefficients so that it becomes inactive. + */ + void makeInactive() throw(); + + /** Makes this filter duplicate the set-up of another one. + */ + void copyCoefficientsFrom (const IIRFilter& other) throw(); + + juce_UseDebuggingNewOperator + +protected: + CriticalSection processLock; + + void setCoefficients (double c1, double c2, double c3, + double c4, double c5, double c6) throw(); + + bool active; + float coefficients[6]; + float x1, x2, y1, y2; + + // (use the copyCoefficientsFrom() method instead of this operator) + const IIRFilter& operator= (const IIRFilter&); +}; + +#endif // __JUCE_IIRFILTER_JUCEHEADER__ +/********* End of inlined file: juce_IIRFilter.h *********/ + +/** + An AudioSource that performs an IIR filter on another source. +*/ +class JUCE_API IIRFilterAudioSource : public AudioSource +{ +public: + + /** Creates a IIRFilterAudioSource for a given input source. + + @param inputSource the input source to read from + @param deleteInputWhenDeleted if true, the input source will be deleted when + this object is deleted + */ + IIRFilterAudioSource (AudioSource* const inputSource, + const bool deleteInputWhenDeleted); + + /** Destructor. */ + ~IIRFilterAudioSource(); + + /** Changes the filter to use the same parameters as the one being passed in. + */ + void setFilterParameters (const IIRFilter& newSettings); + + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + void releaseResources(); + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + juce_UseDebuggingNewOperator + +private: + + AudioSource* const input; + const bool deleteInputWhenDeleted; + OwnedArray iirFilters; + + IIRFilterAudioSource (const IIRFilterAudioSource&); + const IIRFilterAudioSource& operator= (const IIRFilterAudioSource&); +}; + +#endif // __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_IIRFilterAudioSource.h *********/ + +#endif +#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_MixerAudioSource.h *********/ +#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ + +/** + An AudioSource that mixes together the output of a set of other AudioSources. + + Input sources can be added and removed while the mixer is running as long as their + prepareToPlay() and releaseResources() methods are called before and after adding + them to the mixer. +*/ +class JUCE_API MixerAudioSource : public AudioSource +{ +public: + + /** Creates a MixerAudioSource. + */ + MixerAudioSource(); + + /** Destructor. */ + ~MixerAudioSource(); + + /** Adds an input source to the mixer. + + If the mixer is running you'll need to make sure that the input source + is ready to play by calling its prepareToPlay() method before adding it. + If the mixer is stopped, then its input sources will be automatically + prepared when the mixer's prepareToPlay() method is called. + + @param newInput the source to add to the mixer + @param deleteWhenRemoved if true, then this source will be deleted when + the mixer is deleted or when removeAllInputs() is + called (unless the source is previously removed + with the removeInputSource method) + */ + void addInputSource (AudioSource* newInput, + const bool deleteWhenRemoved); + + /** Removes an input source. + + If the mixer is running, this will remove the source but not call its + releaseResources() method, so the caller might want to do this manually. + + @param input the source to remove + @param deleteSource whether to delete this source after it's been removed + */ + void removeInputSource (AudioSource* input, + const bool deleteSource); + + /** Removes all the input sources. + + If the mixer is running, this will remove the sources but not call their + releaseResources() method, so the caller might want to do this manually. + + Any sources which were added with the deleteWhenRemoved flag set will be + deleted by this method. + */ + void removeAllInputs(); + + /** Implementation of the AudioSource method. + + This will call prepareToPlay() on all its input sources. + */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + + /** Implementation of the AudioSource method. + + This will call releaseResources() on all its input sources. + */ + void releaseResources(); + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + juce_UseDebuggingNewOperator + +private: + + VoidArray inputs; + BitArray inputsToDelete; + CriticalSection lock; + AudioSampleBuffer tempBuffer; + double currentSampleRate; + int bufferSizeExpected; + + MixerAudioSource (const MixerAudioSource&); + const MixerAudioSource& operator= (const MixerAudioSource&); +}; + +#endif // __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_MixerAudioSource.h *********/ + +#endif +#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ + +#endif +#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ + +#endif +#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ + +/********* Start of inlined file: juce_ToneGeneratorAudioSource.h *********/ +#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ +#define __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ + +/** + A simple AudioSource that generates a sine wave. + +*/ +class JUCE_API ToneGeneratorAudioSource : public AudioSource +{ +public: + + /** Creates a ToneGeneratorAudioSource. */ + ToneGeneratorAudioSource(); + + /** Destructor. */ + ~ToneGeneratorAudioSource(); + + /** Sets the signal's amplitude. */ + void setAmplitude (const float newAmplitude); + + /** Sets the signal's frequency. */ + void setFrequency (const double newFrequencyHz); + + /** Implementation of the AudioSource method. */ + void prepareToPlay (int samplesPerBlockExpected, double sampleRate); + + /** Implementation of the AudioSource method. */ + void releaseResources(); + + /** Implementation of the AudioSource method. */ + void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); + + juce_UseDebuggingNewOperator + +private: + + double frequency, sampleRate; + double currentPhase, phasePerSample; + float amplitude; + + ToneGeneratorAudioSource (const ToneGeneratorAudioSource&); + const ToneGeneratorAudioSource& operator= (const ToneGeneratorAudioSource&); +}; + +#endif // __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ +/********* End of inlined file: juce_ToneGeneratorAudioSource.h *********/ + +#endif +#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioDeviceManager.h *********/ +#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ +#define __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioIODeviceType.h *********/ +#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ +#define __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ + +class AudioDeviceManager; +class Component; + +/** + Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc. + + To get a list of available audio driver types, use the createDeviceTypes() + method. Each of the objects returned can then be used to list the available + devices of that type. E.g. + @code + OwnedArray types; + AudioIODeviceType::createDeviceTypes (types); + + for (int i = 0; i < types.size(); ++i) + { + String typeName (types[i]->getTypeName()); // This will be things like "DirectSound", "CoreAudio", etc. + + types[i]->scanForDevices(); // This must be called before getting the list of devices + + StringArray deviceNames (types[i]->getDeviceNames()); // This will now return a list of available devices of this type + + for (int j = 0; j < deviceNames.size(); ++j) + { + AudioIODevice* device = types[i]->createDevice (deviceNames [j]); + + ... + } + } + @endcode + + For an easier way of managing audio devices and their settings, have a look at the + AudioDeviceManager class. + + @see AudioIODevice, AudioDeviceManager +*/ +class JUCE_API AudioIODeviceType +{ +public: + + /** Returns the name of this type of driver that this object manages. + + This will be something like "DirectSound", "ASIO", "CoreAudio", "ALSA", etc. + */ + const String& getTypeName() const throw() { return typeName; } + + /** Refreshes the object's cached list of known devices. + + This must be called at least once before calling getDeviceNames() or any of + the other device creation methods. + */ + virtual void scanForDevices() = 0; + + /** Returns the list of available devices of this type. + + The scanForDevices() method must have been called to create this list. + + @param wantInputNames only really used by DirectSound where devices are split up + into inputs and outputs, this indicates whether to use + the input or output name to refer to a pair of devices. + */ + virtual const StringArray getDeviceNames (const bool wantInputNames = false) const = 0; + + /** Returns the name of the default device. + + This will be one of the names from the getDeviceNames() list. + + @param forInput if true, this means that a default input device should be + returned; if false, it should return the default output + */ + virtual int getDefaultDeviceIndex (const bool forInput) const = 0; + + /** Returns the index of a given device in the list of device names. + If asInput is true, it shows the index in the inputs list, otherwise it + looks for it in the outputs list. + */ + virtual int getIndexOfDevice (AudioIODevice* device, const bool asInput) const = 0; + + /** Returns true if two different devices can be used for the input and output. + */ + virtual bool hasSeparateInputsAndOutputs() const = 0; + + /** Creates one of the devices of this type. + + The deviceName must be one of the strings returned by getDeviceNames(), and + scanForDevices() must have been called before this method is used. + */ + virtual AudioIODevice* createDevice (const String& outputDeviceName, + const String& inputDeviceName) = 0; + + struct DeviceSetupDetails + { + AudioDeviceManager* manager; + int minNumInputChannels, maxNumInputChannels; + int minNumOutputChannels, maxNumOutputChannels; + bool useStereoPairs; + }; + + /** Destructor. */ + virtual ~AudioIODeviceType(); + +protected: + AudioIODeviceType (const tchar* const typeName); + +private: + String typeName; + + AudioIODeviceType (const AudioIODeviceType&); + const AudioIODeviceType& operator= (const AudioIODeviceType&); +}; + +#endif // __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ +/********* End of inlined file: juce_AudioIODeviceType.h *********/ + +/********* Start of inlined file: juce_MidiInput.h *********/ +#ifndef __JUCE_MIDIINPUT_JUCEHEADER__ +#define __JUCE_MIDIINPUT_JUCEHEADER__ /********* Start of inlined file: juce_MidiMessage.h *********/ #ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ @@ -27153,6 +30770,163 @@ private: #endif // __JUCE_MIDIMESSAGE_JUCEHEADER__ /********* End of inlined file: juce_MidiMessage.h *********/ +class MidiInput; + +/** + Receives midi messages from a midi input device. + + This class is overridden to handle incoming midi messages. See the MidiInput + class for more details. + + @see MidiInput +*/ +class JUCE_API MidiInputCallback +{ +public: + /** Destructor. */ + virtual ~MidiInputCallback() {} + + /** Receives an incoming message. + + A MidiInput object will call this method when a midi event arrives. It'll be + called on a high-priority system thread, so avoid doing anything time-consuming + in here, and avoid making any UI calls. You might find the MidiBuffer class helpful + for queueing incoming messages for use later. + + @param source the MidiInput object that generated the message + @param message the incoming message. The message's timestamp is set to a value + equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the + time when the message arrived. + */ + virtual void handleIncomingMidiMessage (MidiInput* source, + const MidiMessage& message) = 0; + + /** Notification sent each time a packet of a multi-packet sysex message arrives. + + If a long sysex message is broken up into multiple packets, this callback is made + for each packet that arrives until the message is finished, at which point + the normal handleIncomingMidiMessage() callback will be made with the entire + message. + + The message passed in will contain the start of a sysex, but won't be finished + with the terminating 0xf7 byte. + */ + virtual void handlePartialSysexMessage (MidiInput* source, + const uint8* messageData, + const int numBytesSoFar, + const double timestamp) + { + // (this bit is just to avoid compiler warnings about unused variables) + (void) source; (void) messageData; (void) numBytesSoFar; (void) timestamp; + } +}; + +/** + Represents a midi input device. + + To create one of these, use the static getDevices() method to find out what inputs are + available, and then use the openDevice() method to try to open one. + + @see MidiOutput +*/ +class JUCE_API MidiInput +{ +public: + + /** Returns a list of the available midi input devices. + + You can open one of the devices by passing its index into the + openDevice() method. + + @see getDefaultDeviceIndex, openDevice + */ + static const StringArray getDevices(); + + /** Returns the index of the default midi input device to use. + + This refers to the index in the list returned by getDevices(). + */ + static int getDefaultDeviceIndex(); + + /** Tries to open one of the midi input devices. + + This will return a MidiInput object if it manages to open it. You can then + call start() and stop() on this device, and delete it when no longer needed. + + If the device can't be opened, this will return a null pointer. + + @param deviceIndex the index of a device from the list returned by getDevices() + @param callback the object that will receive the midi messages from this device. + + @see MidiInputCallback, getDevices + */ + static MidiInput* openDevice (int deviceIndex, + MidiInputCallback* callback); + +#if JUCE_LINUX || JUCE_MAC || DOXYGEN + /** This will try to create a new midi input device (Not available on Windows). + + This will attempt to create a new midi input device with the specified name, + for other apps to connect to. + + Returns 0 if a device can't be created. + + @param deviceName the name to use for the new device + @param callback the object that will receive the midi messages from this device. + */ + static MidiInput* createNewDevice (const String& deviceName, + MidiInputCallback* callback); +#endif + + /** Destructor. */ + virtual ~MidiInput(); + + /** Returns the name of this device. + */ + virtual const String getName() const throw() { return name; } + + /** Allows you to set a custom name for the device, in case you don't like the name + it was given when created. + */ + virtual void setName (const String& newName) throw() { name = newName; } + + /** Starts the device running. + + After calling this, the device will start sending midi messages to the + MidiInputCallback object that was specified when the openDevice() method + was called. + + @see stop + */ + virtual void start(); + + /** Stops the device running. + + @see start + */ + virtual void stop(); + + juce_UseDebuggingNewOperator + +protected: + String name; + void* internal; + + MidiInput (const String& name); + MidiInput (const MidiInput&); +}; + +#endif // __JUCE_MIDIINPUT_JUCEHEADER__ +/********* End of inlined file: juce_MidiInput.h *********/ + +/********* Start of inlined file: juce_MidiOutput.h *********/ +#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__ +#define __JUCE_MIDIOUTPUT_JUCEHEADER__ + +/********* Start of inlined file: juce_MidiBuffer.h *********/ +#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ +#define __JUCE_MIDIBUFFER_JUCEHEADER__ + /** Holds a sequence of time-stamped midi events. @@ -27350,674 +31124,19 @@ private: #endif // __JUCE_MIDIBUFFER_JUCEHEADER__ /********* End of inlined file: juce_MidiBuffer.h *********/ -#endif -#ifndef __JUCE_MIDIFILE_JUCEHEADER__ - -/********* Start of inlined file: juce_MidiFile.h *********/ -#ifndef __JUCE_MIDIFILE_JUCEHEADER__ -#define __JUCE_MIDIFILE_JUCEHEADER__ - -/********* Start of inlined file: juce_MidiMessageSequence.h *********/ -#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ -#define __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ - /** - A sequence of timestamped midi messages. + Represents a midi output device. - This allows the sequence to be manipulated, and also to be read from and - written to a standard midi file. - - @see MidiMessage, MidiFile -*/ -class JUCE_API MidiMessageSequence -{ -public: - - /** Creates an empty midi sequence object. */ - MidiMessageSequence(); - - /** Creates a copy of another sequence. */ - MidiMessageSequence (const MidiMessageSequence& other); - - /** Replaces this sequence with another one. */ - const MidiMessageSequence& operator= (const MidiMessageSequence& other); - - /** Destructor. */ - ~MidiMessageSequence(); - - /** Structure used to hold midi events in the sequence. - - These structures act as 'handles' on the events as they are moved about in - the list, and make it quick to find the matching note-offs for note-on events. - - @see MidiMessageSequence::getEventPointer - */ - class MidiEventHolder - { - public: - - /** Destructor. */ - ~MidiEventHolder(); - - /** The message itself, whose timestamp is used to specify the event's time. - */ - MidiMessage message; - - /** The matching note-off event (if this is a note-on event). - - If this isn't a note-on, this pointer will be null. - - Use the MidiMessageSequence::updateMatchedPairs() method to keep these - note-offs up-to-date after events have been moved around in the sequence - or deleted. - */ - MidiEventHolder* noteOffObject; - - juce_UseDebuggingNewOperator - - private: - friend class MidiMessageSequence; - MidiEventHolder (const MidiMessage& message); - }; - - /** Clears the sequence. */ - void clear(); - - /** Returns the number of events in the sequence. */ - int getNumEvents() const; - - /** Returns a pointer to one of the events. */ - MidiEventHolder* getEventPointer (const int index) const; - - /** Returns the time of the note-up that matches the note-on at this index. - - If the event at this index isn't a note-on, it'll just return 0. - - @see MidiMessageSequence::MidiEventHolder::noteOffObject - */ - double getTimeOfMatchingKeyUp (const int index) const; - - /** Returns the index of the note-up that matches the note-on at this index. - - If the event at this index isn't a note-on, it'll just return -1. - - @see MidiMessageSequence::MidiEventHolder::noteOffObject - */ - int getIndexOfMatchingKeyUp (const int index) const; - - /** Returns the index of an event. */ - int getIndexOf (MidiEventHolder* const event) const; - - /** Returns the index of the first event on or after the given timestamp. - - If the time is beyond the end of the sequence, this will return the - number of events. - */ - int getNextIndexAtTime (const double timeStamp) const; - - /** Returns the timestamp of the first event in the sequence. - - @see getEndTime - */ - double getStartTime() const; - - /** Returns the timestamp of the last event in the sequence. - - @see getStartTime - */ - double getEndTime() const; - - /** Returns the timestamp of the event at a given index. - - If the index is out-of-range, this will return 0.0 - */ - double getEventTime (const int index) const; - - /** Inserts a midi message into the sequence. - - The index at which the new message gets inserted will depend on its timestamp, - because the sequence is kept sorted. - - Remember to call updateMatchedPairs() after adding note-on events. - - @param newMessage the new message to add (an internal copy will be made) - @param timeAdjustment an optional value to add to the timestamp of the message - that will be inserted - @see updateMatchedPairs - */ - void addEvent (const MidiMessage& newMessage, - double timeAdjustment = 0); - - /** Deletes one of the events in the sequence. - - Remember to call updateMatchedPairs() after removing events. - - @param index the index of the event to delete - @param deleteMatchingNoteUp whether to also remove the matching note-off - if the event you're removing is a note-on - */ - void deleteEvent (const int index, - const bool deleteMatchingNoteUp); - - /** Merges another sequence into this one. - - Remember to call updateMatchedPairs() after using this method. - - @param other the sequence to add from - @param timeAdjustmentDelta an amount to add to the timestamps of the midi events - as they are read from the other sequence - @param firstAllowableDestTime events will not be added if their time is earlier - than this time. (This is after their time has been adjusted - by the timeAdjustmentDelta) - @param endOfAllowableDestTimes events will not be added if their time is equal to - or greater than this time. (This is after their time has - been adjusted by the timeAdjustmentDelta) - */ - void addSequence (const MidiMessageSequence& other, - double timeAdjustmentDelta, - double firstAllowableDestTime, - double endOfAllowableDestTimes); - - /** Makes sure all the note-on and note-off pairs are up-to-date. - - Call this after moving messages about or deleting/adding messages, and it - will scan the list and make sure all the note-offs in the MidiEventHolder - structures are pointing at the correct ones. - */ - void updateMatchedPairs(); - - /** Copies all the messages for a particular midi channel to another sequence. - - @param channelNumberToExtract the midi channel to look for, in the range 1 to 16 - @param destSequence the sequence that the chosen events should be copied to - @param alsoIncludeMetaEvents if true, any meta-events (which don't apply to a specific - channel) will also be copied across. - @see extractSysExMessages - */ - void extractMidiChannelMessages (const int channelNumberToExtract, - MidiMessageSequence& destSequence, - const bool alsoIncludeMetaEvents) const; - - /** Copies all midi sys-ex messages to another sequence. - - @param destSequence this is the sequence to which any sys-exes in this sequence - will be added - @see extractMidiChannelMessages - */ - void extractSysExMessages (MidiMessageSequence& destSequence) const; - - /** Removes any messages in this sequence that have a specific midi channel. - - @param channelNumberToRemove the midi channel to look for, in the range 1 to 16 - */ - void deleteMidiChannelMessages (const int channelNumberToRemove); - - /** Removes any sys-ex messages from this sequence. - */ - void deleteSysExMessages(); - - /** Adds an offset to the timestamps of all events in the sequence. - - @param deltaTime the amount to add to each timestamp. - */ - void addTimeToMessages (const double deltaTime); - - /** Scans through the sequence to determine the state of any midi controllers at - a given time. - - This will create a sequence of midi controller changes that can be - used to set all midi controllers to the state they would be in at the - specified time within this sequence. - - As well as controllers, it will also recreate the midi program number - and pitch bend position. - - @param channelNumber the midi channel to look for, in the range 1 to 16. Controllers - for other channels will be ignored. - @param time the time at which you want to find out the state - there are - no explicit units for this time measurement, it's the same units - as used for the timestamps of the messages - @param resultMessages an array to which midi controller-change messages will be added. This - will be the minimum number of controller changes to recreate the - state at the required time. - */ - void createControllerUpdatesForTime (const int channelNumber, - const double time, - OwnedArray& resultMessages); - - juce_UseDebuggingNewOperator - - /** @internal */ - static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, - const MidiMessageSequence::MidiEventHolder* const second) throw(); - -private: - - friend class MidiComparator; - friend class MidiFile; - OwnedArray list; - - void sort(); -}; - -#endif // __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ -/********* End of inlined file: juce_MidiMessageSequence.h *********/ - -/** - Reads/writes standard midi format files. - - To read a midi file, create a MidiFile object and call its readFrom() method. You - can then get the individual midi tracks from it using the getTrack() method. - - To write a file, create a MidiFile object, add some MidiMessageSequence objects - to it using the addTrack() method, and then call its writeTo() method to stream - it out. - - @see MidiMessageSequence -*/ -class JUCE_API MidiFile -{ -public: - - /** Creates an empty MidiFile object. - */ - MidiFile() throw(); - - /** Destructor. */ - ~MidiFile() throw(); - - /** Returns the number of tracks in the file. - - @see getTrack, addTrack - */ - int getNumTracks() const throw(); - - /** Returns a pointer to one of the tracks in the file. - - @returns a pointer to the track, or 0 if the index is out-of-range - @see getNumTracks, addTrack - */ - const MidiMessageSequence* getTrack (const int index) const throw(); - - /** Adds a midi track to the file. - - This will make its own internal copy of the sequence that is passed-in. - - @see getNumTracks, getTrack - */ - void addTrack (const MidiMessageSequence& trackSequence) throw(); - - /** Removes all midi tracks from the file. - - @see getNumTracks - */ - void clear() throw(); - - /** Returns the raw time format code that will be written to a stream. - - After reading a midi file, this method will return the time-format that - was read from the file's header. It can be changed using the setTicksPerQuarterNote() - or setSmpteTimeFormat() methods. - - If the value returned is positive, it indicates the number of midi ticks - per quarter-note - see setTicksPerQuarterNote(). - - It it's negative, the upper byte indicates the frames-per-second (but negative), and - the lower byte is the number of ticks per frame - see setSmpteTimeFormat(). - */ - short getTimeFormat() const throw(); - - /** Sets the time format to use when this file is written to a stream. - - If this is called, the file will be written as bars/beats using the - specified resolution, rather than SMPTE absolute times, as would be - used if setSmpteTimeFormat() had been called instead. - - @param ticksPerQuarterNote e.g. 96, 960 - @see setSmpteTimeFormat - */ - void setTicksPerQuarterNote (const int ticksPerQuarterNote) throw(); - - /** Sets the time format to use when this file is written to a stream. - - If this is called, the file will be written using absolute times, rather - than bars/beats as would be the case if setTicksPerBeat() had been called - instead. - - @param framesPerSecond must be 24, 25, 29 or 30 - @param subframeResolution the sub-second resolution, e.g. 4 (midi time code), - 8, 10, 80 (SMPTE bit resolution), or 100. For millisecond - timing, setSmpteTimeFormat (25, 40) - @see setTicksPerBeat - */ - void setSmpteTimeFormat (const int framesPerSecond, - const int subframeResolution) throw(); - - /** Makes a list of all the tempo-change meta-events from all tracks in the midi file. - - Useful for finding the positions of all the tempo changes in a file. - - @param tempoChangeEvents a list to which all the events will be added - */ - void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const; - - /** Makes a list of all the time-signature meta-events from all tracks in the midi file. - - Useful for finding the positions of all the tempo changes in a file. - - @param timeSigEvents a list to which all the events will be added - */ - void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const; - - /** Returns the latest timestamp in any of the tracks. - - (Useful for finding the length of the file). - */ - double getLastTimestamp() const; - - /** Reads a midi file format stream. - - After calling this, you can get the tracks that were read from the file by using the - getNumTracks() and getTrack() methods. - - The timestamps of the midi events in the tracks will represent their positions in - terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds() - method. - - @returns true if the stream was read successfully - */ - bool readFrom (InputStream& sourceStream); - - /** Writes the midi tracks as a standard midi file. - - @returns true if the operation succeeded. - */ - bool writeTo (OutputStream& destStream); - - /** Converts the timestamp of all the midi events from midi ticks to seconds. - - This will use the midi time format and tempo/time signature info in the - tracks to convert all the timestamps to absolute values in seconds. - */ - void convertTimestampTicksToSeconds(); - - juce_UseDebuggingNewOperator - - /** @internal */ - static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, - const MidiMessageSequence::MidiEventHolder* const second) throw(); - -private: - MidiMessageSequence* tracks [128]; - short numTracks, timeFormat; - - MidiFile (const MidiFile&); - const MidiFile& operator= (const MidiFile&); - - void readNextTrack (const char* data, int size); - void writeTrack (OutputStream& mainOut, const int trackNum); -}; - -#endif // __JUCE_MIDIFILE_JUCEHEADER__ -/********* End of inlined file: juce_MidiFile.h *********/ - -#endif -#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - -/********* Start of inlined file: juce_MidiKeyboardState.h *********/ -#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ -#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - -class MidiKeyboardState; - -/** - Receives events from a MidiKeyboardState object. - - @see MidiKeyboardState -*/ -class JUCE_API MidiKeyboardStateListener -{ -public: - - MidiKeyboardStateListener() throw() {} - virtual ~MidiKeyboardStateListener() {} - - /** Called when one of the MidiKeyboardState's keys is pressed. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOn() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOn (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber, float velocity) = 0; - - /** Called when one of the MidiKeyboardState's keys is released. - - This will be called synchronously when the state is either processing a - buffer in its MidiKeyboardState::processNextMidiBuffer() method, or - when a note is being played with its MidiKeyboardState::noteOff() method. - - Note that this callback could happen from an audio callback thread, so be - careful not to block, and avoid any UI activity in the callback. - */ - virtual void handleNoteOff (MidiKeyboardState* source, - int midiChannel, int midiNoteNumber) = 0; -}; - -/** - Represents a piano keyboard, keeping track of which keys are currently pressed. - - This object can parse a stream of midi events, using them to update its idea - of which keys are pressed for each individiual midi channel. - - When keys go up or down, it can broadcast these events to listener objects. - - It also allows key up/down events to be triggered with its noteOn() and noteOff() - methods, and midi messages for these events will be merged into the - midi stream that gets processed by processNextMidiBuffer(). -*/ -class JUCE_API MidiKeyboardState -{ -public: - - MidiKeyboardState(); - ~MidiKeyboardState(); - - /** Resets the state of the object. - - All internal data for all the channels is reset, but no events are sent as a - result. - - If you want to release any keys that are currently down, and to send out note-up - midi messages for this, use the allNotesOff() method instead. - */ - void reset(); - - /** Returns true if the given midi key is currently held down for the given midi channel. - - The channel number must be between 1 and 16. If you want to see if any notes are - on for a range of channels, use the isNoteOnForChannels() method. - */ - bool isNoteOn (const int midiChannel, const int midiNoteNumber) const throw(); - - /** Returns true if the given midi key is currently held down on any of a set of midi channels. - - The channel mask has a bit set for each midi channel you want to test for - bit - 0 = midi channel 1, bit 1 = midi channel 2, etc. - - If a note is on for at least one of the specified channels, this returns true. - */ - bool isNoteOnForChannels (const int midiChannelMask, const int midiNoteNumber) const throw(); - - /** Turns a specified note on. - - This will cause a suitable midi note-on event to be injected into the midi buffer during the - next call to processNextMidiBuffer(). - - It will also trigger a synchronous callback to the listeners to tell them that the key has - gone down. - */ - void noteOn (const int midiChannel, const int midiNoteNumber, const float velocity); - - /** Turns a specified note off. - - This will cause a suitable midi note-off event to be injected into the midi buffer during the - next call to processNextMidiBuffer(). - - It will also trigger a synchronous callback to the listeners to tell them that the key has - gone up. - - But if the note isn't acutally down for the given channel, this method will in fact do nothing. - */ - void noteOff (const int midiChannel, const int midiNoteNumber); - - /** This will turn off any currently-down notes for the given midi channel. - - If you pass 0 for the midi channel, it will in fact turn off all notes on all channels. - - Calling this method will make calls to noteOff(), so can trigger synchronous callbacks - and events being added to the midi stream. - */ - void allNotesOff (const int midiChannel); - - /** Looks at a key-up/down event and uses it to update the state of this object. - - To process a buffer full of midi messages, use the processNextMidiBuffer() method - instead. - */ - void processNextMidiEvent (const MidiMessage& message); - - /** Scans a midi stream for up/down events and adds its own events to it. - - This will look for any up/down events and use them to update the internal state, - synchronously making suitable callbacks to the listeners. - - If injectIndirectEvents is true, then midi events to produce the recent noteOn() - and noteOff() calls will be added into the buffer. - - Only the section of the buffer whose timestamps are between startSample and - (startSample + numSamples) will be affected, and any events added will be placed - between these times. - - If you're going to use this method, you'll need to keep calling it regularly for - it to work satisfactorily. - - To process a single midi event at a time, use the processNextMidiEvent() method - instead. - */ - void processNextMidiBuffer (MidiBuffer& buffer, - const int startSample, - const int numSamples, - const bool injectIndirectEvents); - - /** Registers a listener for callbacks when keys go up or down. - - @see removeListener - */ - void addListener (MidiKeyboardStateListener* const listener) throw(); - - /** Deregisters a listener. - - @see addListener - */ - void removeListener (MidiKeyboardStateListener* const listener) throw(); - - juce_UseDebuggingNewOperator - -private: - CriticalSection lock; - uint16 noteStates [128]; - MidiBuffer eventsToAdd; - VoidArray listeners; - - void noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity); - void noteOffInternal (const int midiChannel, const int midiNoteNumber); - - MidiKeyboardState (const MidiKeyboardState&); - const MidiKeyboardState& operator= (const MidiKeyboardState&); -}; - -#endif // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ -/********* End of inlined file: juce_MidiKeyboardState.h *********/ - -#endif -#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ - -/********* Start of inlined file: juce_MidiMessageCollector.h *********/ -#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ -#define __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ - -/********* Start of inlined file: juce_MidiInput.h *********/ -#ifndef __JUCE_MIDIINPUT_JUCEHEADER__ -#define __JUCE_MIDIINPUT_JUCEHEADER__ - -class MidiInput; - -/** - Receives midi messages from a midi input device. - - This class is overridden to handle incoming midi messages. See the MidiInput - class for more details. + To create one of these, use the static getDevices() method to find out what + outputs are available, then use the openDevice() method to try to open one. @see MidiInput */ -class JUCE_API MidiInputCallback -{ -public: - /** Destructor. */ - virtual ~MidiInputCallback() {} - - /** Receives an incoming message. - - A MidiInput object will call this method when a midi event arrives. It'll be - called on a high-priority system thread, so avoid doing anything time-consuming - in here, and avoid making any UI calls. You might find the MidiBuffer class helpful - for queueing incoming messages for use later. - - @param source the MidiInput object that generated the message - @param message the incoming message. The message's timestamp is set to a value - equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the - time when the message arrived. - */ - virtual void handleIncomingMidiMessage (MidiInput* source, - const MidiMessage& message) = 0; - - /** Notification sent each time a packet of a multi-packet sysex message arrives. - - If a long sysex message is broken up into multiple packets, this callback is made - for each packet that arrives until the message is finished, at which point - the normal handleIncomingMidiMessage() callback will be made with the entire - message. - - The message passed in will contain the start of a sysex, but won't be finished - with the terminating 0xf7 byte. - */ - virtual void handlePartialSysexMessage (MidiInput* source, - const uint8* messageData, - const int numBytesSoFar, - const double timestamp) - { - // (this bit is just to avoid compiler warnings about unused variables) - (void) source; (void) messageData; (void) numBytesSoFar; (void) timestamp; - } -}; - -/** - Represents a midi input device. - - To create one of these, use the static getDevices() method to find out what inputs are - available, and then use the openDevice() method to try to open one. - - @see MidiOutput -*/ -class JUCE_API MidiInput +class JUCE_API MidiOutput : private Thread { public: - /** Returns a list of the available midi input devices. + /** Returns a list of the available midi output devices. You can open one of the devices by passing its index into the openDevice() method. @@ -28026,3173 +31145,194 @@ public: */ static const StringArray getDevices(); - /** Returns the index of the default midi input device to use. + /** Returns the index of the default midi output device to use. This refers to the index in the list returned by getDevices(). */ static int getDefaultDeviceIndex(); - /** Tries to open one of the midi input devices. + /** Tries to open one of the midi output devices. - This will return a MidiInput object if it manages to open it. You can then - call start() and stop() on this device, and delete it when no longer needed. + This will return a MidiOutput object if it manages to open it. You can then + send messages to this device, and delete it when no longer needed. If the device can't be opened, this will return a null pointer. @param deviceIndex the index of a device from the list returned by getDevices() - @param callback the object that will receive the midi messages from this device. - - @see MidiInputCallback, getDevices + @see getDevices */ - static MidiInput* openDevice (int deviceIndex, - MidiInputCallback* callback); + static MidiOutput* openDevice (int deviceIndex); #if JUCE_LINUX || JUCE_MAC || DOXYGEN - /** This will try to create a new midi input device (Not available on Windows). + /** This will try to create a new midi output device (Not available on Windows). - This will attempt to create a new midi input device with the specified name, - for other apps to connect to. + This will attempt to create a new midi output device that other apps can connect + to and use as their midi input. Returns 0 if a device can't be created. @param deviceName the name to use for the new device - @param callback the object that will receive the midi messages from this device. */ - static MidiInput* createNewDevice (const String& deviceName, - MidiInputCallback* callback); + static MidiOutput* createNewDevice (const String& deviceName); #endif /** Destructor. */ - virtual ~MidiInput(); + virtual ~MidiOutput(); - /** Returns the name of this device. - */ - virtual const String getName() const throw() { return name; } - - /** Allows you to set a custom name for the device, in case you don't like the name - it was given when created. - */ - virtual void setName (const String& newName) throw() { name = newName; } - - /** Starts the device running. - - After calling this, the device will start sending midi messages to the - MidiInputCallback object that was specified when the openDevice() method - was called. - - @see stop - */ - virtual void start(); - - /** Stops the device running. - - @see start - */ - virtual void stop(); - - juce_UseDebuggingNewOperator - -protected: - String name; - void* internal; - - MidiInput (const String& name); - MidiInput (const MidiInput&); -}; - -#endif // __JUCE_MIDIINPUT_JUCEHEADER__ -/********* End of inlined file: juce_MidiInput.h *********/ - -/** - Collects incoming realtime MIDI messages and turns them into blocks suitable for - processing by a block-based audio callback. - - The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback - so it can easily use a midi input or keyboard component as its source. - - @see MidiMessage, MidiInput -*/ -class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener, - public MidiInputCallback -{ -public: - - /** Creates a MidiMessageCollector. */ - MidiMessageCollector(); - - /** Destructor. */ - ~MidiMessageCollector(); - - /** Clears any messages from the queue. - - You need to call this method before starting to use the collector, so that - it knows the correct sample rate to use. - */ - void reset (const double sampleRate); - - /** Takes an incoming real-time message and adds it to the queue. - - The message's timestamp is taken, and it will be ready for retrieval as part - of the block returned by the next call to removeNextBlockOfMessages(). - - This method is fully thread-safe when overlapping calls are made with - removeNextBlockOfMessages(). - */ - void addMessageToQueue (const MidiMessage& message); - - /** Removes all the pending messages from the queue as a buffer. - - This will also correct the messages' timestamps to make sure they're in - the range 0 to numSamples - 1. - - This call should be made regularly by something like an audio processing - callback, because the time that it happens is used in calculating the - midi event positions. - - This method is fully thread-safe when overlapping calls are made with - addMessageToQueue(). - */ - void removeNextBlockOfMessages (MidiBuffer& destBuffer, - const int numSamples); - - /** @internal */ - void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity); - /** @internal */ - void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber); - /** @internal */ - void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); - - juce_UseDebuggingNewOperator - -private: - double lastCallbackTime; - CriticalSection midiCallbackLock; - MidiBuffer incomingMessages; - double sampleRate; - - MidiMessageCollector (const MidiMessageCollector&); - const MidiMessageCollector& operator= (const MidiMessageCollector&); -}; - -#endif // __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ -/********* End of inlined file: juce_MidiMessageCollector.h *********/ - -#endif -#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ - -#endif -#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioDataConverters.h *********/ -#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ -#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ - -/** - A set of routines to convert buffers of 32-bit floating point data to and from - various integer formats. - -*/ -class JUCE_API AudioDataConverters -{ -public: - - static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2); - static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2); - - static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3); - static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3); - - static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - - static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - - static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2); - static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2); - - static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3); - static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3); - - static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - - static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - - enum DataFormat - { - int16LE, - int16BE, - int24LE, - int24BE, - int32LE, - int32BE, - float32LE, - float32BE, - }; - - static void convertFloatToFormat (const DataFormat destFormat, - const float* source, void* dest, int numSamples); - - static void convertFormatToFloat (const DataFormat sourceFormat, - const void* source, float* dest, int numSamples); - - static void interleaveSamples (const float** source, float* dest, - const int numSamples, const int numChannels); - - static void deinterleaveSamples (const float* source, float** dest, - const int numSamples, const int numChannels); -}; - -#endif // __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ -/********* End of inlined file: juce_AudioDataConverters.h *********/ - -#endif -#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioSampleBuffer.h *********/ -#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ -#define __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ - -class AudioFormatReader; -class AudioFormatWriter; - -/** - A multi-channel buffer of 32-bit floating point audio samples. - -*/ -class JUCE_API AudioSampleBuffer -{ -public: - - /** Creates a buffer with a specified number of channels and samples. - - The contents of the buffer will initially be undefined, so use clear() to - set all the samples to zero. - - The buffer will allocate its memory internally, and this will be released - when the buffer is deleted. - */ - AudioSampleBuffer (const int numChannels, - const int numSamples) throw(); - - /** Creates a buffer using a pre-allocated block of memory. - - Note that if the buffer is resized or its number of channels is changed, it - will re-allocate memory internally and copy the existing data to this new area, - so it will then stop directly addressing this memory. - - @param dataToReferTo a pre-allocated array containing pointers to the data - for each channel that should be used by this buffer. The - buffer will only refer to this memory, it won't try to delete - it when the buffer is deleted or resized. - @param numChannels the number of channels to use - this must correspond to the - number of elements in the array passed in - @param numSamples the number of samples to use - this must correspond to the - size of the arrays passed in - */ - AudioSampleBuffer (float** dataToReferTo, - const int numChannels, - const int numSamples) throw(); - - /** Copies another buffer. - - This buffer will make its own copy of the other's data, unless the buffer was created - using an external data buffer, in which case boths buffers will just point to the same - shared block of data. - */ - AudioSampleBuffer (const AudioSampleBuffer& other) throw(); - - /** Copies another buffer onto this one. - - This buffer's size will be changed to that of the other buffer. - */ - const AudioSampleBuffer& operator= (const AudioSampleBuffer& other) throw(); - - /** Destructor. - - This will free any memory allocated by the buffer. - */ - virtual ~AudioSampleBuffer() throw(); - - /** Returns the number of channels of audio data that this buffer contains. - - @see getSampleData - */ - int getNumChannels() const throw() { return numChannels; } - - /** Returns the number of samples allocated in each of the buffer's channels. - - @see getSampleData - */ - int getNumSamples() const throw() { return size; } - - /** Returns a pointer one of the buffer's channels. - - For speed, this doesn't check whether the channel number is out of range, - so be careful when using it! - */ - float* getSampleData (const int channelNumber) const throw() - { - jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); - return channels [channelNumber]; - } + /** Makes this device output a midi message. - /** Returns a pointer to a sample in one of the buffer's channels. - - For speed, this doesn't check whether the channel and sample number - are out-of-range, so be careful when using it! - */ - float* getSampleData (const int channelNumber, - const int sampleOffset) const throw() - { - jassert (((unsigned int) channelNumber) < (unsigned int) numChannels); - jassert (((unsigned int) sampleOffset) < (unsigned int) size); - return channels [channelNumber] + sampleOffset; - } - - /** Returns an array of pointers to the channels in the buffer. - - Don't modify any of the pointers that are returned, and bear in mind that - these will become invalid if the buffer is resized. - */ - float** getArrayOfChannels() const throw() { return channels; } - - /** Chages the buffer's size or number of channels. - - This can expand or contract the buffer's length, and add or remove channels. - - If keepExistingContent is true, it will try to preserve as much of the - old data as it can in the new buffer. - - If clearExtraSpace is true, then any extra channels or space that is - allocated will be also be cleared. If false, then this space is left - uninitialised. - - If avoidReallocating is true, then changing the buffer's size won't reduce the - amount of memory that is currently allocated (but it will still increase it if - the new size is bigger than the amount it currently has). If this is false, then - a new allocation will be done so that the buffer uses takes up the minimum amount - of memory that it needs. - */ - void setSize (const int newNumChannels, - const int newNumSamples, - const bool keepExistingContent = false, - const bool clearExtraSpace = false, - const bool avoidReallocating = false) throw(); - - /** Makes this buffer point to a pre-allocated set of channel data arrays. - - There's also a constructor that lets you specify arrays like this, but this - lets you change the channels dynamically. - - Note that if the buffer is resized or its number of channels is changed, it - will re-allocate memory internally and copy the existing data to this new area, - so it will then stop directly addressing this memory. - - @param dataToReferTo a pre-allocated array containing pointers to the data - for each channel that should be used by this buffer. The - buffer will only refer to this memory, it won't try to delete - it when the buffer is deleted or resized. - @param numChannels the number of channels to use - this must correspond to the - number of elements in the array passed in - @param numSamples the number of samples to use - this must correspond to the - size of the arrays passed in - */ - void setDataToReferTo (float** dataToReferTo, - const int numChannels, - const int numSamples) throw(); - - /** Clears all the samples in all channels. */ - void clear() throw(); - - /** Clears a specified region of all the channels. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void clear (const int startSample, - const int numSamples) throw(); - - /** Clears a specified region of just one channel. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! + @see MidiMessage */ - void clear (const int channel, - const int startSample, - const int numSamples) throw(); - - /** Applies a gain multiple to a region of one channel. - - For speed, this doesn't check whether the channel and sample number - are in-range, so be careful! - */ - void applyGain (const int channel, - const int startSample, - int numSamples, - const float gain) throw(); - - /** Applies a gain multiple to a region of all the channels. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGain (const int startSample, - const int numSamples, - const float gain) throw(); - - /** Applies a range of gains to a region of a channel. - - The gain that is applied to each sample will vary from - startGain on the first sample to endGain on the last Sample, - so it can be used to do basic fades. - - For speed, this doesn't check whether the sample numbers - are in-range, so be careful! - */ - void applyGainRamp (const int channel, - const int startSample, - int numSamples, - float startGain, - float endGain) throw(); - - /** Adds samples from another buffer to this one. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to add from - @param sourceChannel the channel within the source buffer to read from - @param sourceStartSample the offset within the source buffer's channel to start reading samples from - @param numSamples the number of samples to process - @param gainToApplyToSource an optional gain to apply to the source samples before they are - added to this buffer's samples - - @see copyFrom - */ - void addFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples, - const float gainToApplyToSource = 1.0f) throw(); - - /** Adds samples from an array of floats to one of the channels. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source data to use - @param numSamples the number of samples to process - @param gainToApplyToSource an optional gain to apply to the source samples before they are - added to this buffer's samples - - @see copyFrom - */ - void addFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gainToApplyToSource = 1.0f) throw(); - - /** Adds samples from an array of floats, applying a gain ramp to them. - - @param destChannel the channel within this buffer to add the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source data to use - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are added to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - */ - void addFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) throw(); - - /** Copies samples from another buffer to this one. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param sourceChannel the channel within the source buffer to read from - @param sourceStartSample the offset within the source buffer's channel to start reading samples from - @param numSamples the number of samples to process - - @see addFrom - */ - void copyFrom (const int destChannel, - const int destStartSample, - const AudioSampleBuffer& source, - const int sourceChannel, - const int sourceStartSample, - int numSamples) throw(); - - /** Copies samples from an array of floats into one of the channels. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - - @see addFrom - */ - void copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples) throw(); - - /** Copies samples from an array of floats into one of the channels, applying a gain to it. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - @param gain the gain to apply - - @see addFrom - */ - void copyFrom (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - const float gain) throw(); - - /** Copies samples from an array of floats into one of the channels, applying a gain ramp. - - @param destChannel the channel within this buffer to copy the samples to - @param destStartSample the start sample within this buffer's channel - @param source the source buffer to read from - @param numSamples the number of samples to process - @param startGain the gain to apply to the first sample (this is multiplied with - the source samples before they are copied to this buffer) - @param endGain the gain to apply to the final sample. The gain is linearly - interpolated between the first and last samples. - - @see addFrom - */ - void copyFromWithRamp (const int destChannel, - const int destStartSample, - const float* source, - int numSamples, - float startGain, - float endGain) throw(); - - /** Finds the highest and lowest sample values in a given range. - - @param channel the channel to read from - @param startSample the start sample within the channel - @param numSamples the number of samples to check - @param minVal on return, the lowest value that was found - @param maxVal on return, the highest value that was found - */ - void findMinMax (const int channel, - const int startSample, - int numSamples, - float& minVal, - float& maxVal) const throw(); - - /** Finds the highest absolute sample value within a region of a channel. - */ - float getMagnitude (const int channel, - const int startSample, - const int numSamples) const throw(); - - /** Finds the highest absolute sample value within a region on all channels. - */ - float getMagnitude (const int startSample, - const int numSamples) const throw(); - - /** Returns the root mean squared level for a region of a channel. - */ - float getRMSLevel (const int channel, - const int startSample, - const int numSamples) const throw(); - - /** Fills a section of the buffer using an AudioReader as its source. - - This will convert the reader's fixed- or floating-point data to - the buffer's floating-point format, and will try to intelligently - cope with mismatches between the number of channels in the reader - and the buffer. - - @see writeToAudioWriter - */ - void readFromAudioReader (AudioFormatReader* reader, - const int startSample, - const int numSamples, - const int readerStartSample, - const bool useReaderLeftChan, - const bool useReaderRightChan) throw(); - - /** Writes a section of this buffer to an audio writer. - - This saves you having to mess about with channels or floating/fixed - point conversion. - - @see readFromAudioReader - */ - void writeToAudioWriter (AudioFormatWriter* writer, - const int startSample, - const int numSamples) const throw(); - - juce_UseDebuggingNewOperator - -private: - int numChannels, size, allocatedBytes; - float** channels; - float* allocatedData; - float* preallocatedChannelSpace [32]; -}; - -#endif // __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ -/********* End of inlined file: juce_AudioSampleBuffer.h *********/ - -#endif -#ifndef __JUCE_IIRFILTER_JUCEHEADER__ - -/********* Start of inlined file: juce_IIRFilter.h *********/ -#ifndef __JUCE_IIRFILTER_JUCEHEADER__ -#define __JUCE_IIRFILTER_JUCEHEADER__ - -/** - An IIR filter that can perform low, high, or band-pass filtering on an - audio signal. - - @see IIRFilterAudioSource -*/ -class JUCE_API IIRFilter -{ -public: - - /** Creates a filter. - - Initially the filter is inactive, so will have no effect on samples that - you process with it. Use the appropriate method to turn it into the type - of filter needed. - */ - IIRFilter() throw(); - - /** Creates a copy of another filter. */ - IIRFilter (const IIRFilter& other) throw(); + virtual void sendMessageNow (const MidiMessage& message); - /** Destructor. */ - ~IIRFilter() throw(); - - /** Resets the filter's processing pipeline, ready to start a new stream of data. - - Note that this clears the processing state, but the type of filter and - its coefficients aren't changed. To put a filter into an inactive state, use - the makeInactive() method. - */ - void reset() throw(); - - /** Performs the filter operation on the given set of samples. - */ - void processSamples (float* const samples, - const int numSamples) throw(); - - /** Processes a single sample, without any locking or checking. - - Use this if you need fast processing of a single value, but be aware that - this isn't thread-safe in the way that processSamples() is. - */ - float processSingleSampleRaw (const float sample) throw(); - - /** Sets the filter up to act as a low-pass filter. - */ - void makeLowPass (const double sampleRate, - const double frequency) throw(); - - /** Sets the filter up to act as a high-pass filter. - */ - void makeHighPass (const double sampleRate, - const double frequency) throw(); - - /** Sets the filter up to act as a low-pass shelf filter with variable Q and gain. - - The gain is a scale factor that the low frequencies are multiplied by, so values - greater than 1.0 will boost the low frequencies, values less than 1.0 will - attenuate them. - */ - void makeLowShelf (const double sampleRate, - const double cutOffFrequency, - const double Q, - const float gainFactor) throw(); - - /** Sets the filter up to act as a high-pass shelf filter with variable Q and gain. - - The gain is a scale factor that the high frequencies are multiplied by, so values - greater than 1.0 will boost the high frequencies, values less than 1.0 will - attenuate them. - */ - void makeHighShelf (const double sampleRate, - const double cutOffFrequency, - const double Q, - const float gainFactor) throw(); - - /** Sets the filter up to act as a band pass filter centred around a - frequency, with a variable Q and gain. - - The gain is a scale factor that the centre frequencies are multiplied by, so - values greater than 1.0 will boost the centre frequencies, values less than - 1.0 will attenuate them. - */ - void makeBandPass (const double sampleRate, - const double centreFrequency, - const double Q, - const float gainFactor) throw(); - - /** Clears the filter's coefficients so that it becomes inactive. - */ - void makeInactive() throw(); - - /** Makes this filter duplicate the set-up of another one. - */ - void copyCoefficientsFrom (const IIRFilter& other) throw(); - - juce_UseDebuggingNewOperator - -protected: - CriticalSection processLock; - - void setCoefficients (double c1, double c2, double c3, - double c4, double c5, double c6) throw(); - - bool active; - float coefficients[6]; - float x1, x2, y1, y2; - - // (use the copyCoefficientsFrom() method instead of this operator) - const IIRFilter& operator= (const IIRFilter&); -}; - -#endif // __JUCE_IIRFILTER_JUCEHEADER__ -/********* End of inlined file: juce_IIRFilter.h *********/ - -#endif -#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioPlayHead.h *********/ -#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ -#define __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ - -/** - A subclass of AudioPlayHead can supply information about the position and - status of a moving play head during audio playback. - - One of these can be supplied to an AudioProcessor object so that it can find - out about the position of the audio that it is rendering. - - @see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead -*/ -class JUCE_API AudioPlayHead -{ -protected: - - AudioPlayHead() {} - -public: - virtual ~AudioPlayHead() {} - - /** Frame rate types. */ - enum FrameRateType - { - fps24 = 0, - fps25 = 1, - fps2997 = 2, - fps30 = 3, - fps2997drop = 4, - fps30drop = 5, - fpsUnknown = 99 - }; - - /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method. - */ - struct CurrentPositionInfo - { - /** The tempo in BPM */ - double bpm; - - /** Time signature numerator, e.g. the 3 of a 3/4 time sig */ - int timeSigNumerator; - /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ - int timeSigDenominator; - - /** The current play position, in seconds from the start of the edit. */ - double timeInSeconds; - - /** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */ - double editOriginTime; - - /** The current play position in pulses-per-quarter-note. - - This is the number of quarter notes since the edit start. - */ - double ppqPosition; - - /** The position of the start of the last bar, in pulses-per-quarter-note. - - This is the number of quarter notes from the start of the edit to the - start of the current bar. - - Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If - it's not available, the value will be 0. - */ - double ppqPositionOfLastBarStart; - - /** The video frame rate, if applicable. */ - FrameRateType frameRate; - - /** True if the transport is currently playing. */ - bool isPlaying; - - /** True if the transport is currently recording. - - (When isRecording is true, then isPlaying will also be true). - */ - bool isRecording; - }; - - /** Fills-in the given structure with details about the transport's - position at the start of the current processing block. - */ - virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0; -}; - -#endif // __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ -/********* End of inlined file: juce_AudioPlayHead.h *********/ - -#endif -#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioProcessor.h *********/ -#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ -#define __JUCE_AUDIOPROCESSOR_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioProcessorEditor.h *********/ -#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ -#define __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ - -class AudioProcessor; - -/** - Base class for the component that acts as the GUI for an AudioProcessor. - - Derive your editor component from this class, and create an instance of it - by overriding the AudioProcessor::createEditor() method. - - @see AudioProcessor, GenericAudioProcessorEditor -*/ -class JUCE_API AudioProcessorEditor : public Component -{ -protected: - - /** Creates an editor for the specified processor. - */ - AudioProcessorEditor (AudioProcessor* const owner); - -public: - /** Destructor. */ - ~AudioProcessorEditor(); - - /** Returns a pointer to the processor that this editor represents. */ - AudioProcessor* getAudioProcessor() const throw() { return owner; } - -private: - - AudioProcessor* const owner; -}; - -#endif // __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ -/********* End of inlined file: juce_AudioProcessorEditor.h *********/ - -/********* Start of inlined file: juce_AudioProcessorListener.h *********/ -#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ -#define __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ - -class AudioProcessor; - -/** - Base class for listeners that want to know about changes to an AudioProcessor. - - Use AudioProcessor::addListener() to register your listener with an AudioProcessor. - - @see AudioProcessor -*/ -class JUCE_API AudioProcessorListener -{ -public: - - /** Destructor. */ - virtual ~AudioProcessorListener() {} - - /** Receives a callback when a parameter is changed. - - IMPORTANT NOTE: this will be called synchronously when a parameter changes, and - many audio processors will change their parameter during their audio callback. - This means that not only has your handler code got to be completely thread-safe, - but it's also got to be VERY fast, and avoid blocking. If you need to handle - this event on your message thread, use this callback to trigger an AsyncUpdater - or ChangeBroadcaster which you can respond to on the message thread. - */ - virtual void audioProcessorParameterChanged (AudioProcessor* processor, - int parameterIndex, - float newValue) = 0; - - /** Called to indicate that something else in the plugin has changed, like its - program, number of parameters, etc. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - */ - virtual void audioProcessorChanged (AudioProcessor* processor) = 0; - - /** Indicates that a parameter change gesture has started. - - E.g. if the user is dragging a slider, this would be called when they first - press the mouse button, and audioProcessorParameterChangeGestureEnd would be - called when they release it. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - - @see audioProcessorParameterChangeGestureEnd - */ - virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor, - int parameterIndex); - - /** Indicates that a parameter change gesture has finished. - - E.g. if the user is dragging a slider, this would be called when they release - the mouse button. - - IMPORTANT NOTE: this will be called synchronously, and many audio processors will - call it during their audio callback. This means that not only has your handler code - got to be completely thread-safe, but it's also got to be VERY fast, and avoid - blocking. If you need to handle this event on your message thread, use this callback - to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the - message thread. - - @see audioPluginParameterChangeGestureStart - */ - virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor, - int parameterIndex); -}; - -#endif // __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ -/********* End of inlined file: juce_AudioProcessorListener.h *********/ - -/** - Base class for audio processing filters or plugins. - - This is intended to act as a base class of audio filter that is general enough to - be wrapped as a VST, AU, RTAS, etc, or used internally. - - It is also used by the plugin hosting code as the wrapper around an instance - of a loaded plugin. - - Derive your filter class from this base class, and if you're building a plugin, - you should implement a global function called createPluginFilter() which creates - and returns a new instance of your subclass. -*/ -class JUCE_API AudioProcessor -{ -protected: - - /** Constructor. - - You can also do your initialisation tasks in the initialiseFilterInfo() - call, which will be made after this object has been created. - */ - AudioProcessor(); - -public: - /** Destructor. */ - virtual ~AudioProcessor(); - - /** Returns the name of this processor. - */ - virtual const String getName() const = 0; - - /** Called before playback starts, to let the filter prepare itself. - - The sample rate is the target sample rate, and will remain constant until - playback stops. - - The estimatedSamplesPerBlock value is a HINT about the typical number of - samples that will be processed for each callback, but isn't any kind - of guarantee. The actual block sizes that the host uses may be different - each time the callback happens, and may be more or less than this value. - */ - virtual void prepareToPlay (double sampleRate, - int estimatedSamplesPerBlock) = 0; - - /** Called after playback has stopped, to let the filter free up any resources it - no longer needs. - */ - virtual void releaseResources() = 0; - - /** Renders the next block. - - When this method is called, the buffer contains a number of channels which is - at least as great as the maximum number of input and output channels that - this filter is using. It will be filled with the filter's input data and - should be replaced with the filter's output. - - So for example if your filter has 2 input channels and 4 output channels, then - the buffer will contain 4 channels, the first two being filled with the - input data. Your filter should read these, do its processing, and replace - the contents of all 4 channels with its output. - - Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels, - all filled with data, and your filter should overwrite the first 2 of these - with its output. But be VERY careful not to write anything to the last 3 - channels, as these might be mapped to memory that the host assumes is read-only! - - Note that if you have more outputs than inputs, then only those channels that - correspond to an input channel are guaranteed to contain sensible data - e.g. - in the case of 2 inputs and 4 outputs, the first two channels contain the input, - but the last two channels may contain garbage, so you should be careful not to - let this pass through without being overwritten or cleared. - - Also note that the buffer may have more channels than are strictly necessary, - but your should only read/write from the ones that your filter is supposed to - be using. - - The number of samples in these buffers is NOT guaranteed to be the same for every - callback, and may be more or less than the estimated value given to prepareToPlay(). - Your code must be able to cope with variable-sized blocks, or you're going to get - clicks and crashes! - - If the filter is receiving a midi input, then the midiMessages array will be filled - with the midi messages for this block. Each message's timestamp will indicate the - message's time, as a number of samples from the start of the block. - - Any messages left in the midi buffer when this method has finished are assumed to - be the filter's midi output. This means that your filter should be careful to - clear any incoming messages from the array if it doesn't want them to be passed-on. - - Be very careful about what you do in this callback - it's going to be called by - the audio thread, so any kind of interaction with the UI is absolutely - out of the question. If you change a parameter in here and need to tell your UI to - update itself, the best way is probably to inherit from a ChangeBroadcaster, let - the UI components register as listeners, and then call sendChangeMessage() inside the - processBlock() method to send out an asynchronous message. You could also use - the AsyncUpdater class in a similar way. - */ - virtual void processBlock (AudioSampleBuffer& buffer, - MidiBuffer& midiMessages) = 0; - - /** Returns the current AudioPlayHead object that should be used to find - out the state and position of the playhead. - - You can call this from your processBlock() method, and use the AudioPlayHead - object to get the details about the time of the start of the block currently - being processed. - - If the host hasn't supplied a playhead object, this will return 0. - */ - AudioPlayHead* getPlayHead() const throw() { return playHead; } - - /** Returns the current sample rate. - - This can be called from your processBlock() method - it's not guaranteed - to be valid at any other time, and may return 0 if it's unknown. - */ - double getSampleRate() const throw() { return sampleRate; } - - /** Returns the current typical block size that is being used. - - This can be called from your processBlock() method - it's not guaranteed - to be valid at any other time. - - Remember it's not the ONLY block size that may be used when calling - processBlock, it's just the normal one. The actual block sizes used may be - larger or smaller than this, and will vary between successive calls. - */ - int getBlockSize() const throw() { return blockSize; } - - /** Returns the number of input channels that the host will be sending the filter. - - If writing a plugin, your JucePluginCharacteristics.h file should specify the - number of channels that your filter would prefer to have, and this method lets - you know how many the host is actually using. - - Note that this method is only valid during or after the prepareToPlay() - method call. Until that point, the number of channels will be unknown. - */ - int getNumInputChannels() const throw() { return numInputChannels; } - - /** Returns the number of output channels that the host will be sending the filter. - - If writing a plugin, your JucePluginCharacteristics.h file should specify the - number of channels that your filter would prefer to have, and this method lets - you know how many the host is actually using. - - Note that this method is only valid during or after the prepareToPlay() - method call. Until that point, the number of channels will be unknown. - */ - int getNumOutputChannels() const throw() { return numOutputChannels; } - - /** Returns the name of one of the input channels, as returned by the host. - - The host might not supply very useful names for channels, and this might be - something like "1", "2", "left", "right", etc. - */ - virtual const String getInputChannelName (const int channelIndex) const = 0; - - /** Returns the name of one of the output channels, as returned by the host. - - The host might not supply very useful names for channels, and this might be - something like "1", "2", "left", "right", etc. - */ - virtual const String getOutputChannelName (const int channelIndex) const = 0; - - /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ - virtual bool isInputChannelStereoPair (int index) const = 0; - - /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ - virtual bool isOutputChannelStereoPair (int index) const = 0; - - /** This returns the number of samples delay that the filter imposes on the audio - passing through it. - - The host will call this to find the latency - the filter itself should set this value - by calling setLatencySamples() as soon as it can during its initialisation. - */ - int getLatencySamples() const throw() { return latencySamples; } - - /** The filter should call this to set the number of samples delay that it introduces. - - The filter should call this as soon as it can during initialisation, and can call it - later if the value changes. - */ - void setLatencySamples (const int newLatency); - - /** Returns true if the processor wants midi messages. */ - virtual bool acceptsMidi() const = 0; - - /** Returns true if the processor produces midi messages. */ - virtual bool producesMidi() const = 0; - - /** This returns a critical section that will automatically be locked while the host - is calling the processBlock() method. - - Use it from your UI or other threads to lock access to variables that are used - by the process callback, but obviously be careful not to keep it locked for - too long, because that could cause stuttering playback. If you need to do something - that'll take a long time and need the processing to stop while it happens, use the - suspendProcessing() method instead. - - @see suspendProcessing - */ - const CriticalSection& getCallbackLock() const throw() { return callbackLock; } - - /** Enables and disables the processing callback. - - If you need to do something time-consuming on a thread and would like to make sure - the audio processing callback doesn't happen until you've finished, use this - to disable the callback and re-enable it again afterwards. - - E.g. - @code - void loadNewPatch() - { - suspendProcessing (true); - - ..do something that takes ages.. - - suspendProcessing (false); - } - @endcode - - If the host tries to make an audio callback while processing is suspended, the - filter will return an empty buffer, but won't block the audio thread like it would - do if you use the getCallbackLock() critical section to synchronise access. - - If you're going to use this, your processBlock() method must call isSuspended() and - check whether it's suspended or not. If it is, then it should skip doing any real - processing, either emitting silence or passing the input through unchanged. - - @see getCallbackLock - */ - void suspendProcessing (const bool shouldBeSuspended); - - /** Returns true if processing is currently suspended. - @see suspendProcessing - */ - bool isSuspended() const throw() { return suspended; } - - /** A plugin can override this to be told when it should reset any playing voices. - - The default implementation does nothing, but a host may call this to tell the - plugin that it should stop any tails or sounds that have been left running. - */ + /** Sends a midi reset to the device. */ virtual void reset(); - /** Returns true if the processor is being run in an offline mode for rendering. + /** Returns the current volume setting for this device. */ + virtual bool getVolume (float& leftVol, + float& rightVol); - If the processor is being run live on realtime signals, this returns false. - If the mode is unknown, this will assume it's realtime and return false. + /** Changes the overall volume for this device. */ + virtual void setVolume (float leftVol, + float rightVol); - This value may be unreliable until the prepareToPlay() method has been called, - and could change each time prepareToPlay() is called. + /** This lets you supply a block of messages that will be sent out at some point + in the future. - @see setNonRealtime() + The MidiOutput class has an internal thread that can send out timestamped + messages - this appends a set of messages to its internal buffer, ready for + sending. + + This will only work if you've already started the thread with startBackgroundThread(). + + A time is supplied, at which the block of messages should be sent. This time uses + the same time base as Time::getMillisecondCounter(), and must be in the future. + + The samplesPerSecondForBuffer parameter indicates the number of samples per second + used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the + samplesPerSecondForBuffer value is needed to convert this sample position to a + real time. */ - bool isNonRealtime() const throw() { return nonRealtime; } + virtual void sendBlockOfMessages (const MidiBuffer& buffer, + const double millisecondCounterToStartAt, + double samplesPerSecondForBuffer) throw(); - /** Called by the host to tell this processor whether it's being used in a non-realime - capacity for offline rendering or bouncing. - - Whatever value is passed-in will be + /** Gets rid of any midi messages that had been added by sendBlockOfMessages(). */ - void setNonRealtime (const bool isNonRealtime) throw(); + virtual void clearAllPendingMessages() throw(); - /** Creates the filter's UI. + /** Starts up a background thread so that the device can send blocks of data. - This can return 0 if you want a UI-less filter, in which case the host may create - a generic UI that lets the user twiddle the parameters directly. - - If you do want to pass back a component, the component should be created and set to - the correct size before returning it. - - Remember not to do anything silly like allowing your filter to keep a pointer to - the component that gets created - it could be deleted later without any warning, which - would make your pointer into a dangler. Use the getActiveEditor() method instead. - - The correct way to handle the connection between an editor component and its - filter is to use something like a ChangeBroadcaster so that the editor can - register itself as a listener, and be told when a change occurs. This lets them - safely unregister themselves when they are deleted. - - Here are a few things to bear in mind when writing an editor: - - - Initially there won't be an editor, until the user opens one, or they might - not open one at all. Your filter mustn't rely on it being there. - - An editor object may be deleted and a replacement one created again at any time. - - It's safe to assume that an editor will be deleted before its filter. + Call this to get the device ready, before using sendBlockOfMessages(). */ - virtual AudioProcessorEditor* createEditor() = 0; + virtual void startBackgroundThread() throw(); - /** Returns the active editor, if there is one. + /** Stops the background thread, and clears any pending midi events. - Bear in mind this can return 0, even if an editor has previously been - opened. + @see startBackgroundThread */ - AudioProcessorEditor* getActiveEditor() const throw() { return activeEditor; } - - /** Returns the active editor, or if there isn't one, it will create one. - - This may call createEditor() internally to create the component. - */ - AudioProcessorEditor* createEditorIfNeeded(); - - /** This must return the correct value immediately after the object has been - created, and mustn't change the number of parameters later. - */ - virtual int getNumParameters() = 0; - - /** Returns the name of a particular parameter. */ - virtual const String getParameterName (int parameterIndex) = 0; - - /** Called by the host to find out the value of one of the filter's parameters. - - The host will expect the value returned to be between 0 and 1.0. - - This could be called quite frequently, so try to make your code efficient. - It's also likely to be called by non-UI threads, so the code in here should - be thread-aware. - */ - virtual float getParameter (int parameterIndex) = 0; - - /** Returns the value of a parameter as a text string. */ - virtual const String getParameterText (int parameterIndex) = 0; - - /** The host will call this method to change the value of one of the filter's parameters. - - The host may call this at any time, including during the audio processing - callback, so the filter has to process this very fast and avoid blocking. - - If you want to set the value of a parameter internally, e.g. from your - editor component, then don't call this directly - instead, use the - setParameterNotifyingHost() method, which will also send a message to - the host telling it about the change. If the message isn't sent, the host - won't be able to automate your parameters properly. - - The value passed will be between 0 and 1.0. - */ - virtual void setParameter (int parameterIndex, - float newValue) = 0; - - /** Your filter can call this when it needs to change one of its parameters. - - This could happen when the editor or some other internal operation changes - a parameter. This method will call the setParameter() method to change the - value, and will then send a message to the host telling it about the change. - - Note that to make sure the host correctly handles automation, you should call - the beginParameterChangeGesture() and endParameterChangeGesture() methods to - tell the host when the user has started and stopped changing the parameter. - */ - void setParameterNotifyingHost (int parameterIndex, - float newValue); - - /** Returns true if the host can automate this parameter. - - By default, this returns true for all parameters. - */ - virtual bool isParameterAutomatable (int parameterIndex) const; - - /** Should return true if this parameter is a "meta" parameter. - - A meta-parameter is a parameter that changes other params. It is used - by some hosts (e.g. AudioUnit hosts). - - By default this returns false. - */ - virtual bool isMetaParameter (int parameterIndex) const; - - /** Sends a signal to the host to tell it that the user is about to start changing this - parameter. - - This allows the host to know when a parameter is actively being held by the user, and - it may use this information to help it record automation. - - If you call this, it must be matched by a later call to endParameterChangeGesture(). - */ - void beginParameterChangeGesture (int parameterIndex); - - /** Tells the host that the user has finished changing this parameter. - - This allows the host to know when a parameter is actively being held by the user, and - it may use this information to help it record automation. - - A call to this method must follow a call to beginParameterChangeGesture(). - */ - void endParameterChangeGesture (int parameterIndex); - - /** The filter can call this when something (apart from a parameter value) has changed. - - It sends a hint to the host that something like the program, number of parameters, - etc, has changed, and that it should update itself. - */ - void updateHostDisplay(); - - /** Returns the number of preset programs the filter supports. - - The value returned must be valid as soon as this object is created, and - must not change over its lifetime. - - This value shouldn't be less than 1. - */ - virtual int getNumPrograms() = 0; - - /** Returns the number of the currently active program. - */ - virtual int getCurrentProgram() = 0; - - /** Called by the host to change the current program. - */ - virtual void setCurrentProgram (int index) = 0; - - /** Must return the name of a given program. */ - virtual const String getProgramName (int index) = 0; - - /** Called by the host to rename a program. - */ - virtual void changeProgramName (int index, const String& newName) = 0; - - /** The host will call this method when it wants to save the filter's internal state. - - This must copy any info about the filter's state into the block of memory provided, - so that the host can store this and later restore it using setStateInformation(). - - Note that there's also a getCurrentProgramStateInformation() method, which only - stores the current program, not the state of the entire filter. - - See also the helper function copyXmlToBinary() for storing settings as XML. - - @see getCurrentProgramStateInformation - */ - virtual void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0; - - /** The host will call this method if it wants to save the state of just the filter's - current program. - - Unlike getStateInformation, this should only return the current program's state. - - Not all hosts support this, and if you don't implement it, the base class - method just calls getStateInformation() instead. If you do implement it, be - sure to also implement getCurrentProgramStateInformation. - - @see getStateInformation, setCurrentProgramStateInformation - */ - virtual void getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); - - /** This must restore the filter's state from a block of data previously created - using getStateInformation(). - - Note that there's also a setCurrentProgramStateInformation() method, which tries - to restore just the current program, not the state of the entire filter. - - See also the helper function getXmlFromBinary() for loading settings as XML. - - @see setCurrentProgramStateInformation - */ - virtual void setStateInformation (const void* data, int sizeInBytes) = 0; - - /** The host will call this method if it wants to restore the state of just the filter's - current program. - - Not all hosts support this, and if you don't implement it, the base class - method just calls setStateInformation() instead. If you do implement it, be - sure to also implement getCurrentProgramStateInformation. - - @see setStateInformation, getCurrentProgramStateInformation - */ - virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes); - - /** Adds a listener that will be called when an aspect of this processor changes. */ - void addListener (AudioProcessorListener* const newListener) throw(); - - /** Removes a previously added listener. */ - void removeListener (AudioProcessorListener* const listenerToRemove) throw(); - - /** Not for public use - this is called before deleting an editor component. */ - void editorBeingDeleted (AudioProcessorEditor* const editor) throw(); - - /** Not for public use - this is called to initialise the processor. */ - void setPlayHead (AudioPlayHead* const newPlayHead) throw(); - - /** Not for public use - this is called to initialise the processor before playing. */ - void setPlayConfigDetails (const int numIns, const int numOuts, - const double sampleRate, - const int blockSize) throw(); + virtual void stopBackgroundThread() throw(); juce_UseDebuggingNewOperator protected: + void* internal; - /** Helper function that just converts an xml element into a binary blob. - - Use this in your filter's getStateInformation() method if you want to - store its state as xml. - - Then use getXmlFromBinary() to reverse this operation and retrieve the XML - from a binary blob. - */ - static void copyXmlToBinary (const XmlElement& xml, - JUCE_NAMESPACE::MemoryBlock& destData); - - /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method. - - This might return 0 if the data's unsuitable or corrupted. Otherwise it will return - an XmlElement object that the caller must delete when no longer needed. - */ - static XmlElement* getXmlFromBinary (const void* data, - const int sizeInBytes); - - /** @internal */ - AudioPlayHead* playHead; - - /** @internal */ - void sendParamChangeMessageToListeners (const int parameterIndex, const float newValue); - -private: - VoidArray listeners; - AudioProcessorEditor* activeEditor; - double sampleRate; - int blockSize, numInputChannels, numOutputChannels, latencySamples; - bool suspended, nonRealtime; - CriticalSection callbackLock, listenerLock; - -#ifdef JUCE_DEBUG - BitArray changingParams; -#endif - - AudioProcessor (const AudioProcessor&); - const AudioProcessor& operator= (const AudioProcessor&); -}; - -#endif // __JUCE_AUDIOPROCESSOR_JUCEHEADER__ -/********* End of inlined file: juce_AudioProcessor.h *********/ - -#endif -#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioProcessorGraph.h *********/ -#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ -#define __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioPluginFormatManager.h *********/ -#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ -#define __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioPluginFormat.h *********/ -#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ -#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioPluginInstance.h *********/ -#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ -#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ - -/********* Start of inlined file: juce_PluginDescription.h *********/ -#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ -#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ - -/** - A small class to represent some facts about a particular type of plugin. - - This class is for storing and managing the details about a plugin without - actually having to load an instance of it. - - A KnownPluginList contains a list of PluginDescription objects. - - @see KnownPluginList -*/ -class JUCE_API PluginDescription -{ -public: - - PluginDescription() throw(); - PluginDescription (const PluginDescription& other) throw(); - const PluginDescription& operator= (const PluginDescription& other) throw(); - ~PluginDescription() throw(); - - /** The name of the plugin. */ - String name; - - /** The plugin format, e.g. "VST", "AudioUnit", etc. - */ - String pluginFormatName; - - /** A category, such as "Dynamics", "Reverbs", etc. - */ - String category; - - /** The manufacturer. */ - String manufacturerName; - - /** The version. This string doesn't have any particular format. */ - String version; - - /** Either the file containing the plugin module, or some other unique way - of identifying it. - - E.g. for an AU, this would be an ID string that the component manager - could use to retrieve the plugin. For a VST, it's the file path. - */ - String fileOrIdentifier; - - /** The last time the plugin file was changed. - This is handy when scanning for new or changed plugins. - */ - Time lastFileModTime; - - /** A unique ID for the plugin. - - Note that this might not be unique between formats, e.g. a VST and some - other format might actually have the same id. - - @see createIdentifierString - */ - int uid; - - /** True if the plugin identifies itself as a synthesiser. */ - bool isInstrument; - - /** The number of inputs. */ - int numInputChannels; - - /** The number of outputs. */ - int numOutputChannels; - - /** Returns true if the two descriptions refer the the same plugin. - - This isn't quite as simple as them just having the same file (because of - shell plugins). - */ - bool isDuplicateOf (const PluginDescription& other) const; - - /** Returns a string that can be saved and used to uniquely identify the - plugin again. - - This contains less info than the XML encoding, and is independent of the - plugin's file location, so can be used to store a plugin ID for use - across different machines. - */ - const String createIdentifierString() const throw(); - - /** Creates an XML object containing these details. - - @see loadFromXml - */ - XmlElement* createXml() const; - - /** Reloads the info in this structure from an XML record that was previously - saved with createXML(). - - Returns true if the XML was a valid plugin description. - */ - bool loadFromXml (const XmlElement& xml); - - juce_UseDebuggingNewOperator -}; - -#endif // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ -/********* End of inlined file: juce_PluginDescription.h *********/ - -/** - Base class for an active instance of a plugin. - - This derives from the AudioProcessor class, and adds some extra functionality - that helps when wrapping dynamically loaded plugins. - - @see AudioProcessor, AudioPluginFormat -*/ -class JUCE_API AudioPluginInstance : public AudioProcessor -{ -public: - - /** Destructor. - - Make sure that you delete any UI components that belong to this plugin before - deleting the plugin. - */ - virtual ~AudioPluginInstance(); - - /** Fills-in the appropriate parts of this plugin description object. - */ - virtual void fillInPluginDescription (PluginDescription& description) const = 0; - - juce_UseDebuggingNewOperator - -protected: - AudioPluginInstance(); - - AudioPluginInstance (const AudioPluginInstance&); - const AudioPluginInstance& operator= (const AudioPluginInstance&); -}; - -#endif // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ -/********* End of inlined file: juce_AudioPluginInstance.h *********/ - -class PluginDescription; - -/** - The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc. - - Use the static getNumFormats() and getFormat() calls to find the types - of format that are available. -*/ -class JUCE_API AudioPluginFormat -{ -public: - - /** Destructor. */ - virtual ~AudioPluginFormat(); - - /** Returns the format name. - - E.g. "VST", "AudioUnit", etc. - */ - virtual const String getName() const = 0; - - /** This tries to create descriptions for all the plugin types available in - a binary module file. - - The file will be some kind of DLL or bundle. - - Normally there will only be one type returned, but some plugins - (e.g. VST shells) can use a single DLL to create a set of different plugin - subtypes, so in that case, each subtype is returned as a separate object. - */ - virtual void findAllTypesForFile (OwnedArray & results, - const String& fileOrIdentifier) = 0; - - /** Tries to recreate a type from a previously generated PluginDescription. - - @see PluginDescription::createInstance - */ - virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0; - - /** Should do a quick check to see if this file or directory might be a plugin of - this format. - - This is for searching for potential files, so it shouldn't actually try to - load the plugin or do anything time-consuming. - */ - virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0; - - /** Returns a readable version of the name of the plugin that this identifier refers to. - */ - virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0; - - /** Checks whether this plugin could possibly be loaded. - - It doesn't actually need to load it, just to check whether the file or component - still exists. - */ - virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; - - /** Searches a suggested set of directories for any plugins in this format. - - The path might be ignored, e.g. by AUs, which are found by the OS rather - than manually. - */ - virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, - const bool recursive) = 0; - - /** Returns the typical places to look for this kind of plugin. - - Note that if this returns no paths, it means that the format can't be scanned-for - (i.e. it's an internal format that doesn't live in files) - */ - virtual const FileSearchPath getDefaultLocationsToSearch() = 0; - - juce_UseDebuggingNewOperator - -protected: - AudioPluginFormat() throw(); - - AudioPluginFormat (const AudioPluginFormat&); - const AudioPluginFormat& operator= (const AudioPluginFormat&); -}; - -#endif // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_AudioPluginFormat.h *********/ - -/** - This maintains a list of known AudioPluginFormats. - - @see AudioPluginFormat -*/ -class JUCE_API AudioPluginFormatManager : public DeletedAtShutdown -{ -public: - - AudioPluginFormatManager() throw(); - - /** Destructor. */ - ~AudioPluginFormatManager() throw(); - - juce_DeclareSingleton_SingleThreaded (AudioPluginFormatManager, false); - - /** Adds any formats that it knows about, e.g. VST. - */ - void addDefaultFormats(); - - /** Returns the number of types of format that are available. - - Use getFormat() to get one of them. - */ - int getNumFormats() throw(); - - /** Returns one of the available formats. - - @see getNumFormats - */ - AudioPluginFormat* getFormat (const int index) throw(); - - /** Adds a format to the list. - - The object passed in will be owned and deleted by the manager. - */ - void addFormat (AudioPluginFormat* const format) throw(); - - /** Tries to load the type for this description, by trying all the formats - that this manager knows about. - - The caller is responsible for deleting the object that is returned. - - If it can't load the plugin, it returns 0 and leaves a message in the - errorMessage string. - */ - AudioPluginInstance* createPluginInstance (const PluginDescription& description, - String& errorMessage) const; - - /** Checks that the file or component for this plugin actually still exists. - - (This won't try to load the plugin) - */ - bool doesPluginStillExist (const PluginDescription& description) const; - - juce_UseDebuggingNewOperator - -private: - OwnedArray formats; - - AudioPluginFormatManager (const AudioPluginFormatManager&); - const AudioPluginFormatManager& operator= (const AudioPluginFormatManager&); -}; - -#endif // __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ -/********* End of inlined file: juce_AudioPluginFormatManager.h *********/ - -/********* Start of inlined file: juce_KnownPluginList.h *********/ -#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ -#define __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ - -/********* Start of inlined file: juce_PopupMenu.h *********/ -#ifndef __JUCE_POPUPMENU_JUCEHEADER__ -#define __JUCE_POPUPMENU_JUCEHEADER__ - -/********* Start of inlined file: juce_PopupMenuCustomComponent.h *********/ -#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ -#define __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ - -/** A user-defined copmonent that can appear inside one of the rows of a popup menu. - - @see PopupMenu::addCustomItem -*/ -class JUCE_API PopupMenuCustomComponent : public Component -{ -public: - /** Destructor. */ - ~PopupMenuCustomComponent(); - - /** Chooses the size that this component would like to have. - - Note that the size which this method returns isn't necessarily the one that - the menu will give it, as it will be stretched to fit the other items in - the menu. - */ - virtual void getIdealSize (int& idealWidth, - int& idealHeight) = 0; - - /** Dismisses the menu indicating that this item has been chosen. - - This will cause the menu to exit from its modal state, returning - this item's id as the result. - */ - void triggerMenuItem(); - - /** Returns true if this item should be highlighted because the mouse is - over it. - - You can call this method in your paint() method to find out whether - to draw a highlight. - */ - bool isItemHighlighted() const throw() { return isHighlighted; } - -protected: - /** Constructor. - - If isTriggeredAutomatically is true, then the menu will automatically detect - a click on this component and use that to trigger it. If it's false, then it's - up to your class to manually trigger the item if it wants to. - */ - PopupMenuCustomComponent (const bool isTriggeredAutomatically = true); - -private: - friend class MenuItemInfo; - friend class MenuItemComponent; - friend class PopupMenuWindow; - int refCount_; - bool isHighlighted, isTriggeredAutomatically; - - PopupMenuCustomComponent (const PopupMenuCustomComponent&); - const PopupMenuCustomComponent& operator= (const PopupMenuCustomComponent&); -}; - -#endif // __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_PopupMenuCustomComponent.h *********/ - -/** Creates and displays a popup-menu. - - To show a popup-menu, you create one of these, add some items to it, then - call its show() method, which returns the id of the item the user selects. - - E.g. @code - void MyWidget::mouseDown (const MouseEvent& e) + struct PendingMessage { - PopupMenu m; - m.addItem (1, "item 1"); - m.addItem (2, "item 2"); + PendingMessage (const uint8* const data, const int len, const double sampleNumber) throw(); - const int result = m.show(); - - if (result == 0) - { - // user dismissed the menu without picking anything - } - else if (result == 1) - { - // user picked item 1 - } - else if (result == 2) - { - // user picked item 2 - } - } - @endcode - - Submenus are easy too: @code - - void MyWidget::mouseDown (const MouseEvent& e) - { - PopupMenu subMenu; - subMenu.addItem (1, "item 1"); - subMenu.addItem (2, "item 2"); - - PopupMenu mainMenu; - mainMenu.addItem (3, "item 3"); - mainMenu.addSubMenu ("other choices", subMenu); - - const int result = m.show(); - - ...etc - } - @endcode -*/ -class JUCE_API PopupMenu -{ -public: - - /** Creates an empty popup menu. */ - PopupMenu() throw(); - - /** Creates a copy of another menu. */ - PopupMenu (const PopupMenu& other) throw(); - - /** Destructor. */ - ~PopupMenu() throw(); - - /** Copies this menu from another one. */ - const PopupMenu& operator= (const PopupMenu& other) throw(); - - /** Resets the menu, removing all its items. */ - void clear() throw(); - - /** Appends a new text item for this menu to show. - - @param itemResultId the number that will be returned from the show() method - if the user picks this item. The value should never be - zero, because that's used to indicate that the user didn't - select anything. - @param itemText the text to show. - @param isActive if false, the item will be shown 'greyed-out' and can't be - picked - @param isTicked if true, the item will be shown with a tick next to it - @param iconToUse if this is non-zero, it should be an image that will be - displayed to the left of the item. This method will take its - own copy of the image passed-in, so there's no need to keep - it hanging around. - - @see addSeparator, addColouredItem, addCustomItem, addSubMenu - */ - void addItem (const int itemResultId, - const String& itemText, - const bool isActive = true, - const bool isTicked = false, - const Image* const iconToUse = 0) throw(); - - /** Adds an item that represents one of the commands in a command manager object. - - @param commandManager the manager to use to trigger the command and get information - about it - @param commandID the ID of the command - @param displayName if this is non-empty, then this string will be used instead of - the command's registered name - */ - void addCommandItem (ApplicationCommandManager* commandManager, - const int commandID, - const String& displayName = String::empty) throw(); - - /** Appends a text item with a special colour. - - This is the same as addItem(), but specifies a colour to use for the - text, which will override the default colours that are used by the - current look-and-feel. See addItem() for a description of the parameters. - */ - void addColouredItem (const int itemResultId, - const String& itemText, - const Colour& itemTextColour, - const bool isActive = true, - const bool isTicked = false, - const Image* const iconToUse = 0) throw(); - - /** Appends a custom menu item. - - This will add a user-defined component to use as a menu item. The component - passed in will be deleted by this menu when it's no longer needed. - - @see PopupMenuCustomComponent - */ - void addCustomItem (const int itemResultId, - PopupMenuCustomComponent* const customComponent) throw(); - - /** Appends a custom menu item that can't be used to trigger a result. - - This will add a user-defined component to use as a menu item. Unlike the - addCustomItem() method that takes a PopupMenuCustomComponent, this version - can't trigger a result from it, so doesn't take a menu ID. It also doesn't - delete the component when it's finished, so it's the caller's responsibility - to manage the component that is passed-in. - - if triggerMenuItemAutomaticallyWhenClicked is true, the menu itself will handle - detection of a mouse-click on your component, and use that to trigger the - menu ID specified in itemResultId. If this is false, the menu item can't - be triggered, so itemResultId is not used. - - @see PopupMenuCustomComponent - */ - void addCustomItem (const int itemResultId, - Component* customComponent, - int idealWidth, int idealHeight, - const bool triggerMenuItemAutomaticallyWhenClicked) throw(); - - /** Appends a sub-menu. - - If the menu that's passed in is empty, it will appear as an inactive item. - */ - void addSubMenu (const String& subMenuName, - const PopupMenu& subMenu, - const bool isActive = true, - Image* const iconToUse = 0, - const bool isTicked = false) throw(); - - /** Appends a separator to the menu, to help break it up into sections. - - The menu class is smart enough not to display separators at the top or bottom - of the menu, and it will replace mutliple adjacent separators with a single - one, so your code can be quite free and easy about adding these, and it'll - always look ok. - */ - void addSeparator() throw(); - - /** Adds a non-clickable text item to the menu. - - This is a bold-font items which can be used as a header to separate the items - into named groups. - */ - void addSectionHeader (const String& title) throw(); - - /** Returns the number of items that the menu currently contains. - - (This doesn't count separators). - */ - int getNumItems() const throw(); - - /** Returns true if the menu contains a command item that triggers the given command. */ - bool containsCommandItem (const int commandID) const throw(); - - /** Returns true if the menu contains any items that can be used. */ - bool containsAnyActiveItems() const throw(); - - /** Displays the menu and waits for the user to pick something. - - This will display the menu modally, and return the ID of the item that the - user picks. If they click somewhere off the menu to get rid of it without - choosing anything, this will return 0. - - The current location of the mouse will be used as the position to show the - menu - to explicitly set the menu's position, use showAt() instead. Depending - on where this point is on the screen, the menu will appear above, below or - to the side of the point. - - @param itemIdThatMustBeVisible if you set this to the ID of one of the menu items, - then when the menu first appears, it will make sure - that this item is visible. So if the menu has too many - items to fit on the screen, it will be scrolled to a - position where this item is visible. - @param minimumWidth a minimum width for the menu, in pixels. It may be wider - than this if some items are too long to fit. - @param maximumNumColumns if there are too many items to fit on-screen in a single - vertical column, the menu may be laid out as a series of - columns - this is the maximum number allowed. To use the - default value for this (probably about 7), you can pass - in zero. - @param standardItemHeight if this is non-zero, it will be used as the standard - height for menu items (apart from custom items) - @see showAt - */ - int show (const int itemIdThatMustBeVisible = 0, - const int minimumWidth = 0, - const int maximumNumColumns = 0, - const int standardItemHeight = 0); - - /** Displays the menu at a specific location. - - This is the same as show(), but uses a specific location (in global screen - co-ordinates) rather than the current mouse position. - - Note that the co-ordinates don't specify the top-left of the menu - they - indicate a point of interest, and the menu will position itself nearby to - this point, trying to keep it fully on-screen. - - @see show() - */ - int showAt (const int screenX, - const int screenY, - const int itemIdThatMustBeVisible = 0, - const int minimumWidth = 0, - const int maximumNumColumns = 0, - const int standardItemHeight = 0); - - /** Displays the menu as if it's attached to a component such as a button. - - This is similar to showAt(), but will position it next to the given component, e.g. - so that the menu's edge is aligned with that of the component. This is intended for - things like buttons that trigger a pop-up menu. - */ - int showAt (Component* componentToAttachTo, - const int itemIdThatMustBeVisible = 0, - const int minimumWidth = 0, - const int maximumNumColumns = 0, - const int standardItemHeight = 0); - - /** Closes any menus that are currently open. - - This might be useful if you have a situation where your window is being closed - by some means other than a user action, and you'd like to make sure that menus - aren't left hanging around. - */ - static void JUCE_CALLTYPE dismissAllActiveMenus() throw(); - - /** Specifies a look-and-feel for the menu and any sub-menus that it has. - - This can be called before show() if you need a customised menu. Be careful - not to delete the LookAndFeel object before the menu has been deleted. - */ - void setLookAndFeel (LookAndFeel* const newLookAndFeel) throw(); - - /** A set of colour IDs to use to change the colour of various aspects of the menu. - - These constants can be used either via the LookAndFeel::setColour() - method for the look and feel that is set for this menu with setLookAndFeel() - - @see setLookAndFeel, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1000700, /**< The colour to fill the menu's background with. */ - textColourId = 0x1000600, /**< The colour for normal menu item text, (unless the - colour is specified when the item is added). */ - headerTextColourId = 0x1000601, /**< The colour for section header item text (see the - addSectionHeader() method). */ - highlightedBackgroundColourId = 0x1000900, /**< The colour to fill the background of the currently - highlighted menu item. */ - highlightedTextColourId = 0x1000800, /**< The colour to use for the text of the currently - highlighted item. */ - }; - - /** - Allows you to iterate through the items in a pop-up menu, and examine - their properties. - - To use this, just create one and repeatedly call its next() method. When this - returns true, all the member variables of the iterator are filled-out with - information describing the menu item. When it returns false, the end of the - list has been reached. - */ - class JUCE_API MenuItemIterator - { - public: - - /** Creates an iterator that will scan through the items in the specified - menu. - - Be careful not to add any items to a menu while it is being iterated, - or things could get out of step. - */ - MenuItemIterator (const PopupMenu& menu) throw(); - - /** Destructor. */ - ~MenuItemIterator() throw(); - - /** Returns true if there is another item, and sets up all this object's - member variables to reflect that item's properties. - */ - bool next() throw(); - - String itemName; - const PopupMenu* subMenu; - int itemId; - bool isSeparator; - bool isTicked; - bool isEnabled; - bool isCustomComponent; - bool isSectionHeader; - const Colour* customColour; - const Image* customImage; - ApplicationCommandManager* commandManager; + MidiMessage message; + PendingMessage* next; juce_UseDebuggingNewOperator - - private: - const PopupMenu& menu; - int index; - - MenuItemIterator (const MenuItemIterator&); - const MenuItemIterator& operator= (const MenuItemIterator&); }; - juce_UseDebuggingNewOperator - -private: - friend class PopupMenuWindow; - friend class MenuItemIterator; - VoidArray items; - LookAndFeel* lookAndFeel; - bool separatorPending; - - void addSeparatorIfPending(); - - int showMenu (const int x, const int y, const int w, const int h, - const int itemIdThatMustBeVisible, - const int minimumWidth, - const int maximumNumColumns, - const int standardItemHeight, - const bool alignToRectangle, - Component* const componentAttachedTo) throw(); - - friend class MenuBarComponent; - Component* createMenuComponent (const int x, const int y, const int w, const int h, - const int itemIdThatMustBeVisible, - const int minimumWidth, - const int maximumNumColumns, - const int standardItemHeight, - const bool alignToRectangle, - Component* menuBarComponent, - ApplicationCommandManager** managerOfChosenCommand, - Component* const componentAttachedTo) throw(); -}; - -#endif // __JUCE_POPUPMENU_JUCEHEADER__ -/********* End of inlined file: juce_PopupMenu.h *********/ - -/** - Manages a list of plugin types. - - This can be easily edited, saved and loaded, and used to create instances of - the plugin types in it. - - @see PluginListComponent -*/ -class JUCE_API KnownPluginList : public ChangeBroadcaster -{ -public: - - /** Creates an empty list. - */ - KnownPluginList(); - - /** Destructor. */ - ~KnownPluginList(); - - /** Clears the list. */ - void clear(); - - /** Returns the number of types currently in the list. - @see getType - */ - int getNumTypes() const throw() { return types.size(); } - - /** Returns one of the types. - @see getNumTypes - */ - PluginDescription* getType (const int index) const throw() { return types [index]; } - - /** Looks for a type in the list which comes from this file. - */ - PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw(); - - /** Looks for a type in the list which matches a plugin type ID. - - The identifierString parameter must have been created by - PluginDescription::createIdentifierString(). - */ - PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw(); - - /** Adds a type manually from its description. */ - bool addType (const PluginDescription& type); - - /** Removes a type. */ - void removeType (const int index) throw(); - - /** Looks for all types that can be loaded from a given file, and adds them - to the list. - - If dontRescanIfAlreadyInList is true, then the file will only be loaded and - re-tested if it's not already in the list, or if the file's modification - time has changed since the list was created. If dontRescanIfAlreadyInList is - false, the file will always be reloaded and tested. - - Returns true if any new types were added, and all the types found in this - file (even if it was already known and hasn't been re-scanned) get returned - in the array. - */ - bool scanAndAddFile (const String& possiblePluginFileOrIdentifier, - const bool dontRescanIfAlreadyInList, - OwnedArray & typesFound, - AudioPluginFormat& formatToUse); - - /** Returns true if the specified file is already known about and if it - hasn't been modified since our entry was created. - */ - bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw(); - - /** Scans and adds a bunch of files that might have been dragged-and-dropped. - - If any types are found in the files, their descriptions are returned in the array. - */ - void scanAndAddDragAndDroppedFiles (const StringArray& filenames, - OwnedArray & typesFound); - - /** Sort methods used to change the order of the plugins in the list. - */ - enum SortMethod - { - defaultOrder = 0, - sortAlphabetically, - sortByCategory, - sortByManufacturer, - sortByFileSystemLocation - }; - - /** Adds all the plugin types to a popup menu so that the user can select one. - - Depending on the sort method, it may add sub-menus for categories, - manufacturers, etc. - - Use getIndexChosenByMenu() to find out the type that was chosen. - */ - void addToMenu (PopupMenu& menu, - const SortMethod sortMethod) const; - - /** Converts a menu item index that has been chosen into its index in this list. - - Returns -1 if it's not an ID that was used. - - @see addToMenu - */ - int getIndexChosenByMenu (const int menuResultCode) const; - - /** Sorts the list. */ - void sort (const SortMethod method); - - /** Creates some XML that can be used to store the state of this list. - */ - XmlElement* createXml() const; - - /** Recreates the state of this list from its stored XML format. - */ - void recreateFromXml (const XmlElement& xml); - - juce_UseDebuggingNewOperator - -private: - OwnedArray types; - - KnownPluginList (const KnownPluginList&); - const KnownPluginList& operator= (const KnownPluginList&); -}; - -#endif // __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ -/********* End of inlined file: juce_KnownPluginList.h *********/ - -/** - A type of AudioProcessor which plays back a graph of other AudioProcessors. - - Use one of these objects if you want to wire-up a set of AudioProcessors - and play back the result. - - Processors can be added to the graph as "nodes" using addNode(), and once - added, you can connect any of their input or output channels to other - nodes using addConnection(). - - To play back a graph through an audio device, you might want to use an - AudioProcessorPlayer object. -*/ -class JUCE_API AudioProcessorGraph : public AudioProcessor, - public AsyncUpdater -{ -public: - - /** Creates an empty graph. - */ - AudioProcessorGraph(); - - /** Destructor. - - Any processor objects that have been added to the graph will also be deleted. - */ - ~AudioProcessorGraph(); - - /** Represents one of the nodes, or processors, in an AudioProcessorGraph. - - To create a node, call AudioProcessorGraph::addNode(). - */ - class JUCE_API Node : public ReferenceCountedObject - { - public: - /** Destructor. - */ - ~Node(); - - /** The ID number assigned to this node. - - This is assigned by the graph that owns it, and can't be changed. - */ - const uint32 id; - - /** The actual processor object that this node represents. - */ - AudioProcessor* const processor; - - /** A set of user-definable properties that are associated with this node. - - This can be used to attach values to the node for whatever purpose seems - useful. For example, you might store an x and y position if your application - is displaying the nodes on-screen. - */ - PropertySet properties; - - /** A convenient typedef for referring to a pointer to a node object. - */ - typedef ReferenceCountedObjectPtr Ptr; - - juce_UseDebuggingNewOperator - - private: - friend class AudioProcessorGraph; - - bool isPrepared; - - Node (const uint32 id, AudioProcessor* const processor) throw(); - - void prepare (const double sampleRate, const int blockSize, AudioProcessorGraph* const graph); - void unprepare(); - - Node (const Node&); - const Node& operator= (const Node&); - }; - - /** Represents a connection between two channels of two nodes in an AudioProcessorGraph. - - To create a connection, use AudioProcessorGraph::addConnection(). - */ - struct JUCE_API Connection - { - public: - - /** The ID number of the node which is the input source for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 sourceNodeId; - - /** The index of the output channel of the source node from which this - connection takes its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the source node's midi output. Otherwise, it is the zero-based - index of an audio output channel in the source node. - */ - int sourceChannelIndex; - - /** The ID number of the node which is the destination for this connection. - @see AudioProcessorGraph::getNodeForId - */ - uint32 destNodeId; - - /** The index of the input channel of the destination node to which this - connection delivers its data. - - If this value is the special number AudioProcessorGraph::midiChannelIndex, then - it is referring to the destination node's midi input. Otherwise, it is the zero-based - index of an audio input channel in the destination node. - */ - int destChannelIndex; - - juce_UseDebuggingNewOperator - - private: - }; - - /** Deletes all nodes and connections from this graph. - - Any processor objects in the graph will be deleted. - */ - void clear(); - - /** Returns the number of nodes in the graph. */ - int getNumNodes() const throw() { return nodes.size(); } - - /** Returns a pointer to one of the nodes in the graph. - - This will return 0 if the index is out of range. - @see getNodeForId - */ - Node* getNode (const int index) const throw() { return nodes [index]; } - - /** Searches the graph for a node with the given ID number and returns it. - - If no such node was found, this returns 0. - @see getNode - */ - Node* getNodeForId (const uint32 nodeId) const throw(); - - /** Adds a node to the graph. - - This creates a new node in the graph, for the specified processor. Once you have - added a processor to the graph, the graph owns it and will delete it later when - it is no longer needed. - - The optional nodeId parameter lets you specify an ID to use for the node, but - if the value is already in use, this new node will overwrite the old one. - - If this succeeds, it returns a pointer to the newly-created node. - */ - Node* addNode (AudioProcessor* const newProcessor, - uint32 nodeId = 0); - - /** Deletes a node within the graph which has the specified ID. - - This will also delete any connections that are attached to this node. - */ - bool removeNode (const uint32 nodeId); - - /** Returns the number of connections in the graph. */ - int getNumConnections() const throw() { return connections.size(); } - - /** Returns a pointer to one of the connections in the graph. */ - const Connection* getConnection (const int index) const throw() { return connections [index]; } - - /** Searches for a connection between some specified channels. - - If no such connection is found, this returns 0. - */ - const Connection* getConnectionBetween (const uint32 sourceNodeId, - const int sourceChannelIndex, - const uint32 destNodeId, - const int destChannelIndex) const throw(); - - /** Returns true if there is a connection between any of the channels of - two specified nodes. - */ - bool isConnected (const uint32 possibleSourceNodeId, - const uint32 possibleDestNodeId) const throw(); - - /** Returns true if it would be legal to connect the specified points. - */ - bool canConnect (const uint32 sourceNodeId, const int sourceChannelIndex, - const uint32 destNodeId, const int destChannelIndex) const throw(); - - /** Attempts to connect two specified channels of two nodes. - - If this isn't allowed (e.g. because you're trying to connect a midi channel - to an audio one or other such nonsense), then it'll return false. - */ - bool addConnection (const uint32 sourceNodeId, const int sourceChannelIndex, - const uint32 destNodeId, const int destChannelIndex); - - /** Deletes the connection with the specified index. - - Returns true if a connection was actually deleted. - */ - void removeConnection (const int index); - - /** Deletes any connection between two specified points. - - Returns true if a connection was actually deleted. - */ - bool removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex, - const uint32 destNodeId, const int destChannelIndex); - - /** Removes all connections from the specified node. - */ - bool disconnectNode (const uint32 nodeId); - - /** Performs a sanity checks of all the connections. - - This might be useful if some of the processors are doing things like changing - their channel counts, which could render some connections obsolete. - */ - bool removeIllegalConnections(); - - /** A special number that represents the midi channel of a node. - - This is used as a channel index value if you want to refer to the midi input - or output instead of an audio channel. - */ - static const int midiChannelIndex; - - /** A special type of AudioProcessor that can live inside an AudioProcessorGraph - in order to use the audio that comes into and out of the graph itself. - - If you create an AudioGraphIOProcessor in "input" mode, it will act as a - node in the graph which delivers the audio that is coming into the parent - graph. This allows you to stream the data to other nodes and process the - incoming audio. - - Likewise, one of these in "output" mode can be sent data which it will add to - the sum of data being sent to the graph's output. - - @see AudioProcessorGraph - */ - class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance - { - public: - /** Specifies the mode in which this processor will operate. - */ - enum IODeviceType - { - audioInputNode, /**< In this mode, the processor has output channels - representing all the audio input channels that are - coming into its parent audio graph. */ - audioOutputNode, /**< In this mode, the processor has input channels - representing all the audio output channels that are - going out of its parent audio graph. */ - midiInputNode, /**< In this mode, the processor has a midi output which - delivers the same midi data that is arriving at its - parent graph. */ - midiOutputNode /**< In this mode, the processor has a midi input and - any data sent to it will be passed out of the parent - graph. */ - }; - - /** Returns the mode of this processor. */ - IODeviceType getType() const throw() { return type; } - - /** Returns the parent graph to which this processor belongs, or 0 if it - hasn't yet been added to one. */ - AudioProcessorGraph* getParentGraph() const throw() { return graph; } - - /** True if this is an audio or midi input. */ - bool isInput() const throw(); - /** True if this is an audio or midi output. */ - bool isOutput() const throw(); - - AudioGraphIOProcessor (const IODeviceType type); - ~AudioGraphIOProcessor(); - - const String getName() const; - void fillInPluginDescription (PluginDescription& d) const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); - - const String getInputChannelName (const int channelIndex) const; - const String getOutputChannelName (const int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - bool acceptsMidi() const; - bool producesMidi() const; - - AudioProcessorEditor* createEditor(); - - int getNumParameters(); - const String getParameterName (int); - float getParameter (int); - const String getParameterText (int); - void setParameter (int, float); - - int getNumPrograms(); - int getCurrentProgram(); - void setCurrentProgram (int); - const String getProgramName (int); - void changeProgramName (int, const String&); - - void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); - void setStateInformation (const void* data, int sizeInBytes); - - /** @internal */ - void setParentGraph (AudioProcessorGraph* const graph) throw(); - - juce_UseDebuggingNewOperator - - private: - const IODeviceType type; - AudioProcessorGraph* graph; - - AudioGraphIOProcessor (const AudioGraphIOProcessor&); - const AudioGraphIOProcessor& operator= (const AudioGraphIOProcessor&); - }; - - // AudioProcessor methods: - - const String getName() const; - - void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); - void releaseResources(); - void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); - - const String getInputChannelName (const int channelIndex) const; - const String getOutputChannelName (const int channelIndex) const; - bool isInputChannelStereoPair (int index) const; - bool isOutputChannelStereoPair (int index) const; - - bool acceptsMidi() const; - bool producesMidi() const; - - AudioProcessorEditor* createEditor() { return 0; } - - int getNumParameters() { return 0; } - const String getParameterName (int) { return String::empty; } - float getParameter (int) { return 0; } - const String getParameterText (int) { return String::empty; } - void setParameter (int, float) { } - - int getNumPrograms() { return 0; } - int getCurrentProgram() { return 0; } - void setCurrentProgram (int) { } - const String getProgramName (int) { return String::empty; } - void changeProgramName (int, const String&) { } - - void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); - void setStateInformation (const void* data, int sizeInBytes); - - /** @internal */ - void handleAsyncUpdate(); - - juce_UseDebuggingNewOperator - -private: - ReferenceCountedArray nodes; - OwnedArray connections; - int lastNodeId; - AudioSampleBuffer renderingBuffers; - OwnedArray midiBuffers; - - CriticalSection renderLock; - VoidArray renderingOps; - - friend class AudioGraphIOProcessor; - AudioSampleBuffer* currentAudioInputBuffer; - AudioSampleBuffer currentAudioOutputBuffer; - MidiBuffer* currentMidiInputBuffer; - MidiBuffer currentMidiOutputBuffer; - - void clearRenderingSequence(); - void buildRenderingSequence(); - - bool isAnInputTo (const uint32 possibleInputId, - const uint32 possibleDestinationId, - const int recursionCheck) const throw(); - - AudioProcessorGraph (const AudioProcessorGraph&); - const AudioProcessorGraph& operator= (const AudioProcessorGraph&); -}; - -#endif // __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ -/********* End of inlined file: juce_AudioProcessorGraph.h *********/ - -#endif -#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioProcessorPlayer.h *********/ -#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ -#define __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioIODevice.h *********/ -#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__ -#define __JUCE_AUDIOIODEVICE_JUCEHEADER__ - -class AudioIODevice; - -/** - One of these is passed to an AudioIODevice object to stream the audio data - in and out. - - The AudioIODevice will repeatedly call this class's audioDeviceIOCallback() - method on its own high-priority audio thread, when it needs to send or receive - the next block of data. - - @see AudioIODevice, AudioDeviceManager -*/ -class JUCE_API AudioIODeviceCallback -{ -public: - /** Destructor. */ - virtual ~AudioIODeviceCallback() {} - - /** Processes a block of incoming and outgoing audio data. - - The subclass's implementation should use the incoming audio for whatever - purposes it needs to, and must fill all the output channels with the next - block of output data before returning. - - The channel data is arranged with the same array indices as the channel name - array returned by AudioIODevice::getOutputChannelNames(), but those channels - that aren't specified in AudioIODevice::open() will have a null pointer for their - associated channel, so remember to check for this. - - @param inputChannelData a set of arrays containing the audio data for each - incoming channel - this data is valid until the function - returns. There will be one channel of data for each input - channel that was enabled when the audio device was opened - (see AudioIODevice::open()) - @param numInputChannels the number of pointers to channel data in the - inputChannelData array. - @param outputChannelData a set of arrays which need to be filled with the data - that should be sent to each outgoing channel of the device. - There will be one channel of data for each output channel - that was enabled when the audio device was opened (see - AudioIODevice::open()) - The initial contents of the array is undefined, so the - callback function must fill all the channels with zeros if - its output is silence. Failing to do this could cause quite - an unpleasant noise! - @param numOutputChannels the number of pointers to channel data in the - outputChannelData array. - @param numSamples the number of samples in each channel of the input and - output arrays. The number of samples will depend on the - audio device's buffer size and will usually remain constant, - although this isn't guaranteed, so make sure your code can - cope with reasonable changes in the buffer size from one - callback to the next. - */ - virtual void audioDeviceIOCallback (const float** inputChannelData, - int numInputChannels, - float** outputChannelData, - int numOutputChannels, - int numSamples) = 0; - - /** Called to indicate that the device is about to start calling back. - - This will be called just before the audio callbacks begin, either when this - callback has just been added to an audio device, or after the device has been - restarted because of a sample-rate or block-size change. - - You can use this opportunity to find out the sample rate and block size - that the device is going to use by calling the AudioIODevice::getCurrentSampleRate() - and AudioIODevice::getCurrentBufferSizeSamples() on the supplied pointer. - - @param device the audio IO device that will be used to drive the callback. - Note that if you're going to store this this pointer, it is - only valid until the next time that audioDeviceStopped is called. - */ - virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; - - /** Called to indicate that the device has stopped. - */ - virtual void audioDeviceStopped() = 0; -}; - -/** - Base class for an audio device with synchronised input and output channels. - - Subclasses of this are used to implement different protocols such as DirectSound, - ASIO, CoreAudio, etc. - - To create one of these, you'll need to use the AudioIODeviceType class - see the - documentation for that class for more info. - - For an easier way of managing audio devices and their settings, have a look at the - AudioDeviceManager class. - - @see AudioIODeviceType, AudioDeviceManager -*/ -class JUCE_API AudioIODevice -{ -public: - /** Destructor. */ - virtual ~AudioIODevice(); - - /** Returns the device's name, (as set in the constructor). */ - const String& getName() const throw() { return name; } - - /** Returns the type of the device. - - E.g. "CoreAudio", "ASIO", etc. - this comes from the AudioIODeviceType that created it. - */ - const String& getTypeName() const throw() { return typeName; } - - /** Returns the names of all the available output channels on this device. - To find out which of these are currently in use, call getActiveOutputChannels(). - */ - virtual const StringArray getOutputChannelNames() = 0; - - /** Returns the names of all the available input channels on this device. - To find out which of these are currently in use, call getActiveInputChannels(). - */ - virtual const StringArray getInputChannelNames() = 0; - - /** Returns the number of sample-rates this device supports. - - To find out which rates are available on this device, use this method to - find out how many there are, and getSampleRate() to get the rates. - - @see getSampleRate - */ - virtual int getNumSampleRates() = 0; - - /** Returns one of the sample-rates this device supports. - - To find out which rates are available on this device, use getNumSampleRates() to - find out how many there are, and getSampleRate() to get the individual rates. - - The sample rate is set by the open() method. - - (Note that for DirectSound some rates might not work, depending on combinations - of i/o channels that are being opened). - - @see getNumSampleRates - */ - virtual double getSampleRate (int index) = 0; - - /** Returns the number of sizes of buffer that are available. - - @see getBufferSizeSamples, getDefaultBufferSize - */ - virtual int getNumBufferSizesAvailable() = 0; - - /** Returns one of the possible buffer-sizes. - - @param index the index of the buffer-size to use, from 0 to getNumBufferSizesAvailable() - 1 - @returns a number of samples - @see getNumBufferSizesAvailable, getDefaultBufferSize - */ - virtual int getBufferSizeSamples (int index) = 0; - - /** Returns the default buffer-size to use. - - @returns a number of samples - @see getNumBufferSizesAvailable, getBufferSizeSamples - */ - virtual int getDefaultBufferSize() = 0; - - /** Tries to open the device ready to play. - - @param inputChannels a BitArray in which a set bit indicates that the corresponding - input channel should be enabled - @param outputChannels a BitArray in which a set bit indicates that the corresponding - output channel should be enabled - @param sampleRate the sample rate to try to use - to find out which rates are - available, see getNumSampleRates() and getSampleRate() - @param bufferSizeSamples the size of i/o buffer to use - to find out the available buffer - sizes, see getNumBufferSizesAvailable() and getBufferSizeSamples() - @returns an error description if there's a problem, or an empty string if it succeeds in - opening the device - @see close - */ - virtual const String open (const BitArray& inputChannels, - const BitArray& outputChannels, - double sampleRate, - int bufferSizeSamples) = 0; - - /** Closes and releases the device if it's open. */ - virtual void close() = 0; - - /** Returns true if the device is still open. - - A device might spontaneously close itself if something goes wrong, so this checks if - it's still open. - */ - virtual bool isOpen() = 0; - - /** Starts the device actually playing. - - This must be called after the device has been opened. - - @param callback the callback to use for streaming the data. - @see AudioIODeviceCallback, open - */ - virtual void start (AudioIODeviceCallback* callback) = 0; - - /** Stops the device playing. - - Once a device has been started, this will stop it. Any pending calls to the - callback class will be flushed before this method returns. - */ - virtual void stop() = 0; - - /** Returns true if the device is still calling back. - - The device might mysteriously stop, so this checks whether it's - still playing. - */ - virtual bool isPlaying() = 0; - - /** Returns the last error that happened if anything went wrong. */ - virtual const String getLastError() = 0; - - /** Returns the buffer size that the device is currently using. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual int getCurrentBufferSizeSamples() = 0; - - /** Returns the sample rate that the device is currently using. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual double getCurrentSampleRate() = 0; - - /** Returns the device's current physical bit-depth. - - If the device isn't actually open, this value doesn't really mean much. - */ - virtual int getCurrentBitDepth() = 0; - - /** Returns a mask showing which of the available output channels are currently - enabled. - @see getOutputChannelNames - */ - virtual const BitArray getActiveOutputChannels() const = 0; - - /** Returns a mask showing which of the available input channels are currently - enabled. - @see getInputChannelNames - */ - virtual const BitArray getActiveInputChannels() const = 0; - - /** Returns the device's output latency. - - This is the delay in samples between a callback getting a block of data, and - that data actually getting played. - */ - virtual int getOutputLatencyInSamples() = 0; - - /** Returns the device's input latency. - - This is the delay in samples between some audio actually arriving at the soundcard, - and the callback getting passed this block of data. - */ - virtual int getInputLatencyInSamples() = 0; - - /** True if this device can show a pop-up control panel for editing its settings. - - This is generally just true of ASIO devices. If true, you can call showControlPanel() - to display it. - */ - virtual bool hasControlPanel() const; - - /** Shows a device-specific control panel if there is one. - - This should only be called for devices which return true from hasControlPanel(). - */ - virtual bool showControlPanel(); - -protected: - /** Creates a device, setting its name and type member variables. */ - AudioIODevice (const String& deviceName, - const String& typeName); - - /** @internal */ - String name, typeName; -}; - -#endif // __JUCE_AUDIOIODEVICE_JUCEHEADER__ -/********* End of inlined file: juce_AudioIODevice.h *********/ - -/** - An AudioIODeviceCallback object which streams audio through an AudioProcessor. - - To use one of these, just make it the callback used by your AudioIODevice, and - give it a processor to use by calling setProcessor(). - - It's also a MidiInputCallback, so you can connect it to both an audio and midi - input to send both streams through the processor. - - @see AudioProcessor, AudioProcessorGraph -*/ -class JUCE_API AudioProcessorPlayer : public AudioIODeviceCallback, - public MidiInputCallback -{ -public: - - /** - */ - AudioProcessorPlayer(); - - /** Destructor. */ - virtual ~AudioProcessorPlayer(); - - /** Sets the processor that should be played. - - The processor that is passed in will not be deleted or owned by this object. - To stop anything playing, pass in 0 to this method. - */ - void setProcessor (AudioProcessor* const processorToPlay); - - /** Returns the current audio processor that is being played. - */ - AudioProcessor* getCurrentProcessor() const throw() { return processor; } - - /** Returns a midi message collector that you can pass midi messages to if you - want them to be injected into the midi stream that is being sent to the - processor. - */ - MidiMessageCollector& getMidiMessageCollector() throw() { return messageCollector; } - - /** @internal */ - void audioDeviceIOCallback (const float** inputChannelData, - int totalNumInputChannels, - float** outputChannelData, - int totalNumOutputChannels, - int numSamples); - /** @internal */ - void audioDeviceAboutToStart (AudioIODevice* device); - /** @internal */ - void audioDeviceStopped(); - /** @internal */ - void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); - - juce_UseDebuggingNewOperator - -private: - AudioProcessor* processor; CriticalSection lock; - double sampleRate; - int blockSize; - bool isPrepared; + PendingMessage* firstMessage; - int numInputChans, numOutputChans; - float* channels [128]; - AudioSampleBuffer tempBuffer; + MidiOutput() throw(); + MidiOutput (const MidiOutput&); - MidiBuffer incomingMidi; - MidiMessageCollector messageCollector; - - AudioProcessorPlayer (const AudioProcessorPlayer&); - const AudioProcessorPlayer& operator= (const AudioProcessorPlayer&); + void run(); }; -#endif // __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ -/********* End of inlined file: juce_AudioProcessorPlayer.h *********/ +#endif // __JUCE_MIDIOUTPUT_JUCEHEADER__ +/********* End of inlined file: juce_MidiOutput.h *********/ -#endif -#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ +/********* Start of inlined file: juce_ComboBox.h *********/ +#ifndef __JUCE_COMBOBOX_JUCEHEADER__ +#define __JUCE_COMBOBOX_JUCEHEADER__ -/********* Start of inlined file: juce_GenericAudioProcessorEditor.h *********/ -#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ -#define __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ +/********* Start of inlined file: juce_Label.h *********/ +#ifndef __JUCE_LABEL_JUCEHEADER__ +#define __JUCE_LABEL_JUCEHEADER__ -/********* Start of inlined file: juce_PropertyPanel.h *********/ -#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ -#define __JUCE_PROPERTYPANEL_JUCEHEADER__ +/********* Start of inlined file: juce_ComponentDeletionWatcher.h *********/ +#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ +#define __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ -/********* Start of inlined file: juce_PropertyComponent.h *********/ -#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ +/** + Object for monitoring a component, and later testing whether it's still valid. -class EditableProperty; + Slightly obscure, this one, but it's used internally for making sure that + after some callbacks, a component hasn't been deleted. It's more reliable than + just using isValidComponent(), which can provide false-positives if a new + component is created at the same memory location as an old one. +*/ +class JUCE_API ComponentDeletionWatcher +{ +public: + + /** Creates a watcher for a given component. + + The component must be valid at the time it's passed in. + */ + ComponentDeletionWatcher (const Component* const componentToWatch) throw(); + + /** Destructor. */ + ~ComponentDeletionWatcher() throw(); + + /** Returns true if the component has been deleted since the time that this + object was created. + */ + bool hasBeenDeleted() const throw(); + + /** Returns the component that's being watched, or null if it has been deleted. */ + const Component* getComponent() const throw(); + + juce_UseDebuggingNewOperator + +private: + const Component* const componentToWatch; + const uint32 componentUID; + + ComponentDeletionWatcher (const ComponentDeletionWatcher&); + const ComponentDeletionWatcher& operator= (const ComponentDeletionWatcher&); +}; + +#endif // __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ +/********* End of inlined file: juce_ComponentDeletionWatcher.h *********/ + +/********* Start of inlined file: juce_TextEditor.h *********/ +#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ +#define __JUCE_TEXTEDITOR_JUCEHEADER__ + +/********* Start of inlined file: juce_Viewport.h *********/ +#ifndef __JUCE_VIEWPORT_JUCEHEADER__ +#define __JUCE_VIEWPORT_JUCEHEADER__ + +/********* Start of inlined file: juce_ScrollBar.h *********/ +#ifndef __JUCE_SCROLLBAR_JUCEHEADER__ +#define __JUCE_SCROLLBAR_JUCEHEADER__ + +/********* Start of inlined file: juce_Button.h *********/ +#ifndef __JUCE_BUTTON_JUCEHEADER__ +#define __JUCE_BUTTON_JUCEHEADER__ + +/********* Start of inlined file: juce_TooltipWindow.h *********/ +#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ +#define __JUCE_TOOLTIPWINDOW_JUCEHEADER__ /********* Start of inlined file: juce_TooltipClient.h *********/ #ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ @@ -31249,106 +31389,6 @@ protected: #endif // __JUCE_TOOLTIPCLIENT_JUCEHEADER__ /********* End of inlined file: juce_TooltipClient.h *********/ -/** - A base class for a component that goes in a PropertyPanel and displays one of - an item's properties. - - Subclasses of this are used to display a property in various forms, e.g. a - ChoicePropertyComponent shows its value as a combo box; a SliderPropertyComponent - shows its value as a slider; a TextPropertyComponent as a text box, etc. - - A subclass must implement the refresh() method which will be called to tell the - component to update itself, and is also responsible for calling this it when the - item that it refers to is changed. - - @see PropertyPanel, TextPropertyComponent, SliderPropertyComponent, - ChoicePropertyComponent, ButtonPropertyComponent, BooleanPropertyComponent -*/ -class JUCE_API PropertyComponent : public Component, - public SettableTooltipClient -{ -public: - - /** Creates a PropertyComponent. - - @param propertyName the name is stored as this component's name, and is - used as the name displayed next to this component in - a property panel - @param preferredHeight the height that the component should be given - some - items may need to be larger than a normal row height. - This value can also be set if a subclass changes the - preferredHeight member variable. - */ - PropertyComponent (const String& propertyName, - const int preferredHeight = 25); - - /** Destructor. */ - ~PropertyComponent(); - - /** Returns this item's preferred height. - - This value is specified either in the constructor or by a subclass changing the - preferredHeight member variable. - */ - int getPreferredHeight() const throw() { return preferredHeight; } - - /** Updates the property component if the item it refers to has changed. - - A subclass must implement this method, and other objects may call it to - force it to refresh itself. - - The subclass should be economical in the amount of work is done, so for - example it should check whether it really needs to do a repaint rather than - just doing one every time this method is called, as it may be called when - the value being displayed hasn't actually changed. - */ - virtual void refresh() = 0; - - /** The default paint method fills the background and draws a label for the - item's name. - - @see LookAndFeel::drawPropertyComponentBackground(), LookAndFeel::drawPropertyComponentLabel() - */ - void paint (Graphics& g); - - /** The default resize method positions any child component to the right of this - one, based on the look and feel's default label size. - */ - void resized(); - - /** By default, this just repaints the component. */ - void enablementChanged(); - - juce_UseDebuggingNewOperator - -protected: - /** Used by the PropertyPanel to determine how high this component needs to be. - - A subclass can update this value in its constructor but shouldn't alter it later - as changes won't necessarily be picked up. - */ - int preferredHeight; -}; - -#endif // __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_PropertyComponent.h *********/ - -/********* Start of inlined file: juce_Viewport.h *********/ -#ifndef __JUCE_VIEWPORT_JUCEHEADER__ -#define __JUCE_VIEWPORT_JUCEHEADER__ - -/********* Start of inlined file: juce_ScrollBar.h *********/ -#ifndef __JUCE_SCROLLBAR_JUCEHEADER__ -#define __JUCE_SCROLLBAR_JUCEHEADER__ - -/********* Start of inlined file: juce_Button.h *********/ -#ifndef __JUCE_BUTTON_JUCEHEADER__ -#define __JUCE_BUTTON_JUCEHEADER__ - -/********* Start of inlined file: juce_TooltipWindow.h *********/ -#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ -#define __JUCE_TOOLTIPWINDOW_JUCEHEADER__ - /** A window that displays a pop-up tooltip when the mouse hovers over another component. @@ -32365,1640 +32405,434 @@ private: #endif // __JUCE_VIEWPORT_JUCEHEADER__ /********* End of inlined file: juce_Viewport.h *********/ -/** - A panel that holds a list of PropertyComponent objects. +/********* Start of inlined file: juce_PopupMenu.h *********/ +#ifndef __JUCE_POPUPMENU_JUCEHEADER__ +#define __JUCE_POPUPMENU_JUCEHEADER__ - This panel displays a list of PropertyComponents, and allows them to be organised - into collapsible sections. +/********* Start of inlined file: juce_PopupMenuCustomComponent.h *********/ +#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ +#define __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ - To use, simply create one of these and add your properties to it with addProperties() - or addSection(). +/** A user-defined copmonent that can appear inside one of the rows of a popup menu. - @see PropertyComponent + @see PopupMenu::addCustomItem */ -class JUCE_API PropertyPanel : public Component +class JUCE_API PopupMenuCustomComponent : public Component { public: - - /** Creates an empty property panel. */ - PropertyPanel(); - /** Destructor. */ - ~PropertyPanel(); + ~PopupMenuCustomComponent(); - /** Deletes all property components from the panel. + /** Chooses the size that this component would like to have. + + Note that the size which this method returns isn't necessarily the one that + the menu will give it, as it will be stretched to fit the other items in + the menu. */ - void clear(); + virtual void getIdealSize (int& idealWidth, + int& idealHeight) = 0; - /** Adds a set of properties to the panel. + /** Dismisses the menu indicating that this item has been chosen. - The components in the list will be owned by this object and will be automatically - deleted later on when no longer needed. - - These properties are added without them being inside a named section. If you - want them to be kept together in a collapsible section, use addSection() instead. + This will cause the menu to exit from its modal state, returning + this item's id as the result. */ - void addProperties (const Array & newPropertyComponents); + void triggerMenuItem(); - /** Adds a set of properties to the panel. + /** Returns true if this item should be highlighted because the mouse is + over it. - These properties are added at the bottom of the list, under a section heading with - a plus/minus button that allows it to be opened and closed. - - The components in the list will be owned by this object and will be automatically - deleted later on when no longer needed. - - To add properies without them being in a section, use addProperties(). + You can call this method in your paint() method to find out whether + to draw a highlight. */ - void addSection (const String& sectionTitle, - const Array & newPropertyComponents, - const bool shouldSectionInitiallyBeOpen = true); + bool isItemHighlighted() const throw() { return isHighlighted; } - /** Calls the refresh() method of all PropertyComponents in the panel */ - void refreshAll() const; - - /** Returns a list of all the names of sections in the panel. - - These are the sections that have been added with addSection(). - */ - const StringArray getSectionNames() const; - - /** Returns true if the section at this index is currently open. - - The index is from 0 up to the number of items returned by getSectionNames(). - */ - bool isSectionOpen (const int sectionIndex) const; - - /** Opens or closes one of the sections. - - The index is from 0 up to the number of items returned by getSectionNames(). - */ - void setSectionOpen (const int sectionIndex, const bool shouldBeOpen); - - /** Enables or disables one of the sections. - - The index is from 0 up to the number of items returned by getSectionNames(). - */ - void setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled); - - /** Saves the current state of open/closed sections so it can be restored later. - - The caller is responsible for deleting the object that is returned. - - To restore this state, use restoreOpennessState(). - - @see restoreOpennessState - */ - XmlElement* getOpennessState() const; - - /** Restores a previously saved arrangement of open/closed sections. - - This will try to restore a snapshot of the panel's state that was created by - the getOpennessState() method. If any of the sections named in the original - XML aren't present, they will be ignored. - - @see getOpennessState - */ - void restoreOpennessState (const XmlElement& newState); - - /** Sets a message to be displayed when there are no properties in the panel. - - The default message is "nothing selected". - */ - void setMessageWhenEmpty (const String& newMessage); - - /** Returns the message that is displayed when there are no properties. - @see setMessageWhenEmpty - */ - const String& getMessageWhenEmpty() const throw(); - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - - juce_UseDebuggingNewOperator - -private: - Viewport* viewport; - Component* propertyHolderComponent; - String messageWhenEmpty; - - void updatePropHolderLayout() const; - void updatePropHolderLayout (const int width) const; -}; - -#endif // __JUCE_PROPERTYPANEL_JUCEHEADER__ -/********* End of inlined file: juce_PropertyPanel.h *********/ - -/** - A type of UI component that displays the parameters of an AudioProcessor as - a simple list of sliders. - - This can be used for showing an editor for a processor that doesn't supply - its own custom editor. - - @see AudioProcessor -*/ -class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor -{ -public: - - GenericAudioProcessorEditor (AudioProcessor* const owner); - ~GenericAudioProcessorEditor(); - - void paint (Graphics& g); - void resized(); - - juce_UseDebuggingNewOperator - -private: - PropertyPanel* panel; -}; - -#endif // __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ -/********* End of inlined file: juce_GenericAudioProcessorEditor.h *********/ - -#endif -#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioFormatReaderSource.h *********/ -#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ -#define __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_PositionableAudioSource.h *********/ -#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioSource.h *********/ -#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__ -#define __JUCE_AUDIOSOURCE_JUCEHEADER__ - -/** - Used by AudioSource::getNextAudioBlock(). -*/ -struct JUCE_API AudioSourceChannelInfo -{ - /** The destination buffer to fill with audio data. - - When the AudioSource::getNextAudioBlock() method is called, the active section - of this buffer should be filled with whatever output the source produces. - - Only the samples specified by the startSample and numSamples members of this structure - should be affected by the call. - - The contents of the buffer when it is passed to the the AudioSource::getNextAudioBlock() - method can be treated as the input if the source is performing some kind of filter operation, - but should be cleared if this is not the case - the clearActiveBufferRegion() is - a handy way of doing this. - - The number of channels in the buffer could be anything, so the AudioSource - must cope with this in whatever way is appropriate for its function. - */ - AudioSampleBuffer* buffer; - - /** The first sample in the buffer from which the callback is expected - to write data. */ - int startSample; - - /** The number of samples in the buffer which the callback is expected to - fill with data. */ - int numSamples; - - /** Convenient method to clear the buffer if the source is not producing any data. */ - void clearActiveBufferRegion() const - { - if (buffer != 0) - buffer->clear (startSample, numSamples); - } -}; - -/** - Base class for objects that can produce a continuous stream of audio. - - @see AudioFormatReaderSource, ResamplingAudioSource -*/ -class JUCE_API AudioSource -{ protected: + /** Constructor. - /** Creates an AudioSource. */ - AudioSource() throw() {} - -public: - /** Destructor. */ - virtual ~AudioSource() {} - - /** Tells the source to prepare for playing. - - The source can use this opportunity to initialise anything it needs to. - - Note that this method could be called more than once in succession without - a matching call to releaseResources(), so make sure your code is robust and - can handle that kind of situation. - - @param samplesPerBlockExpected the number of samples that the source - will be expected to supply each time its - getNextAudioBlock() method is called. This - number may vary slightly, because it will be dependent - on audio hardware callbacks, and these aren't - guaranteed to always use a constant block size, so - the source should be able to cope with small variations. - @param sampleRate the sample rate that the output will be used at - this - is needed by sources such as tone generators. - @see releaseResources, getNextAudioBlock + If isTriggeredAutomatically is true, then the menu will automatically detect + a click on this component and use that to trigger it. If it's false, then it's + up to your class to manually trigger the item if it wants to. */ - virtual void prepareToPlay (int samplesPerBlockExpected, - double sampleRate) = 0; - - /** Allows the source to release anything it no longer needs after playback has stopped. - - This will be called when the source is no longer going to have its getNextAudioBlock() - method called, so it should release any spare memory, etc. that it might have - allocated during the prepareToPlay() call. - - Note that there's no guarantee that prepareToPlay() will actually have been called before - releaseResources(), and it may be called more than once in succession, so make sure your - code is robust and doesn't make any assumptions about when it will be called. - - @see prepareToPlay, getNextAudioBlock - */ - virtual void releaseResources() = 0; - - /** Called repeatedly to fetch subsequent blocks of audio data. - - After calling the prepareToPlay() method, this callback will be made each - time the audio playback hardware (or whatever other destination the audio - data is going to) needs another block of data. - - It will generally be called on a high-priority system thread, or possibly even - an interrupt, so be careful not to do too much work here, as that will cause - audio glitches! - - @see AudioSourceChannelInfo, prepareToPlay, releaseResources - */ - virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0; -}; - -#endif // __JUCE_AUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_AudioSource.h *********/ - -/** - A type of AudioSource which can be repositioned. - - The basic AudioSource just streams continuously with no idea of a current - time or length, so the PositionableAudioSource is used for a finite stream - that has a current read position. - - @see AudioSource, AudioTransportSource -*/ -class JUCE_API PositionableAudioSource : public AudioSource -{ -protected: - - /** Creates the PositionableAudioSource. */ - PositionableAudioSource() throw() {} - -public: - /** Destructor */ - ~PositionableAudioSource() {} - - /** Tells the stream to move to a new position. - - Calling this indicates that the next call to AudioSource::getNextAudioBlock() - should return samples from this position. - - Note that this may be called on a different thread to getNextAudioBlock(), - so the subclass should make sure it's synchronised. - */ - virtual void setNextReadPosition (int newPosition) = 0; - - /** Returns the position from which the next block will be returned. - - @see setNextReadPosition - */ - virtual int getNextReadPosition() const = 0; - - /** Returns the total length of the stream (in samples). */ - virtual int getTotalLength() const = 0; - - /** Returns true if this source is actually playing in a loop. */ - virtual bool isLooping() const = 0; -}; - -#endif // __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_PositionableAudioSource.h *********/ - -/********* Start of inlined file: juce_AudioFormatReader.h *********/ -#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ -#define __JUCE_AUDIOFORMATREADER_JUCEHEADER__ - -class AudioFormat; - -/** - Reads samples from an audio file stream. - - A subclass that reads a specific type of audio format will be created by - an AudioFormat object. - - @see AudioFormat, AudioFormatWriter -*/ -class JUCE_API AudioFormatReader -{ -protected: - - /** Creates an AudioFormatReader object. - - @param sourceStream the stream to read from - this will be deleted - by this object when it is no longer needed. (Some - specialised readers might not use this parameter and - can leave it as 0). - @param formatName the description that will be returned by the getFormatName() - method - */ - AudioFormatReader (InputStream* const sourceStream, - const String& formatName); - -public: - /** Destructor. */ - virtual ~AudioFormatReader(); - - /** Returns a description of what type of format this is. - - E.g. "AIFF" - */ - const String getFormatName() const throw() { return formatName; } - - /** Reads samples from the stream. - - @param destSamples an array of buffers into which the sample data for each - channel will be written. - If the format is fixed-point, each channel will be written - as an array of 32-bit signed integers using the full - range -0x80000000 to 0x7fffffff, regardless of the source's - bit-depth. If it is a floating-point format, you should cast - the resulting array to a (float**) to get the values (in the - range -1.0 to 1.0 or beyond) - If the format is stereo, then destSamples[0] is the left channel - data, and destSamples[1] is the right channel. - The numDestChannels parameter indicates how many pointers this array - contains, but some of these pointers can be null if you don't want to - read data for some of the channels - @param numDestChannels the number of array elements in the destChannels array - @param startSampleInSource the position in the audio file or stream at which the samples - should be read, as a number of samples from the start of the - stream. It's ok for this to be beyond the start or end of the - available data - any samples that are out-of-range will be returned - as zeros. - @param numSamplesToRead the number of samples to read. If this is greater than the number - of samples that the file or stream contains. the result will be padded - with zeros - @param fillLeftoverChannelsWithCopies if true, this indicates that if there's no source data available - for some of the channels that you pass in, then they should be filled with - copies of valid source channels. - E.g. if you're reading a mono file and you pass 2 channels to this method, then - if fillLeftoverChannelsWithCopies is true, both destination channels will be filled - with the same data from the file's single channel. If fillLeftoverChannelsWithCopies - was false, then only the first channel would be filled with the file's contents, and - the second would be cleared. If there are many channels, e.g. you try to read 4 channels - from a stereo file, then the last 3 would all end up with copies of the same data. - @returns true if the operation succeeded, false if there was an error. Note - that reading sections of data beyond the extent of the stream isn't an - error - the reader should just return zeros for these regions - @see readMaxLevels - */ - bool read (int** destSamples, - int numDestChannels, - int64 startSampleInSource, - int numSamplesToRead, - const bool fillLeftoverChannelsWithCopies); - - /** Finds the highest and lowest sample levels from a section of the audio stream. - - This will read a block of samples from the stream, and measure the - highest and lowest sample levels from the channels in that section, returning - these as normalised floating-point levels. - - @param startSample the offset into the audio stream to start reading from. It's - ok for this to be beyond the start or end of the stream. - @param numSamples how many samples to read - @param lowestLeft on return, this is the lowest absolute sample from the left channel - @param highestLeft on return, this is the highest absolute sample from the left channel - @param lowestRight on return, this is the lowest absolute sample from the right - channel (if there is one) - @param highestRight on return, this is the highest absolute sample from the right - channel (if there is one) - @see read - */ - virtual void readMaxLevels (int64 startSample, - int64 numSamples, - float& lowestLeft, - float& highestLeft, - float& lowestRight, - float& highestRight); - - /** Scans the source looking for a sample whose magnitude is in a specified range. - - This will read from the source, either forwards or backwards between two sample - positions, until it finds a sample whose magnitude lies between two specified levels. - - If it finds a suitable sample, it returns its position; if not, it will return -1. - - There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing - points when you're searching for a continuous range of samples - - @param startSample the first sample to look at - @param numSamplesToSearch the number of samples to scan. If this value is negative, - the search will go backwards - @param magnitudeRangeMinimum the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0 - @param magnitudeRangeMaximum the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0 - @param minimumConsecutiveSamples if this is > 0, the method will only look for a sequence - of this many consecutive samples, all of which lie - within the target range. When it finds such a sequence, - it returns the position of the first in-range sample - it found (i.e. the earliest one if scanning forwards, the - latest one if scanning backwards) - */ - int64 searchForLevel (int64 startSample, - int64 numSamplesToSearch, - const double magnitudeRangeMinimum, - const double magnitudeRangeMaximum, - const int minimumConsecutiveSamples); - - /** The sample-rate of the stream. */ - double sampleRate; - - /** The number of bits per sample, e.g. 16, 24, 32. */ - unsigned int bitsPerSample; - - /** The total number of samples in the audio stream. */ - int64 lengthInSamples; - - /** The total number of channels in the audio stream. */ - unsigned int numChannels; - - /** Indicates whether the data is floating-point or fixed. */ - bool usesFloatingPointData; - - /** A set of metadata values that the reader has pulled out of the stream. - - Exactly what these values are depends on the format, so you can - check out the format implementation code to see what kind of stuff - they understand. - */ - StringPairArray metadataValues; - - /** The input stream, for use by subclasses. */ - InputStream* input; - - /** Subclasses must implement this method to perform the low-level read operation. - - Callers should use read() instead of calling this directly. - - @param destSamples the array of destination buffers to fill. Some of these - pointers may be null - @param numDestChannels the number of items in the destSamples array. This - value is guaranteed not to be greater than the number of - channels that this reader object contains - @param startOffsetInDestBuffer the number of samples from the start of the - dest data at which to begin writing - @param startSampleInFile the number of samples into the source data at which - to begin reading. This value is guaranteed to be >= 0. - @param numSamples the number of samples to read - */ - virtual bool readSamples (int** destSamples, - int numDestChannels, - int startOffsetInDestBuffer, - int64 startSampleInFile, - int numSamples) = 0; - - juce_UseDebuggingNewOperator + PopupMenuCustomComponent (const bool isTriggeredAutomatically = true); private: - String formatName; + friend class MenuItemInfo; + friend class MenuItemComponent; + friend class PopupMenuWindow; + int refCount_; + bool isHighlighted, isTriggeredAutomatically; - AudioFormatReader (const AudioFormatReader&); - const AudioFormatReader& operator= (const AudioFormatReader&); + PopupMenuCustomComponent (const PopupMenuCustomComponent&); + const PopupMenuCustomComponent& operator= (const PopupMenuCustomComponent&); }; -#endif // __JUCE_AUDIOFORMATREADER_JUCEHEADER__ -/********* End of inlined file: juce_AudioFormatReader.h *********/ +#endif // __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_PopupMenuCustomComponent.h *********/ -/** - A type of AudioSource that will read from an AudioFormatReader. +/** Creates and displays a popup-menu. - @see PositionableAudioSource, AudioTransportSource, BufferingAudioSource -*/ -class JUCE_API AudioFormatReaderSource : public PositionableAudioSource -{ -public: + To show a popup-menu, you create one of these, add some items to it, then + call its show() method, which returns the id of the item the user selects. - /** Creates an AudioFormatReaderSource for a given reader. - - @param sourceReader the reader to use as the data source - @param deleteReaderWhenThisIsDeleted if true, the reader passed-in will be deleted - when this object is deleted; if false it will be - left up to the caller to manage its lifetime - */ - AudioFormatReaderSource (AudioFormatReader* const sourceReader, - const bool deleteReaderWhenThisIsDeleted); - - /** Destructor. */ - ~AudioFormatReaderSource(); - - /** Toggles loop-mode. - - If set to true, it will continuously loop the input source. If false, - it will just emit silence after the source has finished. - - @see isLooping - */ - void setLooping (const bool shouldLoop) throw(); - - /** Returns whether loop-mode is turned on or not. */ - bool isLooping() const { return looping; } - - /** Returns the reader that's being used. */ - AudioFormatReader* getAudioFormatReader() const throw() { return reader; } - - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - - /** Implementation of the AudioSource method. */ - void releaseResources(); - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int newPosition); - - /** Implements the PositionableAudioSource method. */ - int getNextReadPosition() const; - - /** Implements the PositionableAudioSource method. */ - int getTotalLength() const; - - juce_UseDebuggingNewOperator - -private: - AudioFormatReader* reader; - bool deleteReader; - - int volatile nextPlayPos; - bool volatile looping; - - void readBufferSection (int start, int length, AudioSampleBuffer& buffer, int startSample); - - AudioFormatReaderSource (const AudioFormatReaderSource&); - const AudioFormatReaderSource& operator= (const AudioFormatReaderSource&); -}; - -#endif // __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_AudioFormatReaderSource.h *********/ - -#endif -#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioSourcePlayer.h *********/ -#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ -#define __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ - -/** - Wrapper class to continuously stream audio from an audio source to an - AudioIODevice. - - This object acts as an AudioIODeviceCallback, so can be attached to an - output device, and will stream audio from an AudioSource. -*/ -class JUCE_API AudioSourcePlayer : public AudioIODeviceCallback -{ -public: - - /** Creates an empty AudioSourcePlayer. */ - AudioSourcePlayer(); - - /** Destructor. - - Make sure this object isn't still being used by an AudioIODevice before - deleting it! - */ - virtual ~AudioSourcePlayer(); - - /** Changes the current audio source to play from. - - If the source passed in is already being used, this method will do nothing. - If the source is not null, its prepareToPlay() method will be called - before it starts being used for playback. - - If there's another source currently playing, its releaseResources() method - will be called after it has been swapped for the new one. - - @param newSource the new source to use - this will NOT be deleted - by this object when no longer needed, so it's the - caller's responsibility to manage it. - */ - void setSource (AudioSource* newSource); - - /** Returns the source that's playing. - - May return 0 if there's no source. - */ - AudioSource* getCurrentSource() const throw() { return source; } - - /** Sets a gain to apply to the audio data. */ - void setGain (const float newGain) throw(); - - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceIOCallback (const float** inputChannelData, - int totalNumInputChannels, - float** outputChannelData, - int totalNumOutputChannels, - int numSamples); - - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceAboutToStart (AudioIODevice* device); - - /** Implementation of the AudioIODeviceCallback method. */ - void audioDeviceStopped(); - - juce_UseDebuggingNewOperator - -private: - - CriticalSection readLock; - AudioSource* source; - double sampleRate; - int bufferSize; - float* channels [128]; - float* outputChans [128]; - const float* inputChans [128]; - AudioSampleBuffer tempBuffer; - float lastGain, gain; - - AudioSourcePlayer (const AudioSourcePlayer&); - const AudioSourcePlayer& operator= (const AudioSourcePlayer&); -}; - -#endif // __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__ -/********* End of inlined file: juce_AudioSourcePlayer.h *********/ - -#endif -#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioTransportSource.h *********/ -#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ -#define __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_BufferingAudioSource.h *********/ -#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ - -/** - An AudioSource which takes another source as input, and buffers it using a thread. - - Create this as a wrapper around another thread, and it will read-ahead with - a background thread to smooth out playback. You can either create one of these - directly, or use it indirectly using an AudioTransportSource. - - @see PositionableAudioSource, AudioTransportSource -*/ -class JUCE_API BufferingAudioSource : public PositionableAudioSource -{ -public: - - /** Creates a BufferingAudioSource. - - @param source the input source to read from - @param deleteSourceWhenDeleted if true, then the input source object will - be deleted when this object is deleted - @param numberOfSamplesToBuffer the size of buffer to use for reading ahead - */ - BufferingAudioSource (PositionableAudioSource* source, - const bool deleteSourceWhenDeleted, - int numberOfSamplesToBuffer); - - /** Destructor. - - The input source may be deleted depending on whether the deleteSourceWhenDeleted - flag was set in the constructor. - */ - ~BufferingAudioSource(); - - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - - /** Implementation of the AudioSource method. */ - void releaseResources(); - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int newPosition); - - /** Implements the PositionableAudioSource method. */ - int getNextReadPosition() const; - - /** Implements the PositionableAudioSource method. */ - int getTotalLength() const { return source->getTotalLength(); } - - /** Implements the PositionableAudioSource method. */ - bool isLooping() const { return source->isLooping(); } - - juce_UseDebuggingNewOperator - -private: - - PositionableAudioSource* source; - bool deleteSourceWhenDeleted; - int numberOfSamplesToBuffer; - AudioSampleBuffer buffer; - CriticalSection bufferStartPosLock; - int volatile bufferValidStart, bufferValidEnd, nextPlayPos; - bool wasSourceLooping; - double volatile sampleRate; - - friend class SharedBufferingAudioSourceThread; - bool readNextBufferChunk(); - void readBufferSection (int start, int length, int bufferOffset); - - BufferingAudioSource (const BufferingAudioSource&); - const BufferingAudioSource& operator= (const BufferingAudioSource&); -}; - -#endif // __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_BufferingAudioSource.h *********/ - -/********* Start of inlined file: juce_ResamplingAudioSource.h *********/ -#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ - -/** - A type of AudioSource that takes an input source and changes its sample rate. - - @see AudioSource -*/ -class JUCE_API ResamplingAudioSource : public AudioSource -{ -public: - - /** Creates a ResamplingAudioSource for a given input source. - - @param inputSource the input source to read from - @param deleteInputWhenDeleted if true, the input source will be deleted when - this object is deleted - */ - ResamplingAudioSource (AudioSource* const inputSource, - const bool deleteInputWhenDeleted); - - /** Destructor. */ - ~ResamplingAudioSource(); - - /** Changes the resampling ratio. - - (This value can be changed at any time, even while the source is running). - - @param samplesInPerOutputSample if set to 1.0, the input is passed through; higher - values will speed it up; lower values will slow it - down. The ratio must be greater than 0 - */ - void setResamplingRatio (const double samplesInPerOutputSample); - - /** Returns the current resampling ratio. - - This is the value that was set by setResamplingRatio(). - */ - double getResamplingRatio() const throw() { return ratio; } - - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - void releaseResources(); - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - juce_UseDebuggingNewOperator - -private: - AudioSource* const input; - const bool deleteInputWhenDeleted; - double ratio, lastRatio; - AudioSampleBuffer buffer; - int bufferPos, sampsInBuffer; - double subSampleOffset; - double coefficients[6]; - CriticalSection ratioLock; - - void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6); - void createLowPass (const double proportionalRate); - - struct FilterState + E.g. @code + void MyWidget::mouseDown (const MouseEvent& e) { - double x1, x2, y1, y2; - }; + PopupMenu m; + m.addItem (1, "item 1"); + m.addItem (2, "item 2"); - FilterState filterStates[2]; - void resetFilters(); + const int result = m.show(); - void applyFilter (float* samples, int num, FilterState& fs); - - ResamplingAudioSource (const ResamplingAudioSource&); - const ResamplingAudioSource& operator= (const ResamplingAudioSource&); -}; - -#endif // __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_ResamplingAudioSource.h *********/ - -/** - An AudioSource that takes a PositionableAudioSource and allows it to be - played, stopped, started, etc. - - This can also be told use a buffer and background thread to read ahead, and - if can correct for different sample-rates. - - You may want to use one of these along with an AudioSourcePlayer and AudioIODevice - to control playback of an audio file. - - @see AudioSource, AudioSourcePlayer -*/ -class JUCE_API AudioTransportSource : public PositionableAudioSource, - public ChangeBroadcaster -{ -public: - - /** Creates an AudioTransportSource. - - After creating one of these, use the setSource() method to select an input source. - */ - AudioTransportSource(); - - /** Destructor. */ - ~AudioTransportSource(); - - /** Sets the reader that is being used as the input source. - - This will stop playback, reset the position to 0 and change to the new reader. - - The source passed in will not be deleted by this object, so must be managed by - the caller. - - @param newSource the new input source to use. This may be zero - @param readAheadBufferSize a size of buffer to use for reading ahead. If this - is zero, no reading ahead will be done; if it's - greater than zero, a BufferingAudioSource will be used - to do the reading-ahead - @param sourceSampleRateToCorrectFor if this is non-zero, it specifies the sample - rate of the source, and playback will be sample-rate - adjusted to maintain playback at the correct pitch. If - this is 0, no sample-rate adjustment will be performed - */ - void setSource (PositionableAudioSource* const newSource, - int readAheadBufferSize = 0, - double sourceSampleRateToCorrectFor = 0.0); - - /** Changes the current playback position in the source stream. - - The next time the getNextAudioBlock() method is called, this - is the time from which it'll read data. - - @see getPosition - */ - void setPosition (double newPosition); - - /** Returns the position that the next data block will be read from - - This is a time in seconds. - */ - double getCurrentPosition() const; - - /** Returns true if the player has stopped because its input stream ran out of data. - */ - bool hasStreamFinished() const throw() { return inputStreamEOF; } - - /** Starts playing (if a source has been selected). - - If it starts playing, this will send a message to any ChangeListeners - that are registered with this object. - */ - void start(); - - /** Stops playing. - - If it's actually playing, this will send a message to any ChangeListeners - that are registered with this object. - */ - void stop(); - - /** Returns true if it's currently playing. */ - bool isPlaying() const throw() { return playing; } - - /** Changes the gain to apply to the output. - - @param newGain a factor by which to multiply the outgoing samples, - so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc. - */ - void setGain (const float newGain) throw(); - - /** Returns the current gain setting. - - @see setGain - */ - float getGain() const throw() { return gain; } - - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - - /** Implementation of the AudioSource method. */ - void releaseResources(); - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - /** Implements the PositionableAudioSource method. */ - void setNextReadPosition (int newPosition); - - /** Implements the PositionableAudioSource method. */ - int getNextReadPosition() const; - - /** Implements the PositionableAudioSource method. */ - int getTotalLength() const; - - /** Implements the PositionableAudioSource method. */ - bool isLooping() const; - - juce_UseDebuggingNewOperator - -private: - PositionableAudioSource* source; - ResamplingAudioSource* resamplerSource; - BufferingAudioSource* bufferingSource; - PositionableAudioSource* positionableSource; - AudioSource* masterSource; - - CriticalSection callbackLock; - float volatile gain, lastGain; - bool volatile playing, stopped; - double sampleRate, sourceSampleRate; - int blockSize, readAheadBufferSize; - bool isPrepared, inputStreamEOF; - - AudioTransportSource (const AudioTransportSource&); - const AudioTransportSource& operator= (const AudioTransportSource&); -}; - -#endif // __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_AudioTransportSource.h *********/ - -#endif -#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__ - -#endif -#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_ChannelRemappingAudioSource.h *********/ -#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ - -/** - An AudioSource that takes the audio from another source, and re-maps its - input and output channels to a different arrangement. - - You can use this to increase or decrease the number of channels that an - audio source uses, or to re-order those channels. - - Call the reset() method before using it to set up a default mapping, and then - the setInputChannelMapping() and setOutputChannelMapping() methods to - create an appropriate mapping, otherwise no channels will be connected and - it'll produce silence. - - @see AudioSource -*/ -class ChannelRemappingAudioSource : public AudioSource -{ -public: - - /** Creates a remapping source that will pass on audio from the given input. - - @param source the input source to use. Make sure that this doesn't - get deleted before the ChannelRemappingAudioSource object - @param deleteSourceWhenDeleted if true, the input source will be deleted - when this object is deleted, if false, the caller is - responsible for its deletion - */ - ChannelRemappingAudioSource (AudioSource* const source, - const bool deleteSourceWhenDeleted); - - /** Destructor. */ - ~ChannelRemappingAudioSource(); - - /** Specifies a number of channels that this audio source must produce from its - getNextAudioBlock() callback. - */ - void setNumberOfChannelsToProduce (const int requiredNumberOfChannels) throw(); - - /** Clears any mapped channels. - - After this, no channels are mapped, so this object will produce silence. Create - some mappings with setInputChannelMapping() and setOutputChannelMapping(). - */ - void clearAllMappings() throw(); - - /** Creates an input channel mapping. - - When the getNextAudioBlock() method is called, the data in channel sourceChannelIndex of the incoming - data will be sent to destChannelIndex of our input source. - - @param destChannelIndex the index of an input channel in our input audio source (i.e. the - source specified when this object was created). - @param sourceChannelIndex the index of the input channel in the incoming audio data buffer - during our getNextAudioBlock() callback - */ - void setInputChannelMapping (const int destChannelIndex, - const int sourceChannelIndex) throw(); - - /** Creates an output channel mapping. - - When the getNextAudioBlock() method is called, the data returned in channel sourceChannelIndex by - our input audio source will be copied to channel destChannelIndex of the final buffer. - - @param sourceChannelIndex the index of an output channel coming from our input audio source - (i.e. the source specified when this object was created). - @param destChannelIndex the index of the output channel in the incoming audio data buffer - during our getNextAudioBlock() callback - */ - void setOutputChannelMapping (const int sourceChannelIndex, - const int destChannelIndex) throw(); - - /** Returns the channel from our input that will be sent to channel inputChannelIndex of - our input audio source. - */ - int getRemappedInputChannel (const int inputChannelIndex) const throw(); - - /** Returns the output channel to which channel outputChannelIndex of our input audio - source will be sent to. - */ - int getRemappedOutputChannel (const int outputChannelIndex) const throw(); - - /** Returns an XML object to encapsulate the state of the mappings. - - @see restoreFromXml - */ - XmlElement* createXml() const throw(); - - /** Restores the mappings from an XML object created by createXML(). - - @see createXml - */ - void restoreFromXml (const XmlElement& e) throw(); - - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - void releaseResources(); - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - juce_UseDebuggingNewOperator - -private: - int requiredNumberOfChannels; - Array remappedInputs, remappedOutputs; - - AudioSource* const source; - const bool deleteSourceWhenDeleted; - - AudioSampleBuffer buffer; - AudioSourceChannelInfo remappedInfo; - - CriticalSection lock; - - ChannelRemappingAudioSource (const ChannelRemappingAudioSource&); - const ChannelRemappingAudioSource& operator= (const ChannelRemappingAudioSource&); -}; - -#endif // __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_ChannelRemappingAudioSource.h *********/ - -#endif -#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_IIRFilterAudioSource.h *********/ -#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ - -/** - An AudioSource that performs an IIR filter on another source. -*/ -class JUCE_API IIRFilterAudioSource : public AudioSource -{ -public: - - /** Creates a IIRFilterAudioSource for a given input source. - - @param inputSource the input source to read from - @param deleteInputWhenDeleted if true, the input source will be deleted when - this object is deleted - */ - IIRFilterAudioSource (AudioSource* const inputSource, - const bool deleteInputWhenDeleted); - - /** Destructor. */ - ~IIRFilterAudioSource(); - - /** Changes the filter to use the same parameters as the one being passed in. - */ - void setFilterParameters (const IIRFilter& newSettings); - - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - void releaseResources(); - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - juce_UseDebuggingNewOperator - -private: - - AudioSource* const input; - const bool deleteInputWhenDeleted; - OwnedArray iirFilters; - - IIRFilterAudioSource (const IIRFilterAudioSource&); - const IIRFilterAudioSource& operator= (const IIRFilterAudioSource&); -}; - -#endif // __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_IIRFilterAudioSource.h *********/ - -#endif -#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_MixerAudioSource.h *********/ -#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ - -/** - An AudioSource that mixes together the output of a set of other AudioSources. - - Input sources can be added and removed while the mixer is running as long as their - prepareToPlay() and releaseResources() methods are called before and after adding - them to the mixer. -*/ -class JUCE_API MixerAudioSource : public AudioSource -{ -public: - - /** Creates a MixerAudioSource. - */ - MixerAudioSource(); - - /** Destructor. */ - ~MixerAudioSource(); - - /** Adds an input source to the mixer. - - If the mixer is running you'll need to make sure that the input source - is ready to play by calling its prepareToPlay() method before adding it. - If the mixer is stopped, then its input sources will be automatically - prepared when the mixer's prepareToPlay() method is called. - - @param newInput the source to add to the mixer - @param deleteWhenRemoved if true, then this source will be deleted when - the mixer is deleted or when removeAllInputs() is - called (unless the source is previously removed - with the removeInputSource method) - */ - void addInputSource (AudioSource* newInput, - const bool deleteWhenRemoved); - - /** Removes an input source. - - If the mixer is running, this will remove the source but not call its - releaseResources() method, so the caller might want to do this manually. - - @param input the source to remove - @param deleteSource whether to delete this source after it's been removed - */ - void removeInputSource (AudioSource* input, - const bool deleteSource); - - /** Removes all the input sources. - - If the mixer is running, this will remove the sources but not call their - releaseResources() method, so the caller might want to do this manually. - - Any sources which were added with the deleteWhenRemoved flag set will be - deleted by this method. - */ - void removeAllInputs(); - - /** Implementation of the AudioSource method. - - This will call prepareToPlay() on all its input sources. - */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - - /** Implementation of the AudioSource method. - - This will call releaseResources() on all its input sources. - */ - void releaseResources(); - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - juce_UseDebuggingNewOperator - -private: - - VoidArray inputs; - BitArray inputsToDelete; - CriticalSection lock; - AudioSampleBuffer tempBuffer; - double currentSampleRate; - int bufferSizeExpected; - - MixerAudioSource (const MixerAudioSource&); - const MixerAudioSource& operator= (const MixerAudioSource&); -}; - -#endif // __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_MixerAudioSource.h *********/ - -#endif -#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__ - -#endif -#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__ - -#endif -#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ - -/********* Start of inlined file: juce_ToneGeneratorAudioSource.h *********/ -#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ -#define __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ - -/** - A simple AudioSource that generates a sine wave. - -*/ -class JUCE_API ToneGeneratorAudioSource : public AudioSource -{ -public: - - /** Creates a ToneGeneratorAudioSource. */ - ToneGeneratorAudioSource(); - - /** Destructor. */ - ~ToneGeneratorAudioSource(); - - /** Sets the signal's amplitude. */ - void setAmplitude (const float newAmplitude); - - /** Sets the signal's frequency. */ - void setFrequency (const double newFrequencyHz); - - /** Implementation of the AudioSource method. */ - void prepareToPlay (int samplesPerBlockExpected, double sampleRate); - - /** Implementation of the AudioSource method. */ - void releaseResources(); - - /** Implementation of the AudioSource method. */ - void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill); - - juce_UseDebuggingNewOperator - -private: - - double frequency, sampleRate; - double currentPhase, phasePerSample; - float amplitude; - - ToneGeneratorAudioSource (const ToneGeneratorAudioSource&); - const ToneGeneratorAudioSource& operator= (const ToneGeneratorAudioSource&); -}; - -#endif // __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__ -/********* End of inlined file: juce_ToneGeneratorAudioSource.h *********/ - -#endif -#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioDeviceManager.h *********/ -#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ -#define __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioIODeviceType.h *********/ -#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ -#define __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ - -class AudioDeviceManager; -class Component; - -/** - Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc. - - To get a list of available audio driver types, use the createDeviceTypes() - method. Each of the objects returned can then be used to list the available - devices of that type. E.g. - @code - OwnedArray types; - AudioIODeviceType::createDeviceTypes (types); - - for (int i = 0; i < types.size(); ++i) - { - String typeName (types[i]->getTypeName()); // This will be things like "DirectSound", "CoreAudio", etc. - - types[i]->scanForDevices(); // This must be called before getting the list of devices - - StringArray deviceNames (types[i]->getDeviceNames()); // This will now return a list of available devices of this type - - for (int j = 0; j < deviceNames.size(); ++j) + if (result == 0) { - AudioIODevice* device = types[i]->createDevice (deviceNames [j]); - - ... + // user dismissed the menu without picking anything + } + else if (result == 1) + { + // user picked item 1 + } + else if (result == 2) + { + // user picked item 2 } } @endcode - For an easier way of managing audio devices and their settings, have a look at the - AudioDeviceManager class. + Submenus are easy too: @code - @see AudioIODevice, AudioDeviceManager + void MyWidget::mouseDown (const MouseEvent& e) + { + PopupMenu subMenu; + subMenu.addItem (1, "item 1"); + subMenu.addItem (2, "item 2"); + + PopupMenu mainMenu; + mainMenu.addItem (3, "item 3"); + mainMenu.addSubMenu ("other choices", subMenu); + + const int result = m.show(); + + ...etc + } + @endcode */ -class JUCE_API AudioIODeviceType +class JUCE_API PopupMenu { public: - /** Returns the name of this type of driver that this object manages. + /** Creates an empty popup menu. */ + PopupMenu() throw(); - This will be something like "DirectSound", "ASIO", "CoreAudio", "ALSA", etc. + /** Creates a copy of another menu. */ + PopupMenu (const PopupMenu& other) throw(); + + /** Destructor. */ + ~PopupMenu() throw(); + + /** Copies this menu from another one. */ + const PopupMenu& operator= (const PopupMenu& other) throw(); + + /** Resets the menu, removing all its items. */ + void clear() throw(); + + /** Appends a new text item for this menu to show. + + @param itemResultId the number that will be returned from the show() method + if the user picks this item. The value should never be + zero, because that's used to indicate that the user didn't + select anything. + @param itemText the text to show. + @param isActive if false, the item will be shown 'greyed-out' and can't be + picked + @param isTicked if true, the item will be shown with a tick next to it + @param iconToUse if this is non-zero, it should be an image that will be + displayed to the left of the item. This method will take its + own copy of the image passed-in, so there's no need to keep + it hanging around. + + @see addSeparator, addColouredItem, addCustomItem, addSubMenu */ - const String& getTypeName() const throw() { return typeName; } + void addItem (const int itemResultId, + const String& itemText, + const bool isActive = true, + const bool isTicked = false, + const Image* const iconToUse = 0) throw(); - /** Refreshes the object's cached list of known devices. + /** Adds an item that represents one of the commands in a command manager object. - This must be called at least once before calling getDeviceNames() or any of - the other device creation methods. + @param commandManager the manager to use to trigger the command and get information + about it + @param commandID the ID of the command + @param displayName if this is non-empty, then this string will be used instead of + the command's registered name */ - virtual void scanForDevices() = 0; + void addCommandItem (ApplicationCommandManager* commandManager, + const int commandID, + const String& displayName = String::empty) throw(); - /** Returns the list of available devices of this type. + /** Appends a text item with a special colour. - The scanForDevices() method must have been called to create this list. - - @param wantInputNames only really used by DirectSound where devices are split up - into inputs and outputs, this indicates whether to use - the input or output name to refer to a pair of devices. + This is the same as addItem(), but specifies a colour to use for the + text, which will override the default colours that are used by the + current look-and-feel. See addItem() for a description of the parameters. */ - virtual const StringArray getDeviceNames (const bool wantInputNames = false) const = 0; + void addColouredItem (const int itemResultId, + const String& itemText, + const Colour& itemTextColour, + const bool isActive = true, + const bool isTicked = false, + const Image* const iconToUse = 0) throw(); - /** Returns the name of the default device. + /** Appends a custom menu item. - This will be one of the names from the getDeviceNames() list. + This will add a user-defined component to use as a menu item. The component + passed in will be deleted by this menu when it's no longer needed. - @param forInput if true, this means that a default input device should be - returned; if false, it should return the default output + @see PopupMenuCustomComponent */ - virtual int getDefaultDeviceIndex (const bool forInput) const = 0; + void addCustomItem (const int itemResultId, + PopupMenuCustomComponent* const customComponent) throw(); - /** Returns the index of a given device in the list of device names. - If asInput is true, it shows the index in the inputs list, otherwise it - looks for it in the outputs list. + /** Appends a custom menu item that can't be used to trigger a result. + + This will add a user-defined component to use as a menu item. Unlike the + addCustomItem() method that takes a PopupMenuCustomComponent, this version + can't trigger a result from it, so doesn't take a menu ID. It also doesn't + delete the component when it's finished, so it's the caller's responsibility + to manage the component that is passed-in. + + if triggerMenuItemAutomaticallyWhenClicked is true, the menu itself will handle + detection of a mouse-click on your component, and use that to trigger the + menu ID specified in itemResultId. If this is false, the menu item can't + be triggered, so itemResultId is not used. + + @see PopupMenuCustomComponent */ - virtual int getIndexOfDevice (AudioIODevice* device, const bool asInput) const = 0; + void addCustomItem (const int itemResultId, + Component* customComponent, + int idealWidth, int idealHeight, + const bool triggerMenuItemAutomaticallyWhenClicked) throw(); - /** Returns true if two different devices can be used for the input and output. + /** Appends a sub-menu. + + If the menu that's passed in is empty, it will appear as an inactive item. */ - virtual bool hasSeparateInputsAndOutputs() const = 0; + void addSubMenu (const String& subMenuName, + const PopupMenu& subMenu, + const bool isActive = true, + Image* const iconToUse = 0, + const bool isTicked = false) throw(); - /** Creates one of the devices of this type. + /** Appends a separator to the menu, to help break it up into sections. - The deviceName must be one of the strings returned by getDeviceNames(), and - scanForDevices() must have been called before this method is used. + The menu class is smart enough not to display separators at the top or bottom + of the menu, and it will replace mutliple adjacent separators with a single + one, so your code can be quite free and easy about adding these, and it'll + always look ok. */ - virtual AudioIODevice* createDevice (const String& outputDeviceName, - const String& inputDeviceName) = 0; + void addSeparator() throw(); - struct DeviceSetupDetails + /** Adds a non-clickable text item to the menu. + + This is a bold-font items which can be used as a header to separate the items + into named groups. + */ + void addSectionHeader (const String& title) throw(); + + /** Returns the number of items that the menu currently contains. + + (This doesn't count separators). + */ + int getNumItems() const throw(); + + /** Returns true if the menu contains a command item that triggers the given command. */ + bool containsCommandItem (const int commandID) const throw(); + + /** Returns true if the menu contains any items that can be used. */ + bool containsAnyActiveItems() const throw(); + + /** Displays the menu and waits for the user to pick something. + + This will display the menu modally, and return the ID of the item that the + user picks. If they click somewhere off the menu to get rid of it without + choosing anything, this will return 0. + + The current location of the mouse will be used as the position to show the + menu - to explicitly set the menu's position, use showAt() instead. Depending + on where this point is on the screen, the menu will appear above, below or + to the side of the point. + + @param itemIdThatMustBeVisible if you set this to the ID of one of the menu items, + then when the menu first appears, it will make sure + that this item is visible. So if the menu has too many + items to fit on the screen, it will be scrolled to a + position where this item is visible. + @param minimumWidth a minimum width for the menu, in pixels. It may be wider + than this if some items are too long to fit. + @param maximumNumColumns if there are too many items to fit on-screen in a single + vertical column, the menu may be laid out as a series of + columns - this is the maximum number allowed. To use the + default value for this (probably about 7), you can pass + in zero. + @param standardItemHeight if this is non-zero, it will be used as the standard + height for menu items (apart from custom items) + @see showAt + */ + int show (const int itemIdThatMustBeVisible = 0, + const int minimumWidth = 0, + const int maximumNumColumns = 0, + const int standardItemHeight = 0); + + /** Displays the menu at a specific location. + + This is the same as show(), but uses a specific location (in global screen + co-ordinates) rather than the current mouse position. + + Note that the co-ordinates don't specify the top-left of the menu - they + indicate a point of interest, and the menu will position itself nearby to + this point, trying to keep it fully on-screen. + + @see show() + */ + int showAt (const int screenX, + const int screenY, + const int itemIdThatMustBeVisible = 0, + const int minimumWidth = 0, + const int maximumNumColumns = 0, + const int standardItemHeight = 0); + + /** Displays the menu as if it's attached to a component such as a button. + + This is similar to showAt(), but will position it next to the given component, e.g. + so that the menu's edge is aligned with that of the component. This is intended for + things like buttons that trigger a pop-up menu. + */ + int showAt (Component* componentToAttachTo, + const int itemIdThatMustBeVisible = 0, + const int minimumWidth = 0, + const int maximumNumColumns = 0, + const int standardItemHeight = 0); + + /** Closes any menus that are currently open. + + This might be useful if you have a situation where your window is being closed + by some means other than a user action, and you'd like to make sure that menus + aren't left hanging around. + */ + static void JUCE_CALLTYPE dismissAllActiveMenus() throw(); + + /** Specifies a look-and-feel for the menu and any sub-menus that it has. + + This can be called before show() if you need a customised menu. Be careful + not to delete the LookAndFeel object before the menu has been deleted. + */ + void setLookAndFeel (LookAndFeel* const newLookAndFeel) throw(); + + /** A set of colour IDs to use to change the colour of various aspects of the menu. + + These constants can be used either via the LookAndFeel::setColour() + method for the look and feel that is set for this menu with setLookAndFeel() + + @see setLookAndFeel, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds { - AudioDeviceManager* manager; - int minNumInputChannels, maxNumInputChannels; - int minNumOutputChannels, maxNumOutputChannels; - bool useStereoPairs; + backgroundColourId = 0x1000700, /**< The colour to fill the menu's background with. */ + textColourId = 0x1000600, /**< The colour for normal menu item text, (unless the + colour is specified when the item is added). */ + headerTextColourId = 0x1000601, /**< The colour for section header item text (see the + addSectionHeader() method). */ + highlightedBackgroundColourId = 0x1000900, /**< The colour to fill the background of the currently + highlighted menu item. */ + highlightedTextColourId = 0x1000800, /**< The colour to use for the text of the currently + highlighted item. */ }; - /** Destructor. */ - virtual ~AudioIODeviceType(); + /** + Allows you to iterate through the items in a pop-up menu, and examine + their properties. -protected: - AudioIODeviceType (const tchar* const typeName); - -private: - String typeName; - - AudioIODeviceType (const AudioIODeviceType&); - const AudioIODeviceType& operator= (const AudioIODeviceType&); -}; - -#endif // __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__ -/********* End of inlined file: juce_AudioIODeviceType.h *********/ - -/********* Start of inlined file: juce_MidiOutput.h *********/ -#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__ -#define __JUCE_MIDIOUTPUT_JUCEHEADER__ - -/** - Represents a midi output device. - - To create one of these, use the static getDevices() method to find out what - outputs are available, then use the openDevice() method to try to open one. - - @see MidiInput -*/ -class JUCE_API MidiOutput : private Thread -{ -public: - - /** Returns a list of the available midi output devices. - - You can open one of the devices by passing its index into the - openDevice() method. - - @see getDefaultDeviceIndex, openDevice + To use this, just create one and repeatedly call its next() method. When this + returns true, all the member variables of the iterator are filled-out with + information describing the menu item. When it returns false, the end of the + list has been reached. */ - static const StringArray getDevices(); - - /** Returns the index of the default midi output device to use. - - This refers to the index in the list returned by getDevices(). - */ - static int getDefaultDeviceIndex(); - - /** Tries to open one of the midi output devices. - - This will return a MidiOutput object if it manages to open it. You can then - send messages to this device, and delete it when no longer needed. - - If the device can't be opened, this will return a null pointer. - - @param deviceIndex the index of a device from the list returned by getDevices() - @see getDevices - */ - static MidiOutput* openDevice (int deviceIndex); - -#if JUCE_LINUX || JUCE_MAC || DOXYGEN - /** This will try to create a new midi output device (Not available on Windows). - - This will attempt to create a new midi output device that other apps can connect - to and use as their midi input. - - Returns 0 if a device can't be created. - - @param deviceName the name to use for the new device - */ - static MidiOutput* createNewDevice (const String& deviceName); -#endif - - /** Destructor. */ - virtual ~MidiOutput(); - - /** Makes this device output a midi message. - - @see MidiMessage - */ - virtual void sendMessageNow (const MidiMessage& message); - - /** Sends a midi reset to the device. */ - virtual void reset(); - - /** Returns the current volume setting for this device. */ - virtual bool getVolume (float& leftVol, - float& rightVol); - - /** Changes the overall volume for this device. */ - virtual void setVolume (float leftVol, - float rightVol); - - /** This lets you supply a block of messages that will be sent out at some point - in the future. - - The MidiOutput class has an internal thread that can send out timestamped - messages - this appends a set of messages to its internal buffer, ready for - sending. - - This will only work if you've already started the thread with startBackgroundThread(). - - A time is supplied, at which the block of messages should be sent. This time uses - the same time base as Time::getMillisecondCounter(), and must be in the future. - - The samplesPerSecondForBuffer parameter indicates the number of samples per second - used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the - samplesPerSecondForBuffer value is needed to convert this sample position to a - real time. - */ - virtual void sendBlockOfMessages (const MidiBuffer& buffer, - const double millisecondCounterToStartAt, - double samplesPerSecondForBuffer) throw(); - - /** Gets rid of any midi messages that had been added by sendBlockOfMessages(). - */ - virtual void clearAllPendingMessages() throw(); - - /** Starts up a background thread so that the device can send blocks of data. - - Call this to get the device ready, before using sendBlockOfMessages(). - */ - virtual void startBackgroundThread() throw(); - - /** Stops the background thread, and clears any pending midi events. - - @see startBackgroundThread - */ - virtual void stopBackgroundThread() throw(); - - juce_UseDebuggingNewOperator - -protected: - void* internal; - - struct PendingMessage + class JUCE_API MenuItemIterator { - PendingMessage (const uint8* const data, const int len, const double sampleNumber) throw(); + public: - MidiMessage message; - PendingMessage* next; + /** Creates an iterator that will scan through the items in the specified + menu. + + Be careful not to add any items to a menu while it is being iterated, + or things could get out of step. + */ + MenuItemIterator (const PopupMenu& menu) throw(); + + /** Destructor. */ + ~MenuItemIterator() throw(); + + /** Returns true if there is another item, and sets up all this object's + member variables to reflect that item's properties. + */ + bool next() throw(); + + String itemName; + const PopupMenu* subMenu; + int itemId; + bool isSeparator; + bool isTicked; + bool isEnabled; + bool isCustomComponent; + bool isSectionHeader; + const Colour* customColour; + const Image* customImage; + ApplicationCommandManager* commandManager; juce_UseDebuggingNewOperator + + private: + const PopupMenu& menu; + int index; + + MenuItemIterator (const MenuItemIterator&); + const MenuItemIterator& operator= (const MenuItemIterator&); }; - CriticalSection lock; - PendingMessage* firstMessage; - - MidiOutput() throw(); - MidiOutput (const MidiOutput&); - - void run(); -}; - -#endif // __JUCE_MIDIOUTPUT_JUCEHEADER__ -/********* End of inlined file: juce_MidiOutput.h *********/ - -/********* Start of inlined file: juce_ComboBox.h *********/ -#ifndef __JUCE_COMBOBOX_JUCEHEADER__ -#define __JUCE_COMBOBOX_JUCEHEADER__ - -/********* Start of inlined file: juce_Label.h *********/ -#ifndef __JUCE_LABEL_JUCEHEADER__ -#define __JUCE_LABEL_JUCEHEADER__ - -/********* Start of inlined file: juce_ComponentDeletionWatcher.h *********/ -#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ -#define __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ - -/** - Object for monitoring a component, and later testing whether it's still valid. - - Slightly obscure, this one, but it's used internally for making sure that - after some callbacks, a component hasn't been deleted. It's more reliable than - just using isValidComponent(), which can provide false-positives if a new - component is created at the same memory location as an old one. -*/ -class JUCE_API ComponentDeletionWatcher -{ -public: - - /** Creates a watcher for a given component. - - The component must be valid at the time it's passed in. - */ - ComponentDeletionWatcher (const Component* const componentToWatch) throw(); - - /** Destructor. */ - ~ComponentDeletionWatcher() throw(); - - /** Returns true if the component has been deleted since the time that this - object was created. - */ - bool hasBeenDeleted() const throw(); - - /** Returns the component that's being watched, or null if it has been deleted. */ - const Component* getComponent() const throw(); - juce_UseDebuggingNewOperator private: - const Component* const componentToWatch; - const uint32 componentUID; + friend class PopupMenuWindow; + friend class MenuItemIterator; + VoidArray items; + LookAndFeel* lookAndFeel; + bool separatorPending; - ComponentDeletionWatcher (const ComponentDeletionWatcher&); - const ComponentDeletionWatcher& operator= (const ComponentDeletionWatcher&); + void addSeparatorIfPending(); + + int showMenu (const int x, const int y, const int w, const int h, + const int itemIdThatMustBeVisible, + const int minimumWidth, + const int maximumNumColumns, + const int standardItemHeight, + const bool alignToRectangle, + Component* const componentAttachedTo) throw(); + + friend class MenuBarComponent; + Component* createMenuComponent (const int x, const int y, const int w, const int h, + const int itemIdThatMustBeVisible, + const int minimumWidth, + const int maximumNumColumns, + const int standardItemHeight, + const bool alignToRectangle, + Component* menuBarComponent, + ApplicationCommandManager** managerOfChosenCommand, + Component* const componentAttachedTo) throw(); }; -#endif // __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ -/********* End of inlined file: juce_ComponentDeletionWatcher.h *********/ - -/********* Start of inlined file: juce_TextEditor.h *********/ -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ -#define __JUCE_TEXTEDITOR_JUCEHEADER__ +#endif // __JUCE_POPUPMENU_JUCEHEADER__ +/********* End of inlined file: juce_PopupMenu.h *********/ class TextEditor; class TextHolderComponent; @@ -35758,562 +34592,761 @@ private: #ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__ #endif -#ifndef __JUCE_SAMPLER_JUCEHEADER__ +#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ -/********* Start of inlined file: juce_Sampler.h *********/ -#ifndef __JUCE_SAMPLER_JUCEHEADER__ -#define __JUCE_SAMPLER_JUCEHEADER__ - -/********* Start of inlined file: juce_Synthesiser.h *********/ -#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ -#define __JUCE_SYNTHESISER_JUCEHEADER__ +/********* Start of inlined file: juce_AudioDataConverters.h *********/ +#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ +#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ /** - Describes one of the sounds that a Synthesiser can play. + A set of routines to convert buffers of 32-bit floating point data to and from + various integer formats. - A synthesiser can contain one or more sounds, and a sound can choose which - midi notes and channels can trigger it. - - The SynthesiserSound is a passive class that just describes what the sound is - - the actual audio rendering for a sound is done by a SynthesiserVoice. This allows - more than one SynthesiserVoice to play the same sound at the same time. - - @see Synthesiser, SynthesiserVoice */ -class JUCE_API SynthesiserSound : public ReferenceCountedObject -{ -protected: - - SynthesiserSound(); - -public: - /** Destructor. */ - virtual ~SynthesiserSound(); - - /** Returns true if this sound should be played when a given midi note is pressed. - - The Synthesiser will use this information when deciding which sounds to trigger - for a given note. - */ - virtual bool appliesToNote (const int midiNoteNumber) = 0; - - /** Returns true if the sound should be triggered by midi events on a given channel. - - The Synthesiser will use this information when deciding which sounds to trigger - for a given note. - */ - virtual bool appliesToChannel (const int midiChannel) = 0; - - /** - */ - typedef ReferenceCountedObjectPtr Ptr; - - juce_UseDebuggingNewOperator -}; - -/** - Represents a voice that a Synthesiser can use to play a SynthesiserSound. - - A voice plays a single sound at a time, and a synthesiser holds an array of - voices so that it can play polyphonically. - - @see Synthesiser, SynthesiserSound -*/ -class JUCE_API SynthesiserVoice +class JUCE_API AudioDataConverters { public: - /** Creates a voice. */ - SynthesiserVoice(); + static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2); + static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2); - /** Destructor. */ - virtual ~SynthesiserVoice(); + static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3); + static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3); - /** Returns the midi note that this voice is currently playing. + static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); + static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - Returns a value less than 0 if no note is playing. - */ - int getCurrentlyPlayingNote() const throw() { return currentlyPlayingNote; } + static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); + static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4); - /** Returns the sound that this voice is currently playing. + static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2); + static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2); - Returns 0 if it's not playing. - */ - const SynthesiserSound::Ptr getCurrentlyPlayingSound() const throw() { return currentlyPlayingSound; } + static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3); + static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3); - /** Must return true if this voice object is capable of playing the given sound. + static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); + static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - If there are different classes of sound, and different classes of voice, a voice can - choose which ones it wants to take on. + static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); + static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4); - A typical implementation of this method may just return true if there's only one type - of voice and sound, or it might check the type of the sound object passed-in and - see if it's one that it understands. - */ - virtual bool canPlaySound (SynthesiserSound* sound) = 0; + enum DataFormat + { + int16LE, + int16BE, + int24LE, + int24BE, + int32LE, + int32BE, + float32LE, + float32BE, + }; - /** Called to start a new note. + static void convertFloatToFormat (const DataFormat destFormat, + const float* source, void* dest, int numSamples); - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void startNote (const int midiNoteNumber, - const float velocity, - SynthesiserSound* sound, - const int currentPitchWheelPosition) = 0; + static void convertFormatToFloat (const DataFormat sourceFormat, + const void* source, float* dest, int numSamples); - /** Called to stop a note. + static void interleaveSamples (const float** source, float* dest, + const int numSamples, const int numChannels); - This will be called during the rendering callback, so must be fast and thread-safe. - - If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all - sound immediately, and must call clearCurrentNote() to reset the state of this voice - and allow the synth to reassign it another sound. - - If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to - begin fading out its sound, and it can stop playing until it's finished. As soon as it - finishes playing (during the rendering callback), it must make sure that it calls - clearCurrentNote(). - */ - virtual void stopNote (const bool allowTailOff) = 0; - - /** Called to let the voice know that the pitch wheel has been moved. - - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void pitchWheelMoved (const int newValue) = 0; - - /** Called to let the voice know that a midi controller has been moved. - - This will be called during the rendering callback, so must be fast and thread-safe. - */ - virtual void controllerMoved (const int controllerNumber, - const int newValue) = 0; - - /** Renders the next block of data for this voice. - - The output audio data must be added to the current contents of the buffer provided. - Only the region of the buffer between startSample and (startSample + numSamples) - should be altered by this method. - - If the voice is currently silent, it should just return without doing anything. - - If the sound that the voice is playing finishes during the course of this rendered - block, it must call clearCurrentNote(), to tell the synthesiser that it has finished. - - The size of the blocks that are rendered can change each time it is called, and may - involve rendering as little as 1 sample at a time. In between rendering callbacks, - the voice's methods will be called to tell it about note and controller events. - */ - virtual void renderNextBlock (AudioSampleBuffer& outputBuffer, - int startSample, - int numSamples) = 0; - - /** Returns true if the voice is currently playing a sound which is mapped to the given - midi channel. - - If it's not currently playing, this will return false. - */ - bool isPlayingChannel (const int midiChannel) const; - - /** Changes the voice's reference sample rate. - - The rate is set so that subclasses know the output rate and can set their pitch - accordingly. - - This method is called by the synth, and subclasses can access the current rate with - the currentSampleRate member. - */ - void setCurrentPlaybackSampleRate (const double newRate); - - juce_UseDebuggingNewOperator - -protected: - - /** Returns the current target sample rate at which rendering is being done. - - This is available for subclasses so they can pitch things correctly. - */ - double getSampleRate() const throw() { return currentSampleRate; } - - /** Resets the state of this voice after a sound has finished playing. - - The subclass must call this when it finishes playing a note and becomes available - to play new ones. - - It must either call it in the stopNote() method, or if the voice is tailing off, - then it should call it later during the renderNextBlock method, as soon as it - finishes its tail-off. - - It can also be called at any time during the render callback if the sound happens - to have finished, e.g. if it's playing a sample and the sample finishes. - */ - void clearCurrentNote(); - -private: - - friend class Synthesiser; - - double currentSampleRate; - int currentlyPlayingNote; - uint32 noteOnTime; - SynthesiserSound::Ptr currentlyPlayingSound; + static void deinterleaveSamples (const float* source, float** dest, + const int numSamples, const int numChannels); }; -/** - Base class for a musical device that can play sounds. - - To create a synthesiser, you'll need to create a subclass of SynthesiserSound - to describe each sound available to your synth, and a subclass of SynthesiserVoice - which can play back one of these sounds. - - Then you can use the addVoice() and addSound() methods to give the synthesiser a - set of sounds, and a set of voices it can use to play them. If you only give it - one voice it will be monophonic - the more voices it has, the more polyphony it'll - have available. - - Then repeatedly call the renderNextBlock() method to produce the audio. Any midi - events that go in will be scanned for note on/off messages, and these are used to - start and stop the voices playing the appropriate sounds. - - While it's playing, you can also cause notes to be triggered by calling the noteOn(), - noteOff() and other controller methods. - - Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it - what the target playback rate is. This value is passed on to the voices so that - they can pitch their output correctly. -*/ -class JUCE_API Synthesiser -{ -public: - - /** Creates a new synthesiser. - - You'll need to add some sounds and voices before it'll make any sound.. - */ - Synthesiser(); - - /** Destructor. */ - virtual ~Synthesiser(); - - /** Deletes all voices. */ - void clearVoices(); - - /** Returns the number of voices that have been added. */ - int getNumVoices() const throw() { return voices.size(); } - - /** Returns one of the voices that have been added. */ - SynthesiserVoice* getVoice (const int index) const throw(); - - /** Adds a new voice to the synth. - - All the voices should be the same class of object and are treated equally. - - The object passed in will be managed by the synthesiser, which will delete - it later on when no longer needed. The caller should not retain a pointer to the - voice. - */ - void addVoice (SynthesiserVoice* const newVoice); - - /** Deletes one of the voices. */ - void removeVoice (const int index); - - /** Deletes all sounds. */ - void clearSounds(); - - /** Returns the number of sounds that have been added to the synth. */ - int getNumSounds() const throw() { return sounds.size(); } - - /** Returns one of the sounds. */ - SynthesiserSound* getSound (const int index) const throw() { return sounds [index]; } - - /** Adds a new sound to the synthesiser. - - The object passed in is reference counted, so will be deleted when it is removed - from the synthesiser, and when no voices are still using it. - */ - void addSound (const SynthesiserSound::Ptr& newSound); - - /** Removes and deletes one of the sounds. */ - void removeSound (const int index); - - /** If set to true, then the synth will try to take over an existing voice if - it runs out and needs to play another note. - - The value of this boolean is passed into findFreeVoice(), so the result will - depend on the implementation of this method. - */ - void setNoteStealingEnabled (const bool shouldStealNotes); - - /** Returns true if note-stealing is enabled. - @see setNoteStealingEnabled - */ - bool isNoteStealingEnabled() const throw() { return shouldStealNotes; } - - /** Triggers a note-on event. - - The default method here will find all the sounds that want to be triggered by - this note/channel. For each sound, it'll try to find a free voice, and use the - voice to start playing the sound. - - Subclasses might want to override this if they need a more complex algorithm. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - */ - virtual void noteOn (const int midiChannel, - const int midiNoteNumber, - const float velocity); - - /** Triggers a note-off event. - - This will turn off any voices that are playing a sound for the given note/channel. - - If allowTailOff is true, the voices will be allowed to fade out the notes gracefully - (if they can do). If this is false, the notes will all be cut off immediately. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - */ - virtual void noteOff (const int midiChannel, - const int midiNoteNumber, - const bool allowTailOff); - - /** Turns off all notes. - - This will turn off any voices that are playing a sound on the given midi channel. - - If midiChannel is 0 or less, then all voices will be turned off, regardless of - which channel they're playing. - - If allowTailOff is true, the voices will be allowed to fade out the notes gracefully - (if they can do). If this is false, the notes will all be cut off immediately. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - */ - virtual void allNotesOff (const int midiChannel, - const bool allowTailOff); - - /** Sends a pitch-wheel message. - - This will send a pitch-wheel message to any voices that are playing sounds on - the given midi channel. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - @param midiChannel the midi channel for the event - @param wheelValue the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue() - */ - virtual void handlePitchWheel (const int midiChannel, - const int wheelValue); - - /** Sends a midi controller message. - - This will send a midi controller message to any voices that are playing sounds on - the given midi channel. - - This method will be called automatically according to the midi data passed into - renderNextBlock(), but may be called explicitly too. - - @param midiChannel the midi channel for the event - @param controllerNumber the midi controller type, as returned by MidiMessage::getControllerNumber() - @param controllerValue the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue() - */ - virtual void handleController (const int midiChannel, - const int controllerNumber, - const int controllerValue); - - /** Tells the synthesiser what the sample rate is for the audio it's being used to - render. - - This value is propagated to the voices so that they can use it to render the correct - pitches. - */ - void setCurrentPlaybackSampleRate (const double sampleRate); - - /** Creates the next block of audio output. - - This will process the next numSamples of data from all the voices, and add that output - to the audio block supplied, starting from the offset specified. Note that the - data will be added to the current contents of the buffer, so you should clear it - before calling this method if necessary. - - The midi events in the inputMidi buffer are parsed for note and controller events, - and these are used to trigger the voices. Note that the startSample offset applies - both to the audio output buffer and the midi input buffer, so any midi events - with timestamps outside the specified region will be ignored. - */ - void renderNextBlock (AudioSampleBuffer& outputAudio, - const MidiBuffer& inputMidi, - int startSample, - int numSamples); - - juce_UseDebuggingNewOperator - -protected: - - /** This is used to control access to the rendering callback and the note trigger methods. */ - CriticalSection lock; - - OwnedArray voices; - ReferenceCountedArray sounds; - - /** The last pitch-wheel values for each midi channel. */ - int lastPitchWheelValues [16]; - - /** Searches through the voices to find one that's not currently playing, and which - can play the given sound. - - Returns 0 if all voices are busy and stealing isn't enabled. - - This can be overridden to implement custom voice-stealing algorithms. - */ - virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay, - const bool stealIfNoneAvailable) const; - - /** Starts a specified voice playing a particular sound. - - You'll probably never need to call this, it's used internally by noteOn(), but - may be needed by subclasses for custom behaviours. - */ - void startVoice (SynthesiserVoice* const voice, - SynthesiserSound* const sound, - const int midiChannel, - const int midiNoteNumber, - const float velocity); - - /** xxx Temporary method here to cause a compiler error - note the new parameters for this method. */ - int findFreeVoice (const bool) const { return 0; } - -private: - double sampleRate; - uint32 lastNoteOnCounter; - bool shouldStealNotes; - - Synthesiser (const Synthesiser&); - const Synthesiser& operator= (const Synthesiser&); -}; - -#endif // __JUCE_SYNTHESISER_JUCEHEADER__ -/********* End of inlined file: juce_Synthesiser.h *********/ - -/** - A subclass of SynthesiserSound that represents a sampled audio clip. - - This is a pretty basic sampler, and just attempts to load the whole audio stream - into memory. - - To use it, create a Synthesiser, add some SamplerVoice objects to it, then - give it some SampledSound objects to play. - - @see SamplerVoice, Synthesiser, SynthesiserSound -*/ -class JUCE_API SamplerSound : public SynthesiserSound -{ -public: - - /** Creates a sampled sound from an audio reader. - - This will attempt to load the audio from the source into memory and store - it in this object. - - @param name a name for the sample - @param source the audio to load. This object can be safely deleted by the - caller after this constructor returns - @param midiNotes the set of midi keys that this sound should be played on. This - is used by the SynthesiserSound::appliesToNote() method - @param midiNoteForNormalPitch the midi note at which the sample should be played - with its natural rate. All other notes will be pitched - up or down relative to this one - @param attackTimeSecs the attack (fade-in) time, in seconds - @param releaseTimeSecs the decay (fade-out) time, in seconds - @param maxSampleLengthSeconds a maximum length of audio to read from the audio - source, in seconds - */ - SamplerSound (const String& name, - AudioFormatReader& source, - const BitArray& midiNotes, - const int midiNoteForNormalPitch, - const double attackTimeSecs, - const double releaseTimeSecs, - const double maxSampleLengthSeconds); - - /** Destructor. */ - ~SamplerSound(); - - /** Returns the sample's name */ - const String& getName() const throw() { return name; } - - /** Returns the audio sample data. - This could be 0 if there was a problem loading it. - */ - AudioSampleBuffer* getAudioData() const throw() { return data; } - - bool appliesToNote (const int midiNoteNumber); - bool appliesToChannel (const int midiChannel); - - juce_UseDebuggingNewOperator - -private: - friend class SamplerVoice; - - String name; - AudioSampleBuffer* data; - double sourceSampleRate; - BitArray midiNotes; - int length, attackSamples, releaseSamples; - int midiRootNote; -}; - -/** - A subclass of SynthesiserVoice that can play a SamplerSound. - - To use it, create a Synthesiser, add some SamplerVoice objects to it, then - give it some SampledSound objects to play. - - @see SamplerSound, Synthesiser, SynthesiserVoice -*/ -class JUCE_API SamplerVoice : public SynthesiserVoice -{ -public: - - /** Creates a SamplerVoice. - */ - SamplerVoice(); - - /** Destructor. */ - ~SamplerVoice(); - - bool canPlaySound (SynthesiserSound* sound); - - void startNote (const int midiNoteNumber, - const float velocity, - SynthesiserSound* sound, - const int currentPitchWheelPosition); - - void stopNote (const bool allowTailOff); - - void pitchWheelMoved (const int newValue); - void controllerMoved (const int controllerNumber, - const int newValue); - - void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples); - - juce_UseDebuggingNewOperator - -private: - double pitchRatio; - double sourceSamplePosition; - float lgain, rgain, attackReleaseLevel, attackDelta, releaseDelta; - bool isInAttack, isInRelease; -}; - -#endif // __JUCE_SAMPLER_JUCEHEADER__ -/********* End of inlined file: juce_Sampler.h *********/ +#endif // __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ +/********* End of inlined file: juce_AudioDataConverters.h *********/ #endif -#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ +#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ + +#endif +#ifndef __JUCE_IIRFILTER_JUCEHEADER__ + +#endif +#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ + +#endif +#ifndef __JUCE_MIDIFILE_JUCEHEADER__ + +/********* Start of inlined file: juce_MidiFile.h *********/ +#ifndef __JUCE_MIDIFILE_JUCEHEADER__ +#define __JUCE_MIDIFILE_JUCEHEADER__ + +/********* Start of inlined file: juce_MidiMessageSequence.h *********/ +#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ +#define __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ + +/** + A sequence of timestamped midi messages. + + This allows the sequence to be manipulated, and also to be read from and + written to a standard midi file. + + @see MidiMessage, MidiFile +*/ +class JUCE_API MidiMessageSequence +{ +public: + + /** Creates an empty midi sequence object. */ + MidiMessageSequence(); + + /** Creates a copy of another sequence. */ + MidiMessageSequence (const MidiMessageSequence& other); + + /** Replaces this sequence with another one. */ + const MidiMessageSequence& operator= (const MidiMessageSequence& other); + + /** Destructor. */ + ~MidiMessageSequence(); + + /** Structure used to hold midi events in the sequence. + + These structures act as 'handles' on the events as they are moved about in + the list, and make it quick to find the matching note-offs for note-on events. + + @see MidiMessageSequence::getEventPointer + */ + class MidiEventHolder + { + public: + + /** Destructor. */ + ~MidiEventHolder(); + + /** The message itself, whose timestamp is used to specify the event's time. + */ + MidiMessage message; + + /** The matching note-off event (if this is a note-on event). + + If this isn't a note-on, this pointer will be null. + + Use the MidiMessageSequence::updateMatchedPairs() method to keep these + note-offs up-to-date after events have been moved around in the sequence + or deleted. + */ + MidiEventHolder* noteOffObject; + + juce_UseDebuggingNewOperator + + private: + friend class MidiMessageSequence; + MidiEventHolder (const MidiMessage& message); + }; + + /** Clears the sequence. */ + void clear(); + + /** Returns the number of events in the sequence. */ + int getNumEvents() const; + + /** Returns a pointer to one of the events. */ + MidiEventHolder* getEventPointer (const int index) const; + + /** Returns the time of the note-up that matches the note-on at this index. + + If the event at this index isn't a note-on, it'll just return 0. + + @see MidiMessageSequence::MidiEventHolder::noteOffObject + */ + double getTimeOfMatchingKeyUp (const int index) const; + + /** Returns the index of the note-up that matches the note-on at this index. + + If the event at this index isn't a note-on, it'll just return -1. + + @see MidiMessageSequence::MidiEventHolder::noteOffObject + */ + int getIndexOfMatchingKeyUp (const int index) const; + + /** Returns the index of an event. */ + int getIndexOf (MidiEventHolder* const event) const; + + /** Returns the index of the first event on or after the given timestamp. + + If the time is beyond the end of the sequence, this will return the + number of events. + */ + int getNextIndexAtTime (const double timeStamp) const; + + /** Returns the timestamp of the first event in the sequence. + + @see getEndTime + */ + double getStartTime() const; + + /** Returns the timestamp of the last event in the sequence. + + @see getStartTime + */ + double getEndTime() const; + + /** Returns the timestamp of the event at a given index. + + If the index is out-of-range, this will return 0.0 + */ + double getEventTime (const int index) const; + + /** Inserts a midi message into the sequence. + + The index at which the new message gets inserted will depend on its timestamp, + because the sequence is kept sorted. + + Remember to call updateMatchedPairs() after adding note-on events. + + @param newMessage the new message to add (an internal copy will be made) + @param timeAdjustment an optional value to add to the timestamp of the message + that will be inserted + @see updateMatchedPairs + */ + void addEvent (const MidiMessage& newMessage, + double timeAdjustment = 0); + + /** Deletes one of the events in the sequence. + + Remember to call updateMatchedPairs() after removing events. + + @param index the index of the event to delete + @param deleteMatchingNoteUp whether to also remove the matching note-off + if the event you're removing is a note-on + */ + void deleteEvent (const int index, + const bool deleteMatchingNoteUp); + + /** Merges another sequence into this one. + + Remember to call updateMatchedPairs() after using this method. + + @param other the sequence to add from + @param timeAdjustmentDelta an amount to add to the timestamps of the midi events + as they are read from the other sequence + @param firstAllowableDestTime events will not be added if their time is earlier + than this time. (This is after their time has been adjusted + by the timeAdjustmentDelta) + @param endOfAllowableDestTimes events will not be added if their time is equal to + or greater than this time. (This is after their time has + been adjusted by the timeAdjustmentDelta) + */ + void addSequence (const MidiMessageSequence& other, + double timeAdjustmentDelta, + double firstAllowableDestTime, + double endOfAllowableDestTimes); + + /** Makes sure all the note-on and note-off pairs are up-to-date. + + Call this after moving messages about or deleting/adding messages, and it + will scan the list and make sure all the note-offs in the MidiEventHolder + structures are pointing at the correct ones. + */ + void updateMatchedPairs(); + + /** Copies all the messages for a particular midi channel to another sequence. + + @param channelNumberToExtract the midi channel to look for, in the range 1 to 16 + @param destSequence the sequence that the chosen events should be copied to + @param alsoIncludeMetaEvents if true, any meta-events (which don't apply to a specific + channel) will also be copied across. + @see extractSysExMessages + */ + void extractMidiChannelMessages (const int channelNumberToExtract, + MidiMessageSequence& destSequence, + const bool alsoIncludeMetaEvents) const; + + /** Copies all midi sys-ex messages to another sequence. + + @param destSequence this is the sequence to which any sys-exes in this sequence + will be added + @see extractMidiChannelMessages + */ + void extractSysExMessages (MidiMessageSequence& destSequence) const; + + /** Removes any messages in this sequence that have a specific midi channel. + + @param channelNumberToRemove the midi channel to look for, in the range 1 to 16 + */ + void deleteMidiChannelMessages (const int channelNumberToRemove); + + /** Removes any sys-ex messages from this sequence. + */ + void deleteSysExMessages(); + + /** Adds an offset to the timestamps of all events in the sequence. + + @param deltaTime the amount to add to each timestamp. + */ + void addTimeToMessages (const double deltaTime); + + /** Scans through the sequence to determine the state of any midi controllers at + a given time. + + This will create a sequence of midi controller changes that can be + used to set all midi controllers to the state they would be in at the + specified time within this sequence. + + As well as controllers, it will also recreate the midi program number + and pitch bend position. + + @param channelNumber the midi channel to look for, in the range 1 to 16. Controllers + for other channels will be ignored. + @param time the time at which you want to find out the state - there are + no explicit units for this time measurement, it's the same units + as used for the timestamps of the messages + @param resultMessages an array to which midi controller-change messages will be added. This + will be the minimum number of controller changes to recreate the + state at the required time. + */ + void createControllerUpdatesForTime (const int channelNumber, + const double time, + OwnedArray& resultMessages); + + juce_UseDebuggingNewOperator + + /** @internal */ + static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, + const MidiMessageSequence::MidiEventHolder* const second) throw(); + +private: + + friend class MidiComparator; + friend class MidiFile; + OwnedArray list; + + void sort(); +}; + +#endif // __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ +/********* End of inlined file: juce_MidiMessageSequence.h *********/ + +/** + Reads/writes standard midi format files. + + To read a midi file, create a MidiFile object and call its readFrom() method. You + can then get the individual midi tracks from it using the getTrack() method. + + To write a file, create a MidiFile object, add some MidiMessageSequence objects + to it using the addTrack() method, and then call its writeTo() method to stream + it out. + + @see MidiMessageSequence +*/ +class JUCE_API MidiFile +{ +public: + + /** Creates an empty MidiFile object. + */ + MidiFile() throw(); + + /** Destructor. */ + ~MidiFile() throw(); + + /** Returns the number of tracks in the file. + + @see getTrack, addTrack + */ + int getNumTracks() const throw(); + + /** Returns a pointer to one of the tracks in the file. + + @returns a pointer to the track, or 0 if the index is out-of-range + @see getNumTracks, addTrack + */ + const MidiMessageSequence* getTrack (const int index) const throw(); + + /** Adds a midi track to the file. + + This will make its own internal copy of the sequence that is passed-in. + + @see getNumTracks, getTrack + */ + void addTrack (const MidiMessageSequence& trackSequence) throw(); + + /** Removes all midi tracks from the file. + + @see getNumTracks + */ + void clear() throw(); + + /** Returns the raw time format code that will be written to a stream. + + After reading a midi file, this method will return the time-format that + was read from the file's header. It can be changed using the setTicksPerQuarterNote() + or setSmpteTimeFormat() methods. + + If the value returned is positive, it indicates the number of midi ticks + per quarter-note - see setTicksPerQuarterNote(). + + It it's negative, the upper byte indicates the frames-per-second (but negative), and + the lower byte is the number of ticks per frame - see setSmpteTimeFormat(). + */ + short getTimeFormat() const throw(); + + /** Sets the time format to use when this file is written to a stream. + + If this is called, the file will be written as bars/beats using the + specified resolution, rather than SMPTE absolute times, as would be + used if setSmpteTimeFormat() had been called instead. + + @param ticksPerQuarterNote e.g. 96, 960 + @see setSmpteTimeFormat + */ + void setTicksPerQuarterNote (const int ticksPerQuarterNote) throw(); + + /** Sets the time format to use when this file is written to a stream. + + If this is called, the file will be written using absolute times, rather + than bars/beats as would be the case if setTicksPerBeat() had been called + instead. + + @param framesPerSecond must be 24, 25, 29 or 30 + @param subframeResolution the sub-second resolution, e.g. 4 (midi time code), + 8, 10, 80 (SMPTE bit resolution), or 100. For millisecond + timing, setSmpteTimeFormat (25, 40) + @see setTicksPerBeat + */ + void setSmpteTimeFormat (const int framesPerSecond, + const int subframeResolution) throw(); + + /** Makes a list of all the tempo-change meta-events from all tracks in the midi file. + + Useful for finding the positions of all the tempo changes in a file. + + @param tempoChangeEvents a list to which all the events will be added + */ + void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const; + + /** Makes a list of all the time-signature meta-events from all tracks in the midi file. + + Useful for finding the positions of all the tempo changes in a file. + + @param timeSigEvents a list to which all the events will be added + */ + void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const; + + /** Returns the latest timestamp in any of the tracks. + + (Useful for finding the length of the file). + */ + double getLastTimestamp() const; + + /** Reads a midi file format stream. + + After calling this, you can get the tracks that were read from the file by using the + getNumTracks() and getTrack() methods. + + The timestamps of the midi events in the tracks will represent their positions in + terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds() + method. + + @returns true if the stream was read successfully + */ + bool readFrom (InputStream& sourceStream); + + /** Writes the midi tracks as a standard midi file. + + @returns true if the operation succeeded. + */ + bool writeTo (OutputStream& destStream); + + /** Converts the timestamp of all the midi events from midi ticks to seconds. + + This will use the midi time format and tempo/time signature info in the + tracks to convert all the timestamps to absolute values in seconds. + */ + void convertTimestampTicksToSeconds(); + + juce_UseDebuggingNewOperator + + /** @internal */ + static int compareElements (const MidiMessageSequence::MidiEventHolder* const first, + const MidiMessageSequence::MidiEventHolder* const second) throw(); + +private: + MidiMessageSequence* tracks [128]; + short numTracks, timeFormat; + + MidiFile (const MidiFile&); + const MidiFile& operator= (const MidiFile&); + + void readNextTrack (const char* data, int size); + void writeTrack (OutputStream& mainOut, const int trackNum); +}; + +#endif // __JUCE_MIDIFILE_JUCEHEADER__ +/********* End of inlined file: juce_MidiFile.h *********/ + +#endif +#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ + +/********* Start of inlined file: juce_MidiKeyboardState.h *********/ +#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ +#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ + +class MidiKeyboardState; + +/** + Receives events from a MidiKeyboardState object. + + @see MidiKeyboardState +*/ +class JUCE_API MidiKeyboardStateListener +{ +public: + + MidiKeyboardStateListener() throw() {} + virtual ~MidiKeyboardStateListener() {} + + /** Called when one of the MidiKeyboardState's keys is pressed. + + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOn() method. + + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. + */ + virtual void handleNoteOn (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber, float velocity) = 0; + + /** Called when one of the MidiKeyboardState's keys is released. + + This will be called synchronously when the state is either processing a + buffer in its MidiKeyboardState::processNextMidiBuffer() method, or + when a note is being played with its MidiKeyboardState::noteOff() method. + + Note that this callback could happen from an audio callback thread, so be + careful not to block, and avoid any UI activity in the callback. + */ + virtual void handleNoteOff (MidiKeyboardState* source, + int midiChannel, int midiNoteNumber) = 0; +}; + +/** + Represents a piano keyboard, keeping track of which keys are currently pressed. + + This object can parse a stream of midi events, using them to update its idea + of which keys are pressed for each individiual midi channel. + + When keys go up or down, it can broadcast these events to listener objects. + + It also allows key up/down events to be triggered with its noteOn() and noteOff() + methods, and midi messages for these events will be merged into the + midi stream that gets processed by processNextMidiBuffer(). +*/ +class JUCE_API MidiKeyboardState +{ +public: + + MidiKeyboardState(); + ~MidiKeyboardState(); + + /** Resets the state of the object. + + All internal data for all the channels is reset, but no events are sent as a + result. + + If you want to release any keys that are currently down, and to send out note-up + midi messages for this, use the allNotesOff() method instead. + */ + void reset(); + + /** Returns true if the given midi key is currently held down for the given midi channel. + + The channel number must be between 1 and 16. If you want to see if any notes are + on for a range of channels, use the isNoteOnForChannels() method. + */ + bool isNoteOn (const int midiChannel, const int midiNoteNumber) const throw(); + + /** Returns true if the given midi key is currently held down on any of a set of midi channels. + + The channel mask has a bit set for each midi channel you want to test for - bit + 0 = midi channel 1, bit 1 = midi channel 2, etc. + + If a note is on for at least one of the specified channels, this returns true. + */ + bool isNoteOnForChannels (const int midiChannelMask, const int midiNoteNumber) const throw(); + + /** Turns a specified note on. + + This will cause a suitable midi note-on event to be injected into the midi buffer during the + next call to processNextMidiBuffer(). + + It will also trigger a synchronous callback to the listeners to tell them that the key has + gone down. + */ + void noteOn (const int midiChannel, const int midiNoteNumber, const float velocity); + + /** Turns a specified note off. + + This will cause a suitable midi note-off event to be injected into the midi buffer during the + next call to processNextMidiBuffer(). + + It will also trigger a synchronous callback to the listeners to tell them that the key has + gone up. + + But if the note isn't acutally down for the given channel, this method will in fact do nothing. + */ + void noteOff (const int midiChannel, const int midiNoteNumber); + + /** This will turn off any currently-down notes for the given midi channel. + + If you pass 0 for the midi channel, it will in fact turn off all notes on all channels. + + Calling this method will make calls to noteOff(), so can trigger synchronous callbacks + and events being added to the midi stream. + */ + void allNotesOff (const int midiChannel); + + /** Looks at a key-up/down event and uses it to update the state of this object. + + To process a buffer full of midi messages, use the processNextMidiBuffer() method + instead. + */ + void processNextMidiEvent (const MidiMessage& message); + + /** Scans a midi stream for up/down events and adds its own events to it. + + This will look for any up/down events and use them to update the internal state, + synchronously making suitable callbacks to the listeners. + + If injectIndirectEvents is true, then midi events to produce the recent noteOn() + and noteOff() calls will be added into the buffer. + + Only the section of the buffer whose timestamps are between startSample and + (startSample + numSamples) will be affected, and any events added will be placed + between these times. + + If you're going to use this method, you'll need to keep calling it regularly for + it to work satisfactorily. + + To process a single midi event at a time, use the processNextMidiEvent() method + instead. + */ + void processNextMidiBuffer (MidiBuffer& buffer, + const int startSample, + const int numSamples, + const bool injectIndirectEvents); + + /** Registers a listener for callbacks when keys go up or down. + + @see removeListener + */ + void addListener (MidiKeyboardStateListener* const listener) throw(); + + /** Deregisters a listener. + + @see addListener + */ + void removeListener (MidiKeyboardStateListener* const listener) throw(); + + juce_UseDebuggingNewOperator + +private: + CriticalSection lock; + uint16 noteStates [128]; + MidiBuffer eventsToAdd; + VoidArray listeners; + + void noteOnInternal (const int midiChannel, const int midiNoteNumber, const float velocity); + void noteOffInternal (const int midiChannel, const int midiNoteNumber); + + MidiKeyboardState (const MidiKeyboardState&); + const MidiKeyboardState& operator= (const MidiKeyboardState&); +}; + +#endif // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ +/********* End of inlined file: juce_MidiKeyboardState.h *********/ + +#endif +#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ + +#endif +#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ + +/********* Start of inlined file: juce_MidiMessageCollector.h *********/ +#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ +#define __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ + +/** + Collects incoming realtime MIDI messages and turns them into blocks suitable for + processing by a block-based audio callback. + + The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback + so it can easily use a midi input or keyboard component as its source. + + @see MidiMessage, MidiInput +*/ +class JUCE_API MidiMessageCollector : public MidiKeyboardStateListener, + public MidiInputCallback +{ +public: + + /** Creates a MidiMessageCollector. */ + MidiMessageCollector(); + + /** Destructor. */ + ~MidiMessageCollector(); + + /** Clears any messages from the queue. + + You need to call this method before starting to use the collector, so that + it knows the correct sample rate to use. + */ + void reset (const double sampleRate); + + /** Takes an incoming real-time message and adds it to the queue. + + The message's timestamp is taken, and it will be ready for retrieval as part + of the block returned by the next call to removeNextBlockOfMessages(). + + This method is fully thread-safe when overlapping calls are made with + removeNextBlockOfMessages(). + */ + void addMessageToQueue (const MidiMessage& message); + + /** Removes all the pending messages from the queue as a buffer. + + This will also correct the messages' timestamps to make sure they're in + the range 0 to numSamples - 1. + + This call should be made regularly by something like an audio processing + callback, because the time that it happens is used in calculating the + midi event positions. + + This method is fully thread-safe when overlapping calls are made with + addMessageToQueue(). + */ + void removeNextBlockOfMessages (MidiBuffer& destBuffer, + const int numSamples); + + /** @internal */ + void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity); + /** @internal */ + void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber); + /** @internal */ + void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); + + juce_UseDebuggingNewOperator + +private: + double lastCallbackTime; + CriticalSection midiCallbackLock; + MidiBuffer incomingMessages; + double sampleRate; + + MidiMessageCollector (const MidiMessageCollector&); + const MidiMessageCollector& operator= (const MidiMessageCollector&); +}; + +#endif // __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ +/********* End of inlined file: juce_MidiMessageCollector.h *********/ + +#endif +#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ #endif #ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ @@ -36322,6 +35355,991 @@ private: #ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ #define __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ +/********* Start of inlined file: juce_AudioPluginFormat.h *********/ +#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ +#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioPluginInstance.h *********/ +#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ +#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioProcessor.h *********/ +#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSOR_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioProcessorEditor.h *********/ +#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ + +class AudioProcessor; + +/** + Base class for the component that acts as the GUI for an AudioProcessor. + + Derive your editor component from this class, and create an instance of it + by overriding the AudioProcessor::createEditor() method. + + @see AudioProcessor, GenericAudioProcessorEditor +*/ +class JUCE_API AudioProcessorEditor : public Component +{ +protected: + + /** Creates an editor for the specified processor. + */ + AudioProcessorEditor (AudioProcessor* const owner); + +public: + /** Destructor. */ + ~AudioProcessorEditor(); + + /** Returns a pointer to the processor that this editor represents. */ + AudioProcessor* getAudioProcessor() const throw() { return owner; } + +private: + + AudioProcessor* const owner; +}; + +#endif // __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ +/********* End of inlined file: juce_AudioProcessorEditor.h *********/ + +/********* Start of inlined file: juce_AudioProcessorListener.h *********/ +#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ + +class AudioProcessor; + +/** + Base class for listeners that want to know about changes to an AudioProcessor. + + Use AudioProcessor::addListener() to register your listener with an AudioProcessor. + + @see AudioProcessor +*/ +class JUCE_API AudioProcessorListener +{ +public: + + /** Destructor. */ + virtual ~AudioProcessorListener() {} + + /** Receives a callback when a parameter is changed. + + IMPORTANT NOTE: this will be called synchronously when a parameter changes, and + many audio processors will change their parameter during their audio callback. + This means that not only has your handler code got to be completely thread-safe, + but it's also got to be VERY fast, and avoid blocking. If you need to handle + this event on your message thread, use this callback to trigger an AsyncUpdater + or ChangeBroadcaster which you can respond to on the message thread. + */ + virtual void audioProcessorParameterChanged (AudioProcessor* processor, + int parameterIndex, + float newValue) = 0; + + /** Called to indicate that something else in the plugin has changed, like its + program, number of parameters, etc. + + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. + */ + virtual void audioProcessorChanged (AudioProcessor* processor) = 0; + + /** Indicates that a parameter change gesture has started. + + E.g. if the user is dragging a slider, this would be called when they first + press the mouse button, and audioProcessorParameterChangeGestureEnd would be + called when they release it. + + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. + + @see audioProcessorParameterChangeGestureEnd + */ + virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor, + int parameterIndex); + + /** Indicates that a parameter change gesture has finished. + + E.g. if the user is dragging a slider, this would be called when they release + the mouse button. + + IMPORTANT NOTE: this will be called synchronously, and many audio processors will + call it during their audio callback. This means that not only has your handler code + got to be completely thread-safe, but it's also got to be VERY fast, and avoid + blocking. If you need to handle this event on your message thread, use this callback + to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the + message thread. + + @see audioPluginParameterChangeGestureStart + */ + virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor, + int parameterIndex); +}; + +#endif // __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ +/********* End of inlined file: juce_AudioProcessorListener.h *********/ + +/********* Start of inlined file: juce_AudioPlayHead.h *********/ +#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ +#define __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ + +/** + A subclass of AudioPlayHead can supply information about the position and + status of a moving play head during audio playback. + + One of these can be supplied to an AudioProcessor object so that it can find + out about the position of the audio that it is rendering. + + @see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead +*/ +class JUCE_API AudioPlayHead +{ +protected: + + AudioPlayHead() {} + +public: + virtual ~AudioPlayHead() {} + + /** Frame rate types. */ + enum FrameRateType + { + fps24 = 0, + fps25 = 1, + fps2997 = 2, + fps30 = 3, + fps2997drop = 4, + fps30drop = 5, + fpsUnknown = 99 + }; + + /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method. + */ + struct CurrentPositionInfo + { + /** The tempo in BPM */ + double bpm; + + /** Time signature numerator, e.g. the 3 of a 3/4 time sig */ + int timeSigNumerator; + /** Time signature denominator, e.g. the 4 of a 3/4 time sig */ + int timeSigDenominator; + + /** The current play position, in seconds from the start of the edit. */ + double timeInSeconds; + + /** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */ + double editOriginTime; + + /** The current play position in pulses-per-quarter-note. + + This is the number of quarter notes since the edit start. + */ + double ppqPosition; + + /** The position of the start of the last bar, in pulses-per-quarter-note. + + This is the number of quarter notes from the start of the edit to the + start of the current bar. + + Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If + it's not available, the value will be 0. + */ + double ppqPositionOfLastBarStart; + + /** The video frame rate, if applicable. */ + FrameRateType frameRate; + + /** True if the transport is currently playing. */ + bool isPlaying; + + /** True if the transport is currently recording. + + (When isRecording is true, then isPlaying will also be true). + */ + bool isRecording; + }; + + /** Fills-in the given structure with details about the transport's + position at the start of the current processing block. + */ + virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0; +}; + +#endif // __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ +/********* End of inlined file: juce_AudioPlayHead.h *********/ + +/** + Base class for audio processing filters or plugins. + + This is intended to act as a base class of audio filter that is general enough to + be wrapped as a VST, AU, RTAS, etc, or used internally. + + It is also used by the plugin hosting code as the wrapper around an instance + of a loaded plugin. + + Derive your filter class from this base class, and if you're building a plugin, + you should implement a global function called createPluginFilter() which creates + and returns a new instance of your subclass. +*/ +class JUCE_API AudioProcessor +{ +protected: + + /** Constructor. + + You can also do your initialisation tasks in the initialiseFilterInfo() + call, which will be made after this object has been created. + */ + AudioProcessor(); + +public: + /** Destructor. */ + virtual ~AudioProcessor(); + + /** Returns the name of this processor. + */ + virtual const String getName() const = 0; + + /** Called before playback starts, to let the filter prepare itself. + + The sample rate is the target sample rate, and will remain constant until + playback stops. + + The estimatedSamplesPerBlock value is a HINT about the typical number of + samples that will be processed for each callback, but isn't any kind + of guarantee. The actual block sizes that the host uses may be different + each time the callback happens, and may be more or less than this value. + */ + virtual void prepareToPlay (double sampleRate, + int estimatedSamplesPerBlock) = 0; + + /** Called after playback has stopped, to let the filter free up any resources it + no longer needs. + */ + virtual void releaseResources() = 0; + + /** Renders the next block. + + When this method is called, the buffer contains a number of channels which is + at least as great as the maximum number of input and output channels that + this filter is using. It will be filled with the filter's input data and + should be replaced with the filter's output. + + So for example if your filter has 2 input channels and 4 output channels, then + the buffer will contain 4 channels, the first two being filled with the + input data. Your filter should read these, do its processing, and replace + the contents of all 4 channels with its output. + + Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels, + all filled with data, and your filter should overwrite the first 2 of these + with its output. But be VERY careful not to write anything to the last 3 + channels, as these might be mapped to memory that the host assumes is read-only! + + Note that if you have more outputs than inputs, then only those channels that + correspond to an input channel are guaranteed to contain sensible data - e.g. + in the case of 2 inputs and 4 outputs, the first two channels contain the input, + but the last two channels may contain garbage, so you should be careful not to + let this pass through without being overwritten or cleared. + + Also note that the buffer may have more channels than are strictly necessary, + but your should only read/write from the ones that your filter is supposed to + be using. + + The number of samples in these buffers is NOT guaranteed to be the same for every + callback, and may be more or less than the estimated value given to prepareToPlay(). + Your code must be able to cope with variable-sized blocks, or you're going to get + clicks and crashes! + + If the filter is receiving a midi input, then the midiMessages array will be filled + with the midi messages for this block. Each message's timestamp will indicate the + message's time, as a number of samples from the start of the block. + + Any messages left in the midi buffer when this method has finished are assumed to + be the filter's midi output. This means that your filter should be careful to + clear any incoming messages from the array if it doesn't want them to be passed-on. + + Be very careful about what you do in this callback - it's going to be called by + the audio thread, so any kind of interaction with the UI is absolutely + out of the question. If you change a parameter in here and need to tell your UI to + update itself, the best way is probably to inherit from a ChangeBroadcaster, let + the UI components register as listeners, and then call sendChangeMessage() inside the + processBlock() method to send out an asynchronous message. You could also use + the AsyncUpdater class in a similar way. + */ + virtual void processBlock (AudioSampleBuffer& buffer, + MidiBuffer& midiMessages) = 0; + + /** Returns the current AudioPlayHead object that should be used to find + out the state and position of the playhead. + + You can call this from your processBlock() method, and use the AudioPlayHead + object to get the details about the time of the start of the block currently + being processed. + + If the host hasn't supplied a playhead object, this will return 0. + */ + AudioPlayHead* getPlayHead() const throw() { return playHead; } + + /** Returns the current sample rate. + + This can be called from your processBlock() method - it's not guaranteed + to be valid at any other time, and may return 0 if it's unknown. + */ + double getSampleRate() const throw() { return sampleRate; } + + /** Returns the current typical block size that is being used. + + This can be called from your processBlock() method - it's not guaranteed + to be valid at any other time. + + Remember it's not the ONLY block size that may be used when calling + processBlock, it's just the normal one. The actual block sizes used may be + larger or smaller than this, and will vary between successive calls. + */ + int getBlockSize() const throw() { return blockSize; } + + /** Returns the number of input channels that the host will be sending the filter. + + If writing a plugin, your JucePluginCharacteristics.h file should specify the + number of channels that your filter would prefer to have, and this method lets + you know how many the host is actually using. + + Note that this method is only valid during or after the prepareToPlay() + method call. Until that point, the number of channels will be unknown. + */ + int getNumInputChannels() const throw() { return numInputChannels; } + + /** Returns the number of output channels that the host will be sending the filter. + + If writing a plugin, your JucePluginCharacteristics.h file should specify the + number of channels that your filter would prefer to have, and this method lets + you know how many the host is actually using. + + Note that this method is only valid during or after the prepareToPlay() + method call. Until that point, the number of channels will be unknown. + */ + int getNumOutputChannels() const throw() { return numOutputChannels; } + + /** Returns the name of one of the input channels, as returned by the host. + + The host might not supply very useful names for channels, and this might be + something like "1", "2", "left", "right", etc. + */ + virtual const String getInputChannelName (const int channelIndex) const = 0; + + /** Returns the name of one of the output channels, as returned by the host. + + The host might not supply very useful names for channels, and this might be + something like "1", "2", "left", "right", etc. + */ + virtual const String getOutputChannelName (const int channelIndex) const = 0; + + /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ + virtual bool isInputChannelStereoPair (int index) const = 0; + + /** Returns true if the specified channel is part of a stereo pair with its neighbour. */ + virtual bool isOutputChannelStereoPair (int index) const = 0; + + /** This returns the number of samples delay that the filter imposes on the audio + passing through it. + + The host will call this to find the latency - the filter itself should set this value + by calling setLatencySamples() as soon as it can during its initialisation. + */ + int getLatencySamples() const throw() { return latencySamples; } + + /** The filter should call this to set the number of samples delay that it introduces. + + The filter should call this as soon as it can during initialisation, and can call it + later if the value changes. + */ + void setLatencySamples (const int newLatency); + + /** Returns true if the processor wants midi messages. */ + virtual bool acceptsMidi() const = 0; + + /** Returns true if the processor produces midi messages. */ + virtual bool producesMidi() const = 0; + + /** This returns a critical section that will automatically be locked while the host + is calling the processBlock() method. + + Use it from your UI or other threads to lock access to variables that are used + by the process callback, but obviously be careful not to keep it locked for + too long, because that could cause stuttering playback. If you need to do something + that'll take a long time and need the processing to stop while it happens, use the + suspendProcessing() method instead. + + @see suspendProcessing + */ + const CriticalSection& getCallbackLock() const throw() { return callbackLock; } + + /** Enables and disables the processing callback. + + If you need to do something time-consuming on a thread and would like to make sure + the audio processing callback doesn't happen until you've finished, use this + to disable the callback and re-enable it again afterwards. + + E.g. + @code + void loadNewPatch() + { + suspendProcessing (true); + + ..do something that takes ages.. + + suspendProcessing (false); + } + @endcode + + If the host tries to make an audio callback while processing is suspended, the + filter will return an empty buffer, but won't block the audio thread like it would + do if you use the getCallbackLock() critical section to synchronise access. + + If you're going to use this, your processBlock() method must call isSuspended() and + check whether it's suspended or not. If it is, then it should skip doing any real + processing, either emitting silence or passing the input through unchanged. + + @see getCallbackLock + */ + void suspendProcessing (const bool shouldBeSuspended); + + /** Returns true if processing is currently suspended. + @see suspendProcessing + */ + bool isSuspended() const throw() { return suspended; } + + /** A plugin can override this to be told when it should reset any playing voices. + + The default implementation does nothing, but a host may call this to tell the + plugin that it should stop any tails or sounds that have been left running. + */ + virtual void reset(); + + /** Returns true if the processor is being run in an offline mode for rendering. + + If the processor is being run live on realtime signals, this returns false. + If the mode is unknown, this will assume it's realtime and return false. + + This value may be unreliable until the prepareToPlay() method has been called, + and could change each time prepareToPlay() is called. + + @see setNonRealtime() + */ + bool isNonRealtime() const throw() { return nonRealtime; } + + /** Called by the host to tell this processor whether it's being used in a non-realime + capacity for offline rendering or bouncing. + + Whatever value is passed-in will be + */ + void setNonRealtime (const bool isNonRealtime) throw(); + + /** Creates the filter's UI. + + This can return 0 if you want a UI-less filter, in which case the host may create + a generic UI that lets the user twiddle the parameters directly. + + If you do want to pass back a component, the component should be created and set to + the correct size before returning it. + + Remember not to do anything silly like allowing your filter to keep a pointer to + the component that gets created - it could be deleted later without any warning, which + would make your pointer into a dangler. Use the getActiveEditor() method instead. + + The correct way to handle the connection between an editor component and its + filter is to use something like a ChangeBroadcaster so that the editor can + register itself as a listener, and be told when a change occurs. This lets them + safely unregister themselves when they are deleted. + + Here are a few things to bear in mind when writing an editor: + + - Initially there won't be an editor, until the user opens one, or they might + not open one at all. Your filter mustn't rely on it being there. + - An editor object may be deleted and a replacement one created again at any time. + - It's safe to assume that an editor will be deleted before its filter. + */ + virtual AudioProcessorEditor* createEditor() = 0; + + /** Returns the active editor, if there is one. + + Bear in mind this can return 0, even if an editor has previously been + opened. + */ + AudioProcessorEditor* getActiveEditor() const throw() { return activeEditor; } + + /** Returns the active editor, or if there isn't one, it will create one. + + This may call createEditor() internally to create the component. + */ + AudioProcessorEditor* createEditorIfNeeded(); + + /** This must return the correct value immediately after the object has been + created, and mustn't change the number of parameters later. + */ + virtual int getNumParameters() = 0; + + /** Returns the name of a particular parameter. */ + virtual const String getParameterName (int parameterIndex) = 0; + + /** Called by the host to find out the value of one of the filter's parameters. + + The host will expect the value returned to be between 0 and 1.0. + + This could be called quite frequently, so try to make your code efficient. + It's also likely to be called by non-UI threads, so the code in here should + be thread-aware. + */ + virtual float getParameter (int parameterIndex) = 0; + + /** Returns the value of a parameter as a text string. */ + virtual const String getParameterText (int parameterIndex) = 0; + + /** The host will call this method to change the value of one of the filter's parameters. + + The host may call this at any time, including during the audio processing + callback, so the filter has to process this very fast and avoid blocking. + + If you want to set the value of a parameter internally, e.g. from your + editor component, then don't call this directly - instead, use the + setParameterNotifyingHost() method, which will also send a message to + the host telling it about the change. If the message isn't sent, the host + won't be able to automate your parameters properly. + + The value passed will be between 0 and 1.0. + */ + virtual void setParameter (int parameterIndex, + float newValue) = 0; + + /** Your filter can call this when it needs to change one of its parameters. + + This could happen when the editor or some other internal operation changes + a parameter. This method will call the setParameter() method to change the + value, and will then send a message to the host telling it about the change. + + Note that to make sure the host correctly handles automation, you should call + the beginParameterChangeGesture() and endParameterChangeGesture() methods to + tell the host when the user has started and stopped changing the parameter. + */ + void setParameterNotifyingHost (int parameterIndex, + float newValue); + + /** Returns true if the host can automate this parameter. + + By default, this returns true for all parameters. + */ + virtual bool isParameterAutomatable (int parameterIndex) const; + + /** Should return true if this parameter is a "meta" parameter. + + A meta-parameter is a parameter that changes other params. It is used + by some hosts (e.g. AudioUnit hosts). + + By default this returns false. + */ + virtual bool isMetaParameter (int parameterIndex) const; + + /** Sends a signal to the host to tell it that the user is about to start changing this + parameter. + + This allows the host to know when a parameter is actively being held by the user, and + it may use this information to help it record automation. + + If you call this, it must be matched by a later call to endParameterChangeGesture(). + */ + void beginParameterChangeGesture (int parameterIndex); + + /** Tells the host that the user has finished changing this parameter. + + This allows the host to know when a parameter is actively being held by the user, and + it may use this information to help it record automation. + + A call to this method must follow a call to beginParameterChangeGesture(). + */ + void endParameterChangeGesture (int parameterIndex); + + /** The filter can call this when something (apart from a parameter value) has changed. + + It sends a hint to the host that something like the program, number of parameters, + etc, has changed, and that it should update itself. + */ + void updateHostDisplay(); + + /** Returns the number of preset programs the filter supports. + + The value returned must be valid as soon as this object is created, and + must not change over its lifetime. + + This value shouldn't be less than 1. + */ + virtual int getNumPrograms() = 0; + + /** Returns the number of the currently active program. + */ + virtual int getCurrentProgram() = 0; + + /** Called by the host to change the current program. + */ + virtual void setCurrentProgram (int index) = 0; + + /** Must return the name of a given program. */ + virtual const String getProgramName (int index) = 0; + + /** Called by the host to rename a program. + */ + virtual void changeProgramName (int index, const String& newName) = 0; + + /** The host will call this method when it wants to save the filter's internal state. + + This must copy any info about the filter's state into the block of memory provided, + so that the host can store this and later restore it using setStateInformation(). + + Note that there's also a getCurrentProgramStateInformation() method, which only + stores the current program, not the state of the entire filter. + + See also the helper function copyXmlToBinary() for storing settings as XML. + + @see getCurrentProgramStateInformation + */ + virtual void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0; + + /** The host will call this method if it wants to save the state of just the filter's + current program. + + Unlike getStateInformation, this should only return the current program's state. + + Not all hosts support this, and if you don't implement it, the base class + method just calls getStateInformation() instead. If you do implement it, be + sure to also implement getCurrentProgramStateInformation. + + @see getStateInformation, setCurrentProgramStateInformation + */ + virtual void getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); + + /** This must restore the filter's state from a block of data previously created + using getStateInformation(). + + Note that there's also a setCurrentProgramStateInformation() method, which tries + to restore just the current program, not the state of the entire filter. + + See also the helper function getXmlFromBinary() for loading settings as XML. + + @see setCurrentProgramStateInformation + */ + virtual void setStateInformation (const void* data, int sizeInBytes) = 0; + + /** The host will call this method if it wants to restore the state of just the filter's + current program. + + Not all hosts support this, and if you don't implement it, the base class + method just calls setStateInformation() instead. If you do implement it, be + sure to also implement getCurrentProgramStateInformation. + + @see setStateInformation, getCurrentProgramStateInformation + */ + virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes); + + /** Adds a listener that will be called when an aspect of this processor changes. */ + void addListener (AudioProcessorListener* const newListener) throw(); + + /** Removes a previously added listener. */ + void removeListener (AudioProcessorListener* const listenerToRemove) throw(); + + /** Not for public use - this is called before deleting an editor component. */ + void editorBeingDeleted (AudioProcessorEditor* const editor) throw(); + + /** Not for public use - this is called to initialise the processor. */ + void setPlayHead (AudioPlayHead* const newPlayHead) throw(); + + /** Not for public use - this is called to initialise the processor before playing. */ + void setPlayConfigDetails (const int numIns, const int numOuts, + const double sampleRate, + const int blockSize) throw(); + + juce_UseDebuggingNewOperator + +protected: + + /** Helper function that just converts an xml element into a binary blob. + + Use this in your filter's getStateInformation() method if you want to + store its state as xml. + + Then use getXmlFromBinary() to reverse this operation and retrieve the XML + from a binary blob. + */ + static void copyXmlToBinary (const XmlElement& xml, + JUCE_NAMESPACE::MemoryBlock& destData); + + /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method. + + This might return 0 if the data's unsuitable or corrupted. Otherwise it will return + an XmlElement object that the caller must delete when no longer needed. + */ + static XmlElement* getXmlFromBinary (const void* data, + const int sizeInBytes); + + /** @internal */ + AudioPlayHead* playHead; + + /** @internal */ + void sendParamChangeMessageToListeners (const int parameterIndex, const float newValue); + +private: + VoidArray listeners; + AudioProcessorEditor* activeEditor; + double sampleRate; + int blockSize, numInputChannels, numOutputChannels, latencySamples; + bool suspended, nonRealtime; + CriticalSection callbackLock, listenerLock; + +#ifdef JUCE_DEBUG + BitArray changingParams; +#endif + + AudioProcessor (const AudioProcessor&); + const AudioProcessor& operator= (const AudioProcessor&); +}; + +#endif // __JUCE_AUDIOPROCESSOR_JUCEHEADER__ +/********* End of inlined file: juce_AudioProcessor.h *********/ + +/********* Start of inlined file: juce_PluginDescription.h *********/ +#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ +#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ + +/** + A small class to represent some facts about a particular type of plugin. + + This class is for storing and managing the details about a plugin without + actually having to load an instance of it. + + A KnownPluginList contains a list of PluginDescription objects. + + @see KnownPluginList +*/ +class JUCE_API PluginDescription +{ +public: + + PluginDescription() throw(); + PluginDescription (const PluginDescription& other) throw(); + const PluginDescription& operator= (const PluginDescription& other) throw(); + ~PluginDescription() throw(); + + /** The name of the plugin. */ + String name; + + /** The plugin format, e.g. "VST", "AudioUnit", etc. + */ + String pluginFormatName; + + /** A category, such as "Dynamics", "Reverbs", etc. + */ + String category; + + /** The manufacturer. */ + String manufacturerName; + + /** The version. This string doesn't have any particular format. */ + String version; + + /** Either the file containing the plugin module, or some other unique way + of identifying it. + + E.g. for an AU, this would be an ID string that the component manager + could use to retrieve the plugin. For a VST, it's the file path. + */ + String fileOrIdentifier; + + /** The last time the plugin file was changed. + This is handy when scanning for new or changed plugins. + */ + Time lastFileModTime; + + /** A unique ID for the plugin. + + Note that this might not be unique between formats, e.g. a VST and some + other format might actually have the same id. + + @see createIdentifierString + */ + int uid; + + /** True if the plugin identifies itself as a synthesiser. */ + bool isInstrument; + + /** The number of inputs. */ + int numInputChannels; + + /** The number of outputs. */ + int numOutputChannels; + + /** Returns true if the two descriptions refer the the same plugin. + + This isn't quite as simple as them just having the same file (because of + shell plugins). + */ + bool isDuplicateOf (const PluginDescription& other) const; + + /** Returns a string that can be saved and used to uniquely identify the + plugin again. + + This contains less info than the XML encoding, and is independent of the + plugin's file location, so can be used to store a plugin ID for use + across different machines. + */ + const String createIdentifierString() const throw(); + + /** Creates an XML object containing these details. + + @see loadFromXml + */ + XmlElement* createXml() const; + + /** Reloads the info in this structure from an XML record that was previously + saved with createXML(). + + Returns true if the XML was a valid plugin description. + */ + bool loadFromXml (const XmlElement& xml); + + juce_UseDebuggingNewOperator +}; + +#endif // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ +/********* End of inlined file: juce_PluginDescription.h *********/ + +/** + Base class for an active instance of a plugin. + + This derives from the AudioProcessor class, and adds some extra functionality + that helps when wrapping dynamically loaded plugins. + + @see AudioProcessor, AudioPluginFormat +*/ +class JUCE_API AudioPluginInstance : public AudioProcessor +{ +public: + + /** Destructor. + + Make sure that you delete any UI components that belong to this plugin before + deleting the plugin. + */ + virtual ~AudioPluginInstance(); + + /** Fills-in the appropriate parts of this plugin description object. + */ + virtual void fillInPluginDescription (PluginDescription& description) const = 0; + + juce_UseDebuggingNewOperator + +protected: + AudioPluginInstance(); + + AudioPluginInstance (const AudioPluginInstance&); + const AudioPluginInstance& operator= (const AudioPluginInstance&); +}; + +#endif // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ +/********* End of inlined file: juce_AudioPluginInstance.h *********/ + +class PluginDescription; + +/** + The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc. + + Use the static getNumFormats() and getFormat() calls to find the types + of format that are available. +*/ +class JUCE_API AudioPluginFormat +{ +public: + + /** Destructor. */ + virtual ~AudioPluginFormat(); + + /** Returns the format name. + + E.g. "VST", "AudioUnit", etc. + */ + virtual const String getName() const = 0; + + /** This tries to create descriptions for all the plugin types available in + a binary module file. + + The file will be some kind of DLL or bundle. + + Normally there will only be one type returned, but some plugins + (e.g. VST shells) can use a single DLL to create a set of different plugin + subtypes, so in that case, each subtype is returned as a separate object. + */ + virtual void findAllTypesForFile (OwnedArray & results, + const String& fileOrIdentifier) = 0; + + /** Tries to recreate a type from a previously generated PluginDescription. + + @see PluginDescription::createInstance + */ + virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0; + + /** Should do a quick check to see if this file or directory might be a plugin of + this format. + + This is for searching for potential files, so it shouldn't actually try to + load the plugin or do anything time-consuming. + */ + virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0; + + /** Returns a readable version of the name of the plugin that this identifier refers to. + */ + virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0; + + /** Checks whether this plugin could possibly be loaded. + + It doesn't actually need to load it, just to check whether the file or component + still exists. + */ + virtual bool doesPluginStillExist (const PluginDescription& desc) = 0; + + /** Searches a suggested set of directories for any plugins in this format. + + The path might be ignored, e.g. by AUs, which are found by the OS rather + than manually. + */ + virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, + const bool recursive) = 0; + + /** Returns the typical places to look for this kind of plugin. + + Note that if this returns no paths, it means that the format can't be scanned-for + (i.e. it's an internal format that doesn't live in files) + */ + virtual const FileSearchPath getDefaultLocationsToSearch() = 0; + + juce_UseDebuggingNewOperator + +protected: + AudioPluginFormat() throw(); + + AudioPluginFormat (const AudioPluginFormat&); + const AudioPluginFormat& operator= (const AudioPluginFormat&); +}; + +#endif // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_AudioPluginFormat.h *********/ + #if JUCE_PLUGINHOST_AU && JUCE_MAC /** @@ -36454,7 +36472,7 @@ class VSTMidiEventList public: VSTMidiEventList() - : events (0), numEventsUsed (0), numEventsAllocated (0) + : numEventsUsed (0), numEventsAllocated (0) { } @@ -36549,9 +36567,9 @@ public: const int size = 20 + sizeof (VstEvent*) * numEventsNeeded; if (events == 0) - events = (VstEvents*) juce_calloc (size); + events.calloc (size, 1); else - events = (VstEvents*) juce_realloc (events, size); + events.realloc (size, 1); for (int i = numEventsAllocated; i < numEventsNeeded; ++i) { @@ -36581,14 +36599,13 @@ public: juce_free (e); } - juce_free (events); - events = 0; + events.free(); numEventsUsed = 0; numEventsAllocated = 0; } } - VstEvents* events; + HeapBlock events; private: int numEventsUsed, numEventsAllocated; @@ -36645,12 +36662,217 @@ private: #endif #ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ +/********* Start of inlined file: juce_AudioPluginFormatManager.h *********/ +#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ +#define __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ + +/** + This maintains a list of known AudioPluginFormats. + + @see AudioPluginFormat +*/ +class JUCE_API AudioPluginFormatManager : public DeletedAtShutdown +{ +public: + + AudioPluginFormatManager() throw(); + + /** Destructor. */ + ~AudioPluginFormatManager() throw(); + + juce_DeclareSingleton_SingleThreaded (AudioPluginFormatManager, false); + + /** Adds any formats that it knows about, e.g. VST. + */ + void addDefaultFormats(); + + /** Returns the number of types of format that are available. + + Use getFormat() to get one of them. + */ + int getNumFormats() throw(); + + /** Returns one of the available formats. + + @see getNumFormats + */ + AudioPluginFormat* getFormat (const int index) throw(); + + /** Adds a format to the list. + + The object passed in will be owned and deleted by the manager. + */ + void addFormat (AudioPluginFormat* const format) throw(); + + /** Tries to load the type for this description, by trying all the formats + that this manager knows about. + + The caller is responsible for deleting the object that is returned. + + If it can't load the plugin, it returns 0 and leaves a message in the + errorMessage string. + */ + AudioPluginInstance* createPluginInstance (const PluginDescription& description, + String& errorMessage) const; + + /** Checks that the file or component for this plugin actually still exists. + + (This won't try to load the plugin) + */ + bool doesPluginStillExist (const PluginDescription& description) const; + + juce_UseDebuggingNewOperator + +private: + OwnedArray formats; + + AudioPluginFormatManager (const AudioPluginFormatManager&); + const AudioPluginFormatManager& operator= (const AudioPluginFormatManager&); +}; + +#endif // __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__ +/********* End of inlined file: juce_AudioPluginFormatManager.h *********/ + #endif #ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__ #endif #ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ +/********* Start of inlined file: juce_KnownPluginList.h *********/ +#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ +#define __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ + +/** + Manages a list of plugin types. + + This can be easily edited, saved and loaded, and used to create instances of + the plugin types in it. + + @see PluginListComponent +*/ +class JUCE_API KnownPluginList : public ChangeBroadcaster +{ +public: + + /** Creates an empty list. + */ + KnownPluginList(); + + /** Destructor. */ + ~KnownPluginList(); + + /** Clears the list. */ + void clear(); + + /** Returns the number of types currently in the list. + @see getType + */ + int getNumTypes() const throw() { return types.size(); } + + /** Returns one of the types. + @see getNumTypes + */ + PluginDescription* getType (const int index) const throw() { return types [index]; } + + /** Looks for a type in the list which comes from this file. + */ + PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw(); + + /** Looks for a type in the list which matches a plugin type ID. + + The identifierString parameter must have been created by + PluginDescription::createIdentifierString(). + */ + PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw(); + + /** Adds a type manually from its description. */ + bool addType (const PluginDescription& type); + + /** Removes a type. */ + void removeType (const int index) throw(); + + /** Looks for all types that can be loaded from a given file, and adds them + to the list. + + If dontRescanIfAlreadyInList is true, then the file will only be loaded and + re-tested if it's not already in the list, or if the file's modification + time has changed since the list was created. If dontRescanIfAlreadyInList is + false, the file will always be reloaded and tested. + + Returns true if any new types were added, and all the types found in this + file (even if it was already known and hasn't been re-scanned) get returned + in the array. + */ + bool scanAndAddFile (const String& possiblePluginFileOrIdentifier, + const bool dontRescanIfAlreadyInList, + OwnedArray & typesFound, + AudioPluginFormat& formatToUse); + + /** Returns true if the specified file is already known about and if it + hasn't been modified since our entry was created. + */ + bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw(); + + /** Scans and adds a bunch of files that might have been dragged-and-dropped. + + If any types are found in the files, their descriptions are returned in the array. + */ + void scanAndAddDragAndDroppedFiles (const StringArray& filenames, + OwnedArray & typesFound); + + /** Sort methods used to change the order of the plugins in the list. + */ + enum SortMethod + { + defaultOrder = 0, + sortAlphabetically, + sortByCategory, + sortByManufacturer, + sortByFileSystemLocation + }; + + /** Adds all the plugin types to a popup menu so that the user can select one. + + Depending on the sort method, it may add sub-menus for categories, + manufacturers, etc. + + Use getIndexChosenByMenu() to find out the type that was chosen. + */ + void addToMenu (PopupMenu& menu, + const SortMethod sortMethod) const; + + /** Converts a menu item index that has been chosen into its index in this list. + + Returns -1 if it's not an ID that was used. + + @see addToMenu + */ + int getIndexChosenByMenu (const int menuResultCode) const; + + /** Sorts the list. */ + void sort (const SortMethod method); + + /** Creates some XML that can be used to store the state of this list. + */ + XmlElement* createXml() const; + + /** Recreates the state of this list from its stored XML format. + */ + void recreateFromXml (const XmlElement& xml); + + juce_UseDebuggingNewOperator + +private: + OwnedArray types; + + KnownPluginList (const KnownPluginList&); + const KnownPluginList& operator= (const KnownPluginList&); +}; + +#endif // __JUCE_KNOWNPLUGINLIST_JUCEHEADER__ +/********* End of inlined file: juce_KnownPluginList.h *********/ + #endif #ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__ @@ -37447,1257 +37669,1306 @@ private: /********* End of inlined file: juce_PluginListComponent.h *********/ #endif -#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ -/********* Start of inlined file: juce_AiffAudioFormat.h *********/ -#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ +#endif +#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ -/********* Start of inlined file: juce_AudioFormat.h *********/ -#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ -#define __JUCE_AUDIOFORMAT_JUCEHEADER__ +#endif +#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ -/********* Start of inlined file: juce_AudioFormatWriter.h *********/ -#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ -#define __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ +#endif +#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioProcessorGraph.h *********/ +#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ /** - Writes samples to an audio file stream. + A type of AudioProcessor which plays back a graph of other AudioProcessors. - A subclass that writes a specific type of audio format will be created by - an AudioFormat object. + Use one of these objects if you want to wire-up a set of AudioProcessors + and play back the result. - After creating one of these with the AudioFormat::createWriterFor() method - you can call its write() method to store the samples, and then delete it. + Processors can be added to the graph as "nodes" using addNode(), and once + added, you can connect any of their input or output channels to other + nodes using addConnection(). - @see AudioFormat, AudioFormatReader + To play back a graph through an audio device, you might want to use an + AudioProcessorPlayer object. */ -class JUCE_API AudioFormatWriter -{ -protected: - - /** Creates an AudioFormatWriter object. - - @param destStream the stream to write to - this will be deleted - by this object when it is no longer needed - @param formatName the description that will be returned by the getFormatName() - method - @param sampleRate the sample rate to use - the base class just stores - this value, it doesn't do anything with it - @param numberOfChannels the number of channels to write - the base class just stores - this value, it doesn't do anything with it - @param bitsPerSample the bit depth of the stream - the base class just stores - this value, it doesn't do anything with it - */ - AudioFormatWriter (OutputStream* const destStream, - const String& formatName, - const double sampleRate, - const unsigned int numberOfChannels, - const unsigned int bitsPerSample); - -public: - /** Destructor. */ - virtual ~AudioFormatWriter(); - - /** Returns a description of what type of format this is. - - E.g. "AIFF file" - */ - const String getFormatName() const throw() { return formatName; } - - /** Writes a set of samples to the audio stream. - - Note that if you're trying to write the contents of an AudioSampleBuffer, you - can use AudioSampleBuffer::writeToAudioWriter(). - - @param samplesToWrite an array of arrays containing the sample data for - each channel to write. This is a zero-terminated - array of arrays, and can contain a different number - of channels than the actual stream uses, and the - writer should do its best to cope with this. - If the format is fixed-point, each channel will be formatted - as an array of signed integers using the full 32-bit - range -0x80000000 to 0x7fffffff, regardless of the source's - bit-depth. If it is a floating-point format, you should treat - the arrays as arrays of floats, and just cast it to an (int**) - to pass it into the method. - @param numSamples the number of samples to write - */ - virtual bool write (const int** samplesToWrite, - int numSamples) = 0; - - /** Reads a section of samples from an AudioFormatReader, and writes these to - the output. - - This will take care of any floating-point conversion that's required to convert - between the two formats. It won't deal with sample-rate conversion, though. - - If numSamplesToRead < 0, it will write the entire length of the reader. - - @returns false if it can't read or write properly during the operation - */ - bool writeFromAudioReader (AudioFormatReader& reader, - int64 startSample, - int64 numSamplesToRead); - - /** Reads some samples from an AudioSource, and writes these to the output. - - The source must already have been initialised with the AudioSource::prepareToPlay() method - - @param source the source to read from - @param numSamplesToRead total number of samples to read and write - @param samplesPerBlock the maximum number of samples to fetch from the source - @returns false if it can't read or write properly during the operation - */ - bool writeFromAudioSource (AudioSource& source, - int numSamplesToRead, - const int samplesPerBlock = 2048); - - /** Returns the sample rate being used. */ - double getSampleRate() const throw() { return sampleRate; } - - /** Returns the number of channels being written. */ - int getNumChannels() const throw() { return numChannels; } - - /** Returns the bit-depth of the data being written. */ - int getBitsPerSample() const throw() { return bitsPerSample; } - - /** Returns true if it's a floating-point format, false if it's fixed-point. */ - bool isFloatingPoint() const throw() { return usesFloatingPointData; } - - juce_UseDebuggingNewOperator - -protected: - /** The sample rate of the stream. */ - double sampleRate; - - /** The number of channels being written to the stream. */ - unsigned int numChannels; - - /** The bit depth of the file. */ - unsigned int bitsPerSample; - - /** True if it's a floating-point format, false if it's fixed-point. */ - bool usesFloatingPointData; - - /** The output stream for Use by subclasses. */ - OutputStream* output; - -private: - String formatName; -}; - -#endif // __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ -/********* End of inlined file: juce_AudioFormatWriter.h *********/ - -/** - Subclasses of AudioFormat are used to read and write different audio - file formats. - - @see AudioFormatReader, AudioFormatWriter, WavAudioFormat, AiffAudioFormat -*/ -class JUCE_API AudioFormat +class JUCE_API AudioProcessorGraph : public AudioProcessor, + public AsyncUpdater { public: - /** Destructor. */ - virtual ~AudioFormat(); - - /** Returns the name of this format. - - e.g. "WAV file" or "AIFF file" + /** Creates an empty graph. */ - const String& getFormatName() const; + AudioProcessorGraph(); - /** Returns all the file extensions that might apply to a file of this format. + /** Destructor. - The first item will be the one that's preferred when creating a new file. - - So for a wav file this might just return ".wav"; for an AIFF file it might - return two items, ".aif" and ".aiff" + Any processor objects that have been added to the graph will also be deleted. */ - const StringArray& getFileExtensions() const; + ~AudioProcessorGraph(); - /** Returns true if this the given file can be read by this format. + /** Represents one of the nodes, or processors, in an AudioProcessorGraph. - Subclasses shouldn't do too much work here, just check the extension or - file type. The base class implementation just checks the file's extension - against one of the ones that was registered in the constructor. + To create a node, call AudioProcessorGraph::addNode(). */ - virtual bool canHandleFile (const File& fileToTest); - - /** Returns a set of sample rates that the format can read and write. */ - virtual const Array getPossibleSampleRates() = 0; - - /** Returns a set of bit depths that the format can read and write. */ - virtual const Array getPossibleBitDepths() = 0; - - /** Returns true if the format can do 2-channel audio. */ - virtual bool canDoStereo() = 0; - - /** Returns true if the format can do 1-channel audio. */ - virtual bool canDoMono() = 0; - - /** Returns true if the format uses compressed data. */ - virtual bool isCompressed(); - - /** Returns a list of different qualities that can be used when writing. - - Non-compressed formats will just return an empty array, but for something - like Ogg-Vorbis or MP3, it might return a list of bit-rates, etc. - - When calling createWriterFor(), an index from this array is passed in to - tell the format which option is required. - */ - virtual const StringArray getQualityOptions(); - - /** Tries to create an object that can read from a stream containing audio - data in this format. - - The reader object that is returned can be used to read from the stream, and - should then be deleted by the caller. - - @param sourceStream the stream to read from - the AudioFormatReader object - that is returned will delete this stream when it no longer - needs it. - @param deleteStreamIfOpeningFails if no reader can be created, this determines whether this method - should delete the stream object that was passed-in. (If a valid - reader is returned, it will always be in charge of deleting the - stream, so this parameter is ignored) - @see AudioFormatReader - */ - virtual AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails) = 0; - - /** Tries to create an object that can write to a stream with this audio format. - - The writer object that is returned can be used to write to the stream, and - should then be deleted by the caller. - - If the stream can't be created for some reason (e.g. the parameters passed in - here aren't suitable), this will return 0. - - @param streamToWriteTo the stream that the data will go to - this will be - deleted by the AudioFormatWriter object when it's no longer - needed. If no AudioFormatWriter can be created by this method, - the stream will NOT be deleted, so that the caller can re-use it - to try to open a different format, etc - @param sampleRateToUse the sample rate for the file, which must be one of the ones - returned by getPossibleSampleRates() - @param numberOfChannels the number of channels - this must be either 1 or 2, and - the choice will depend on the results of canDoMono() and - canDoStereo() - @param bitsPerSample the bits per sample to use - this must be one of the values - returned by getPossibleBitDepths() - @param metadataValues a set of metadata values that the writer should try to write - to the stream. Exactly what these are depends on the format, - and the subclass doesn't actually have to do anything with - them if it doesn't want to. Have a look at the specific format - implementation classes to see possible values that can be - used - @param qualityOptionIndex the index of one of compression qualities returned by the - getQualityOptions() method. If there aren't any quality options - for this format, just pass 0 in this parameter, as it'll be - ignored - @see AudioFormatWriter - */ - virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex) = 0; - -protected: - /** Creates an AudioFormat object. - - @param formatName this sets the value that will be returned by getFormatName() - @param fileExtensions a zero-terminated list of file extensions - this is what will - be returned by getFileExtension() - */ - AudioFormat (const String& formatName, - const tchar** const fileExtensions); - -private: - - String formatName; - StringArray fileExtensions; -}; - -#endif // __JUCE_AUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_AudioFormat.h *********/ - -/** - Reads and Writes AIFF format audio files. - - @see AudioFormat -*/ -class JUCE_API AiffAudioFormat : public AudioFormat -{ -public: - - /** Creates an format object. */ - AiffAudioFormat(); - - /** Destructor. */ - ~AiffAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); -#if JUCE_MAC - bool canHandleFile (const File& fileToTest); -#endif - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif // __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_AiffAudioFormat.h *********/ - -#endif -#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioFormatManager.h *********/ -#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ -#define __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ - -/** - A class for keeping a list of available audio formats, and for deciding which - one to use to open a given file. - - You can either use this class as a singleton object, or create instances of it - yourself. Once created, use its registerFormat() method to tell it which - formats it should use. - - @see AudioFormat -*/ -class JUCE_API AudioFormatManager -{ -public: - - /** Creates an empty format manager. - - Before it'll be any use, you'll need to call registerFormat() with all the - formats you want it to be able to recognise. - */ - AudioFormatManager(); - - /** Destructor. */ - ~AudioFormatManager(); - - juce_DeclareSingleton (AudioFormatManager, false); - - /** Adds a format to the manager's list of available file types. - - The object passed-in will be deleted by this object, so don't keep a pointer - to it! - - If makeThisTheDefaultFormat is true, then the getDefaultFormat() method will - return this one when called. - */ - void registerFormat (AudioFormat* newFormat, - const bool makeThisTheDefaultFormat); - - /** Handy method to make it easy to register the formats that come with Juce. - - Currently, this will add WAV and AIFF to the list. - */ - void registerBasicFormats(); - - /** Clears the list of known formats. */ - void clearFormats(); - - /** Returns the number of currently registered file formats. */ - int getNumKnownFormats() const; - - /** Returns one of the registered file formats. */ - AudioFormat* getKnownFormat (const int index) const; - - /** Looks for which of the known formats is listed as being for a given file - extension. - - The extension may have a dot before it, so e.g. ".wav" or "wav" are both ok. - */ - AudioFormat* findFormatForFileExtension (const String& fileExtension) const; - - /** Returns the format which has been set as the default one. - - You can set a format as being the default when it is registered. It's useful - when you want to write to a file, because the best format may change between - platforms, e.g. AIFF is preferred on the Mac, WAV on Windows. - - If none has been set as the default, this method will just return the first - one in the list. - */ - AudioFormat* getDefaultFormat() const; - - /** Returns a set of wildcards for file-matching that contains the extensions for - all known formats. - - E.g. if might return "*.wav;*.aiff" if it just knows about wavs and aiffs. - */ - const String getWildcardForAllFormats() const; - - /** Searches through the known formats to try to create a suitable reader for - this file. - - If none of the registered formats can open the file, it'll return 0. If it - returns a reader, it's the caller's responsibility to delete the reader. - */ - AudioFormatReader* createReaderFor (const File& audioFile); - - /** Searches through the known formats to try to create a suitable reader for - this stream. - - The stream object that is passed-in will be deleted by this method or by the - reader that is returned, so the caller should not keep any references to it. - - The stream that is passed-in must be capable of being repositioned so - that all the formats can have a go at opening it. - - If none of the registered formats can open the stream, it'll return 0. If it - returns a reader, it's the caller's responsibility to delete the reader. - */ - AudioFormatReader* createReaderFor (InputStream* audioFileStream); - - juce_UseDebuggingNewOperator - -private: - VoidArray knownFormats; - int defaultFormatIndex; -}; - -#endif // __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ -/********* End of inlined file: juce_AudioFormatManager.h *********/ - -#endif -#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ - -#endif -#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioSubsectionReader.h *********/ -#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ -#define __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ - -/** - This class is used to wrap an AudioFormatReader and only read from a - subsection of the file. - - So if you have a reader which can read a 1000 sample file, you could wrap it - in one of these to only access, e.g. samples 100 to 200, and any samples - outside that will come back as 0. Accessing sample 0 from this reader will - actually read the first sample from the other's subsection, which might - be at a non-zero position. - - @see AudioFormatReader -*/ -class JUCE_API AudioSubsectionReader : public AudioFormatReader -{ -public: - - /** Creates a AudioSubsectionReader for a given data source. - - @param sourceReader the source reader from which we'll be taking data - @param subsectionStartSample the sample within the source reader which will be - mapped onto sample 0 for this reader. - @param subsectionLength the number of samples from the source that will - make up the subsection. If this reader is asked for - any samples beyond this region, it will return zero. - @param deleteSourceWhenDeleted if true, the sourceReader object will be deleted when - this object is deleted. - */ - AudioSubsectionReader (AudioFormatReader* const sourceReader, - const int64 subsectionStartSample, - const int64 subsectionLength, - const bool deleteSourceWhenDeleted); - - /** Destructor. */ - ~AudioSubsectionReader(); - - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples); - - void readMaxLevels (int64 startSample, - int64 numSamples, - float& lowestLeft, - float& highestLeft, - float& lowestRight, - float& highestRight); - - juce_UseDebuggingNewOperator - -private: - AudioFormatReader* const source; - int64 startSample, length; - const bool deleteSourceWhenDeleted; - - AudioSubsectionReader (const AudioSubsectionReader&); - const AudioSubsectionReader& operator= (const AudioSubsectionReader&); -}; - -#endif // __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ -/********* End of inlined file: juce_AudioSubsectionReader.h *********/ - -#endif -#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioThumbnail.h *********/ -#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ -#define __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ - -class AudioThumbnailCache; - -/** - Makes it easy to quickly draw scaled views of the waveform shape of an - audio file. - - To use this class, just create an AudioThumbNail class for the file you want - to draw, call setSource to tell it which file or resource to use, then call - drawChannel() to draw it. - - The class will asynchronously scan the wavefile to create its scaled-down view, - so you should make your UI repaint itself as this data comes in. To do this, the - AudioThumbnail is a ChangeBroadcaster, and will broadcast a message when its - listeners should repaint themselves. - - The thumbnail stores an internal low-res version of the wave data, and this can - be loaded and saved to avoid having to scan the file again. - - @see AudioThumbnailCache -*/ -class JUCE_API AudioThumbnail : public ChangeBroadcaster, - public TimeSliceClient, - private Timer -{ -public: - - /** Creates an audio thumbnail. - - @param sourceSamplesPerThumbnailSample when creating a stored, low-res version - of the audio data, this is the scale at which it should be done. (This - number is the number of original samples that will be averaged for each - low-res sample) - @param formatManagerToUse the audio format manager that is used to open the file - @param cacheToUse an instance of an AudioThumbnailCache - this provides a background - thread and storage that is used to by the thumbnail, and the cache - object can be shared between multiple thumbnails - */ - AudioThumbnail (const int sourceSamplesPerThumbnailSample, - AudioFormatManager& formatManagerToUse, - AudioThumbnailCache& cacheToUse); - - /** Destructor. */ - ~AudioThumbnail(); - - /** Specifies the file or stream that contains the audio file. - - For a file, just call - @code - setSource (new FileInputSource (file)) - @endcode - - You can pass a zero in here to clear the thumbnail. - - The source that is passed in will be deleted by this object when it is no - longer needed - */ - void setSource (InputSource* const newSource); - - /** Reloads the low res thumbnail data from an input stream. - - The thumb will automatically attempt to reload itself from its - AudioThumbnailCache. - */ - void loadFrom (InputStream& input); - - /** Saves the low res thumbnail data to an output stream. - - The thumb will automatically attempt to save itself to its - AudioThumbnailCache after it finishes scanning the wave file. - */ - void saveTo (OutputStream& output) const; - - /** Returns the number of channels in the file. - */ - int getNumChannels() const throw(); - - /** Returns the length of the audio file, in seconds. - */ - double getTotalLength() const throw(); - - /** Renders the waveform shape for a channel. - - The waveform will be drawn within the specified rectangle, where startTime - and endTime specify the times within the audio file that should be positioned - at the left and right edges of the rectangle. - - The waveform will be scaled vertically so that a full-volume sample will fill - the rectangle vertically, but you can also specify an extra vertical scale factor - with the verticalZoomFactor parameter. - */ - void drawChannel (Graphics& g, - int x, int y, int w, int h, - double startTimeSeconds, - double endTimeSeconds, - int channelNum, - const float verticalZoomFactor); - - /** Returns true if the low res preview is fully generated. - */ - bool isFullyLoaded() const throw(); - - /** @internal */ - bool useTimeSlice(); - /** @internal */ - void timerCallback(); - - juce_UseDebuggingNewOperator - -private: - AudioFormatManager& formatManagerToUse; - AudioThumbnailCache& cache; - InputSource* source; - - CriticalSection readerLock; - AudioFormatReader* reader; - - MemoryBlock data, cachedLevels; - int orginalSamplesPerThumbnailSample; - - int numChannelsCached, numSamplesCached; - double cachedStart, cachedTimePerPixel; - bool cacheNeedsRefilling; - - void clear(); - - AudioFormatReader* createReader() const; - - void generateSection (AudioFormatReader& reader, - int64 startSample, - int numSamples); - - char* getChannelData (int channel) const; - - void refillCache (const int numSamples, - double startTime, - const double timePerPixel); - - friend class AudioThumbnailCache; - - // true if it needs more callbacks from the readNextBlockFromAudioFile() method - bool initialiseFromAudioFile (AudioFormatReader& reader); - - // returns true if more needs to be read - bool readNextBlockFromAudioFile (AudioFormatReader& reader); -}; - -#endif // __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ -/********* End of inlined file: juce_AudioThumbnail.h *********/ - -#endif -#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioThumbnailCache.h *********/ -#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ -#define __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ - -struct ThumbnailCacheEntry; - -/** - An instance of this class is used to manage multiple AudioThumbnail objects. - - The cache runs a single background thread that is shared by all the thumbnails - that need it, and it maintains a set of low-res previews in memory, to avoid - having to re-scan audio files too often. - - @see AudioThumbnail -*/ -class JUCE_API AudioThumbnailCache : public TimeSliceThread -{ -public: - - /** Creates a cache object. - - The maxNumThumbsToStore parameter lets you specify how many previews should - be kept in memory at once. - */ - AudioThumbnailCache (const int maxNumThumbsToStore); - - /** Destructor. */ - ~AudioThumbnailCache(); - - /** Clears out any stored thumbnails. - */ - void clear(); - - /** Reloads the specified thumb if this cache contains the appropriate stored - data. - - This is called automatically by the AudioThumbnail class, so you shouldn't - normally need to call it directly. - */ - bool loadThumb (AudioThumbnail& thumb, const int64 hashCode); - - /** Stores the cachable data from the specified thumb in this cache. - - This is called automatically by the AudioThumbnail class, so you shouldn't - normally need to call it directly. - */ - void storeThumb (const AudioThumbnail& thumb, const int64 hashCode); - - juce_UseDebuggingNewOperator - -private: - - OwnedArray thumbs; - int maxNumThumbsToStore; - - friend class AudioThumbnail; - void addThumbnail (AudioThumbnail* const thumb); - void removeThumbnail (AudioThumbnail* const thumb); -}; - -#endif // __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ -/********* End of inlined file: juce_AudioThumbnailCache.h *********/ - -#endif -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_FlacAudioFormat.h *********/ -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_USE_FLAC || defined (DOXYGEN) - -/** - Reads and writes the lossless-compression FLAC audio format. - - To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h, - and make sure your include search path and library search path are set up to find - the FLAC header files and static libraries. - - @see AudioFormat -*/ -class JUCE_API FlacAudioFormat : public AudioFormat -{ -public: - - FlacAudioFormat(); - ~FlacAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - bool isCompressed(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_FlacAudioFormat.h *********/ - -#endif -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_WavAudioFormat.h *********/ -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - -/** - Reads and Writes WAV format audio files. - - @see AudioFormat -*/ -class JUCE_API WavAudioFormat : public AudioFormat -{ -public: - - /** Creates a format object. */ - WavAudioFormat(); - - /** Destructor. */ - ~WavAudioFormat(); - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavDescription; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginator; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginatorRef; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Date format is: yyyy-mm-dd - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginationDate; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - Time format is: hh-mm-ss - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavOriginationTime; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - This is the number of samples from the start of an edit that the - file is supposed to begin at. Seems like an obvious mistake to - only allow a file to occur in an edit once, but that's the way - it is.. - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavTimeReference; - - /** Metadata property name used by wav readers and writers for adding - a BWAV chunk to the file. - - This is a - - @see AudioFormatReader::metadataValues, createWriterFor - */ - static const tchar* const bwavCodingHistory; - - /** Utility function to fill out the appropriate metadata for a BWAV file. - - This just makes it easier than using the property names directly, and it - fills out the time and date in the right format. - */ - static const StringPairArray createBWAVMetadata (const String& description, - const String& originator, - const String& originatorRef, - const Time& dateAndTime, - const int64 timeReferenceSamples, - const String& codingHistory); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - /** Utility function to replace the metadata in a wav file with a new set of values. - - If possible, this cheats by overwriting just the metadata region of the file, rather - than by copying the whole file again. - */ - bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata); - - juce_UseDebuggingNewOperator -}; - -#endif // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_WavAudioFormat.h *********/ - -#endif -#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioCDReader.h *********/ -#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ -#define __JUCE_AUDIOCDREADER_JUCEHEADER__ - -#if JUCE_USE_CDREADER - -#if JUCE_MAC - -#endif - -/** - A type of AudioFormatReader that reads from an audio CD. - - One of these can be used to read a CD as if it's one big audio stream. Use the - getPositionOfTrackStart() method to find where the individual tracks are - within the stream. - - @see AudioFormatReader -*/ -class JUCE_API AudioCDReader : public AudioFormatReader -{ -public: - - /** Returns a list of names of Audio CDs currently available for reading. - - If there's a CD drive but no CD in it, this might return an empty list, or - possibly a device that can be opened but which has no tracks, depending - on the platform. - - @see createReaderForCD - */ - static const StringArray getAvailableCDNames(); - - /** Tries to create an AudioFormatReader that can read from an Audio CD. - - @param index the index of one of the available CDs - use getAvailableCDNames() - to find out how many there are. - @returns a new AudioCDReader object, or 0 if it couldn't be created. The - caller will be responsible for deleting the object returned. - */ - static AudioCDReader* createReaderForCD (const int index); - - /** Destructor. */ - ~AudioCDReader(); - - /** Implementation of the AudioFormatReader method. */ - bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer, - int64 startSampleInFile, int numSamples); - - /** Checks whether the CD has been removed from the drive. - */ - bool isCDStillPresent() const; - - /** Returns the total number of tracks (audio + data). - */ - int getNumTracks() const; - - /** Finds the sample offset of the start of a track. - - @param trackNum the track number, where 0 is the first track. - */ - int getPositionOfTrackStart (int trackNum) const; - - /** Returns true if a given track is an audio track. - - @param trackNum the track number, where 0 is the first track. - */ - bool isTrackAudio (int trackNum) const; - - /** Refreshes the object's table of contents. - - If the disc has been ejected and a different one put in since this - object was created, this will cause it to update its idea of how many tracks - there are, etc. - */ - void refreshTrackLengths(); - - /** Enables scanning for indexes within tracks. - - @see getLastIndex - */ - void enableIndexScanning (bool enabled); - - /** Returns the index number found during the last read() call. - - Index scanning is turned off by default - turn it on with enableIndexScanning(). - - Then when the read() method is called, if it comes across an index within that - block, the index number is stored and returned by this method. - - Some devices might not support indexes, of course. - - (If you don't know what CD indexes are, it's unlikely you'll ever need them). - - @see enableIndexScanning - */ - int getLastIndex() const; - - /** Scans a track to find the position of any indexes within it. - - @param trackNumber the track to look in, where 0 is the first track on the disc - @returns an array of sample positions of any index points found (not including - the index that marks the start of the track) - */ - const Array findIndexesInTrack (const int trackNumber); - - /** Returns the CDDB id number for the CD. - - It's not a great way of identifying a disc, but it's traditional. - */ - int getCDDBId(); - - /** Tries to eject the disk. - - Of course this might not be possible, if some other process is using it. - */ - void ejectDisk(); - - juce_UseDebuggingNewOperator - -private: - -#if JUCE_MAC - File volumeDir; - OwnedArray tracks; - Array trackStartSamples; - int currentReaderTrack; - AudioFormatReader* reader; - AudioCDReader (const File& volume); -public: - static int compareElements (const File* const, const File* const) throw(); -private: - -#elif JUCE_WINDOWS - int numTracks; - int trackStarts[100]; - bool audioTracks [100]; - void* handle; - bool indexingEnabled; - int lastIndex, firstFrameInBuffer, samplesInBuffer; - MemoryBlock buffer; - AudioCDReader (void* handle); - int getIndexAt (int samplePos); - -#elif JUCE_LINUX - AudioCDReader(); -#endif - - AudioCDReader (const AudioCDReader&); - const AudioCDReader& operator= (const AudioCDReader&); -}; - -#endif -#endif // __JUCE_AUDIOCDREADER_JUCEHEADER__ -/********* End of inlined file: juce_AudioCDReader.h *********/ - -#endif -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/ -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_USE_OGGVORBIS || defined (DOXYGEN) - -/** - Reads and writes the Ogg-Vorbis audio format. - - To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h, - and make sure your include search path and library search path are set up to find - the Vorbis and Ogg header files and static libraries. - - @see AudioFormat, -*/ -class JUCE_API OggVorbisAudioFormat : public AudioFormat -{ -public: - - OggVorbisAudioFormat(); - ~OggVorbisAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - bool isCompressed(); - const StringArray getQualityOptions(); - - /** Tries to estimate the quality level of an ogg file based on its size. - - If it can't read the file for some reason, this will just return 1 (medium quality), - otherwise it will return the approximate quality setting that would have been used - to create the file. - - @see getQualityOptions - */ - int estimateOggFileQuality (const File& source); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/ - -#endif -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - -/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/ -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ -#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - -#if JUCE_QUICKTIME - -/** - Uses QuickTime to read the audio track a movie or media file. - - As well as QuickTime movies, this should also manage to open other audio - files that quicktime can understand, like mp3, m4a, etc. - - @see AudioFormat -*/ -class JUCE_API QuickTimeAudioFormat : public AudioFormat -{ -public: - - /** Creates a format object. */ - QuickTimeAudioFormat(); - - /** Destructor. */ - ~QuickTimeAudioFormat(); - - const Array getPossibleSampleRates(); - const Array getPossibleBitDepths(); - bool canDoStereo(); - bool canDoMono(); - - AudioFormatReader* createReaderFor (InputStream* sourceStream, - const bool deleteStreamIfOpeningFails); - - AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo, - double sampleRateToUse, - unsigned int numberOfChannels, - int bitsPerSample, - const StringPairArray& metadataValues, - int qualityOptionIndex); - - juce_UseDebuggingNewOperator -}; - -#endif -#endif // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/ - -#endif -#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ - -/********* Start of inlined file: juce_AudioCDBurner.h *********/ -#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ -#define __JUCE_AUDIOCDBURNER_JUCEHEADER__ - -#if JUCE_USE_CDBURNER - -/** -*/ -class AudioCDBurner -{ -public: - - /** Returns a list of available optical drives. - - Use openDevice() to open one of the items from this list. - */ - static const StringArray findAvailableDevices(); - - /** Tries to open one of the optical drives. - - The deviceIndex is an index into the array returned by findAvailableDevices(). - */ - static AudioCDBurner* openDevice (const int deviceIndex); - - /** Destructor. */ - ~AudioCDBurner(); - - /** Returns true if there's a writable disk in the drive. - */ - bool isDiskPresent() const; - - /** Returns the number of free blocks on the disk. - - There are 75 blocks per second, at 44100Hz. - */ - int getNumAvailableAudioBlocks() const; - - /** Adds a track to be written. - - The source passed-in here will be kept by this object, and it will - be used and deleted at some point in the future, either during the - burn() method or when this AudioCDBurner object is deleted. Your caller - method shouldn't keep a reference to it or use it again after passing - it in here. - */ - bool addAudioTrack (AudioSource* source, int numSamples); - - /** - - Return true to cancel the current burn operation - */ - class BurnProgressListener + class JUCE_API Node : public ReferenceCountedObject { public: - BurnProgressListener() throw() {} - virtual ~BurnProgressListener() {} - - /** Called at intervals to report on the progress of the AudioCDBurner. - - To cancel the burn, return true from this. + /** Destructor. */ - virtual bool audioCDBurnProgress (float proportionComplete) = 0; + ~Node(); + + /** The ID number assigned to this node. + + This is assigned by the graph that owns it, and can't be changed. + */ + const uint32 id; + + /** The actual processor object that this node represents. + */ + AudioProcessor* const processor; + + /** A set of user-definable properties that are associated with this node. + + This can be used to attach values to the node for whatever purpose seems + useful. For example, you might store an x and y position if your application + is displaying the nodes on-screen. + */ + PropertySet properties; + + /** A convenient typedef for referring to a pointer to a node object. + */ + typedef ReferenceCountedObjectPtr Ptr; + + juce_UseDebuggingNewOperator + + private: + friend class AudioProcessorGraph; + + bool isPrepared; + + Node (const uint32 id, AudioProcessor* const processor) throw(); + + void prepare (const double sampleRate, const int blockSize, AudioProcessorGraph* const graph); + void unprepare(); + + Node (const Node&); + const Node& operator= (const Node&); }; - const String burn (BurnProgressListener* listener, - const bool ejectDiscAfterwards, - const bool peformFakeBurnForTesting); + /** Represents a connection between two channels of two nodes in an AudioProcessorGraph. + + To create a connection, use AudioProcessorGraph::addConnection(). + */ + struct JUCE_API Connection + { + public: + + /** The ID number of the node which is the input source for this connection. + @see AudioProcessorGraph::getNodeForId + */ + uint32 sourceNodeId; + + /** The index of the output channel of the source node from which this + connection takes its data. + + If this value is the special number AudioProcessorGraph::midiChannelIndex, then + it is referring to the source node's midi output. Otherwise, it is the zero-based + index of an audio output channel in the source node. + */ + int sourceChannelIndex; + + /** The ID number of the node which is the destination for this connection. + @see AudioProcessorGraph::getNodeForId + */ + uint32 destNodeId; + + /** The index of the input channel of the destination node to which this + connection delivers its data. + + If this value is the special number AudioProcessorGraph::midiChannelIndex, then + it is referring to the destination node's midi input. Otherwise, it is the zero-based + index of an audio input channel in the destination node. + */ + int destChannelIndex; + + juce_UseDebuggingNewOperator + + private: + }; + + /** Deletes all nodes and connections from this graph. + + Any processor objects in the graph will be deleted. + */ + void clear(); + + /** Returns the number of nodes in the graph. */ + int getNumNodes() const throw() { return nodes.size(); } + + /** Returns a pointer to one of the nodes in the graph. + + This will return 0 if the index is out of range. + @see getNodeForId + */ + Node* getNode (const int index) const throw() { return nodes [index]; } + + /** Searches the graph for a node with the given ID number and returns it. + + If no such node was found, this returns 0. + @see getNode + */ + Node* getNodeForId (const uint32 nodeId) const throw(); + + /** Adds a node to the graph. + + This creates a new node in the graph, for the specified processor. Once you have + added a processor to the graph, the graph owns it and will delete it later when + it is no longer needed. + + The optional nodeId parameter lets you specify an ID to use for the node, but + if the value is already in use, this new node will overwrite the old one. + + If this succeeds, it returns a pointer to the newly-created node. + */ + Node* addNode (AudioProcessor* const newProcessor, + uint32 nodeId = 0); + + /** Deletes a node within the graph which has the specified ID. + + This will also delete any connections that are attached to this node. + */ + bool removeNode (const uint32 nodeId); + + /** Returns the number of connections in the graph. */ + int getNumConnections() const throw() { return connections.size(); } + + /** Returns a pointer to one of the connections in the graph. */ + const Connection* getConnection (const int index) const throw() { return connections [index]; } + + /** Searches for a connection between some specified channels. + + If no such connection is found, this returns 0. + */ + const Connection* getConnectionBetween (const uint32 sourceNodeId, + const int sourceChannelIndex, + const uint32 destNodeId, + const int destChannelIndex) const throw(); + + /** Returns true if there is a connection between any of the channels of + two specified nodes. + */ + bool isConnected (const uint32 possibleSourceNodeId, + const uint32 possibleDestNodeId) const throw(); + + /** Returns true if it would be legal to connect the specified points. + */ + bool canConnect (const uint32 sourceNodeId, const int sourceChannelIndex, + const uint32 destNodeId, const int destChannelIndex) const throw(); + + /** Attempts to connect two specified channels of two nodes. + + If this isn't allowed (e.g. because you're trying to connect a midi channel + to an audio one or other such nonsense), then it'll return false. + */ + bool addConnection (const uint32 sourceNodeId, const int sourceChannelIndex, + const uint32 destNodeId, const int destChannelIndex); + + /** Deletes the connection with the specified index. + + Returns true if a connection was actually deleted. + */ + void removeConnection (const int index); + + /** Deletes any connection between two specified points. + + Returns true if a connection was actually deleted. + */ + bool removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex, + const uint32 destNodeId, const int destChannelIndex); + + /** Removes all connections from the specified node. + */ + bool disconnectNode (const uint32 nodeId); + + /** Performs a sanity checks of all the connections. + + This might be useful if some of the processors are doing things like changing + their channel counts, which could render some connections obsolete. + */ + bool removeIllegalConnections(); + + /** A special number that represents the midi channel of a node. + + This is used as a channel index value if you want to refer to the midi input + or output instead of an audio channel. + */ + static const int midiChannelIndex; + + /** A special type of AudioProcessor that can live inside an AudioProcessorGraph + in order to use the audio that comes into and out of the graph itself. + + If you create an AudioGraphIOProcessor in "input" mode, it will act as a + node in the graph which delivers the audio that is coming into the parent + graph. This allows you to stream the data to other nodes and process the + incoming audio. + + Likewise, one of these in "output" mode can be sent data which it will add to + the sum of data being sent to the graph's output. + + @see AudioProcessorGraph + */ + class JUCE_API AudioGraphIOProcessor : public AudioPluginInstance + { + public: + /** Specifies the mode in which this processor will operate. + */ + enum IODeviceType + { + audioInputNode, /**< In this mode, the processor has output channels + representing all the audio input channels that are + coming into its parent audio graph. */ + audioOutputNode, /**< In this mode, the processor has input channels + representing all the audio output channels that are + going out of its parent audio graph. */ + midiInputNode, /**< In this mode, the processor has a midi output which + delivers the same midi data that is arriving at its + parent graph. */ + midiOutputNode /**< In this mode, the processor has a midi input and + any data sent to it will be passed out of the parent + graph. */ + }; + + /** Returns the mode of this processor. */ + IODeviceType getType() const throw() { return type; } + + /** Returns the parent graph to which this processor belongs, or 0 if it + hasn't yet been added to one. */ + AudioProcessorGraph* getParentGraph() const throw() { return graph; } + + /** True if this is an audio or midi input. */ + bool isInput() const throw(); + /** True if this is an audio or midi output. */ + bool isOutput() const throw(); + + AudioGraphIOProcessor (const IODeviceType type); + ~AudioGraphIOProcessor(); + + const String getName() const; + void fillInPluginDescription (PluginDescription& d) const; + + void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); + void releaseResources(); + void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); + + const String getInputChannelName (const int channelIndex) const; + const String getOutputChannelName (const int channelIndex) const; + bool isInputChannelStereoPair (int index) const; + bool isOutputChannelStereoPair (int index) const; + bool acceptsMidi() const; + bool producesMidi() const; + + AudioProcessorEditor* createEditor(); + + int getNumParameters(); + const String getParameterName (int); + float getParameter (int); + const String getParameterText (int); + void setParameter (int, float); + + int getNumPrograms(); + int getCurrentProgram(); + void setCurrentProgram (int); + const String getProgramName (int); + void changeProgramName (int, const String&); + + void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); + void setStateInformation (const void* data, int sizeInBytes); + + /** @internal */ + void setParentGraph (AudioProcessorGraph* const graph) throw(); + + juce_UseDebuggingNewOperator + + private: + const IODeviceType type; + AudioProcessorGraph* graph; + + AudioGraphIOProcessor (const AudioGraphIOProcessor&); + const AudioGraphIOProcessor& operator= (const AudioGraphIOProcessor&); + }; + + // AudioProcessor methods: + + const String getName() const; + + void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock); + void releaseResources(); + void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages); + + const String getInputChannelName (const int channelIndex) const; + const String getOutputChannelName (const int channelIndex) const; + bool isInputChannelStereoPair (int index) const; + bool isOutputChannelStereoPair (int index) const; + + bool acceptsMidi() const; + bool producesMidi() const; + + AudioProcessorEditor* createEditor() { return 0; } + + int getNumParameters() { return 0; } + const String getParameterName (int) { return String::empty; } + float getParameter (int) { return 0; } + const String getParameterText (int) { return String::empty; } + void setParameter (int, float) { } + + int getNumPrograms() { return 0; } + int getCurrentProgram() { return 0; } + void setCurrentProgram (int) { } + const String getProgramName (int) { return String::empty; } + void changeProgramName (int, const String&) { } + + void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData); + void setStateInformation (const void* data, int sizeInBytes); + + /** @internal */ + void handleAsyncUpdate(); juce_UseDebuggingNewOperator private: - AudioCDBurner (const int deviceIndex); + ReferenceCountedArray nodes; + OwnedArray connections; + int lastNodeId; + AudioSampleBuffer renderingBuffers; + OwnedArray midiBuffers; - void* internal; + CriticalSection renderLock; + VoidArray renderingOps; + + friend class AudioGraphIOProcessor; + AudioSampleBuffer* currentAudioInputBuffer; + AudioSampleBuffer currentAudioOutputBuffer; + MidiBuffer* currentMidiInputBuffer; + MidiBuffer currentMidiOutputBuffer; + + void clearRenderingSequence(); + void buildRenderingSequence(); + + bool isAnInputTo (const uint32 possibleInputId, + const uint32 possibleDestinationId, + const int recursionCheck) const throw(); + + AudioProcessorGraph (const AudioProcessorGraph&); + const AudioProcessorGraph& operator= (const AudioProcessorGraph&); }; +#endif // __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ +/********* End of inlined file: juce_AudioProcessorGraph.h *********/ + #endif -#endif // __JUCE_AUDIOCDBURNER_JUCEHEADER__ -/********* End of inlined file: juce_AudioCDBurner.h *********/ +#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ + +#endif +#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ + +/********* Start of inlined file: juce_AudioProcessorPlayer.h *********/ +#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ +#define __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ + +/** + An AudioIODeviceCallback object which streams audio through an AudioProcessor. + + To use one of these, just make it the callback used by your AudioIODevice, and + give it a processor to use by calling setProcessor(). + + It's also a MidiInputCallback, so you can connect it to both an audio and midi + input to send both streams through the processor. + + @see AudioProcessor, AudioProcessorGraph +*/ +class JUCE_API AudioProcessorPlayer : public AudioIODeviceCallback, + public MidiInputCallback +{ +public: + + /** + */ + AudioProcessorPlayer(); + + /** Destructor. */ + virtual ~AudioProcessorPlayer(); + + /** Sets the processor that should be played. + + The processor that is passed in will not be deleted or owned by this object. + To stop anything playing, pass in 0 to this method. + */ + void setProcessor (AudioProcessor* const processorToPlay); + + /** Returns the current audio processor that is being played. + */ + AudioProcessor* getCurrentProcessor() const throw() { return processor; } + + /** Returns a midi message collector that you can pass midi messages to if you + want them to be injected into the midi stream that is being sent to the + processor. + */ + MidiMessageCollector& getMidiMessageCollector() throw() { return messageCollector; } + + /** @internal */ + void audioDeviceIOCallback (const float** inputChannelData, + int totalNumInputChannels, + float** outputChannelData, + int totalNumOutputChannels, + int numSamples); + /** @internal */ + void audioDeviceAboutToStart (AudioIODevice* device); + /** @internal */ + void audioDeviceStopped(); + /** @internal */ + void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message); + + juce_UseDebuggingNewOperator + +private: + AudioProcessor* processor; + CriticalSection lock; + double sampleRate; + int blockSize; + bool isPrepared; + + int numInputChans, numOutputChans; + float* channels [128]; + AudioSampleBuffer tempBuffer; + + MidiBuffer incomingMidi; + MidiMessageCollector messageCollector; + + AudioProcessorPlayer (const AudioProcessorPlayer&); + const AudioProcessorPlayer& operator= (const AudioProcessorPlayer&); +}; + +#endif // __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ +/********* End of inlined file: juce_AudioProcessorPlayer.h *********/ + +#endif +#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ + +/********* Start of inlined file: juce_GenericAudioProcessorEditor.h *********/ +#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ +#define __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ + +/********* Start of inlined file: juce_PropertyPanel.h *********/ +#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ +#define __JUCE_PROPERTYPANEL_JUCEHEADER__ + +/********* Start of inlined file: juce_PropertyComponent.h *********/ +#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ + +class EditableProperty; + +/** + A base class for a component that goes in a PropertyPanel and displays one of + an item's properties. + + Subclasses of this are used to display a property in various forms, e.g. a + ChoicePropertyComponent shows its value as a combo box; a SliderPropertyComponent + shows its value as a slider; a TextPropertyComponent as a text box, etc. + + A subclass must implement the refresh() method which will be called to tell the + component to update itself, and is also responsible for calling this it when the + item that it refers to is changed. + + @see PropertyPanel, TextPropertyComponent, SliderPropertyComponent, + ChoicePropertyComponent, ButtonPropertyComponent, BooleanPropertyComponent +*/ +class JUCE_API PropertyComponent : public Component, + public SettableTooltipClient +{ +public: + + /** Creates a PropertyComponent. + + @param propertyName the name is stored as this component's name, and is + used as the name displayed next to this component in + a property panel + @param preferredHeight the height that the component should be given - some + items may need to be larger than a normal row height. + This value can also be set if a subclass changes the + preferredHeight member variable. + */ + PropertyComponent (const String& propertyName, + const int preferredHeight = 25); + + /** Destructor. */ + ~PropertyComponent(); + + /** Returns this item's preferred height. + + This value is specified either in the constructor or by a subclass changing the + preferredHeight member variable. + */ + int getPreferredHeight() const throw() { return preferredHeight; } + + /** Updates the property component if the item it refers to has changed. + + A subclass must implement this method, and other objects may call it to + force it to refresh itself. + + The subclass should be economical in the amount of work is done, so for + example it should check whether it really needs to do a repaint rather than + just doing one every time this method is called, as it may be called when + the value being displayed hasn't actually changed. + */ + virtual void refresh() = 0; + + /** The default paint method fills the background and draws a label for the + item's name. + + @see LookAndFeel::drawPropertyComponentBackground(), LookAndFeel::drawPropertyComponentLabel() + */ + void paint (Graphics& g); + + /** The default resize method positions any child component to the right of this + one, based on the look and feel's default label size. + */ + void resized(); + + /** By default, this just repaints the component. */ + void enablementChanged(); + + juce_UseDebuggingNewOperator + +protected: + /** Used by the PropertyPanel to determine how high this component needs to be. + + A subclass can update this value in its constructor but shouldn't alter it later + as changes won't necessarily be picked up. + */ + int preferredHeight; +}; + +#endif // __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_PropertyComponent.h *********/ + +/** + A panel that holds a list of PropertyComponent objects. + + This panel displays a list of PropertyComponents, and allows them to be organised + into collapsible sections. + + To use, simply create one of these and add your properties to it with addProperties() + or addSection(). + + @see PropertyComponent +*/ +class JUCE_API PropertyPanel : public Component +{ +public: + + /** Creates an empty property panel. */ + PropertyPanel(); + + /** Destructor. */ + ~PropertyPanel(); + + /** Deletes all property components from the panel. + */ + void clear(); + + /** Adds a set of properties to the panel. + + The components in the list will be owned by this object and will be automatically + deleted later on when no longer needed. + + These properties are added without them being inside a named section. If you + want them to be kept together in a collapsible section, use addSection() instead. + */ + void addProperties (const Array & newPropertyComponents); + + /** Adds a set of properties to the panel. + + These properties are added at the bottom of the list, under a section heading with + a plus/minus button that allows it to be opened and closed. + + The components in the list will be owned by this object and will be automatically + deleted later on when no longer needed. + + To add properies without them being in a section, use addProperties(). + */ + void addSection (const String& sectionTitle, + const Array & newPropertyComponents, + const bool shouldSectionInitiallyBeOpen = true); + + /** Calls the refresh() method of all PropertyComponents in the panel */ + void refreshAll() const; + + /** Returns a list of all the names of sections in the panel. + + These are the sections that have been added with addSection(). + */ + const StringArray getSectionNames() const; + + /** Returns true if the section at this index is currently open. + + The index is from 0 up to the number of items returned by getSectionNames(). + */ + bool isSectionOpen (const int sectionIndex) const; + + /** Opens or closes one of the sections. + + The index is from 0 up to the number of items returned by getSectionNames(). + */ + void setSectionOpen (const int sectionIndex, const bool shouldBeOpen); + + /** Enables or disables one of the sections. + + The index is from 0 up to the number of items returned by getSectionNames(). + */ + void setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled); + + /** Saves the current state of open/closed sections so it can be restored later. + + The caller is responsible for deleting the object that is returned. + + To restore this state, use restoreOpennessState(). + + @see restoreOpennessState + */ + XmlElement* getOpennessState() const; + + /** Restores a previously saved arrangement of open/closed sections. + + This will try to restore a snapshot of the panel's state that was created by + the getOpennessState() method. If any of the sections named in the original + XML aren't present, they will be ignored. + + @see getOpennessState + */ + void restoreOpennessState (const XmlElement& newState); + + /** Sets a message to be displayed when there are no properties in the panel. + + The default message is "nothing selected". + */ + void setMessageWhenEmpty (const String& newMessage); + + /** Returns the message that is displayed when there are no properties. + @see setMessageWhenEmpty + */ + const String& getMessageWhenEmpty() const throw(); + + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void resized(); + + juce_UseDebuggingNewOperator + +private: + Viewport* viewport; + Component* propertyHolderComponent; + String messageWhenEmpty; + + void updatePropHolderLayout() const; + void updatePropHolderLayout (const int width) const; +}; + +#endif // __JUCE_PROPERTYPANEL_JUCEHEADER__ +/********* End of inlined file: juce_PropertyPanel.h *********/ + +/** + A type of UI component that displays the parameters of an AudioProcessor as + a simple list of sliders. + + This can be used for showing an editor for a processor that doesn't supply + its own custom editor. + + @see AudioProcessor +*/ +class JUCE_API GenericAudioProcessorEditor : public AudioProcessorEditor +{ +public: + + GenericAudioProcessorEditor (AudioProcessor* const owner); + ~GenericAudioProcessorEditor(); + + void paint (Graphics& g); + void resized(); + + juce_UseDebuggingNewOperator + +private: + PropertyPanel* panel; +}; + +#endif // __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ +/********* End of inlined file: juce_GenericAudioProcessorEditor.h *********/ + +#endif +#ifndef __JUCE_SAMPLER_JUCEHEADER__ + +/********* Start of inlined file: juce_Sampler.h *********/ +#ifndef __JUCE_SAMPLER_JUCEHEADER__ +#define __JUCE_SAMPLER_JUCEHEADER__ + +/********* Start of inlined file: juce_Synthesiser.h *********/ +#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ +#define __JUCE_SYNTHESISER_JUCEHEADER__ + +/** + Describes one of the sounds that a Synthesiser can play. + + A synthesiser can contain one or more sounds, and a sound can choose which + midi notes and channels can trigger it. + + The SynthesiserSound is a passive class that just describes what the sound is - + the actual audio rendering for a sound is done by a SynthesiserVoice. This allows + more than one SynthesiserVoice to play the same sound at the same time. + + @see Synthesiser, SynthesiserVoice +*/ +class JUCE_API SynthesiserSound : public ReferenceCountedObject +{ +protected: + + SynthesiserSound(); + +public: + /** Destructor. */ + virtual ~SynthesiserSound(); + + /** Returns true if this sound should be played when a given midi note is pressed. + + The Synthesiser will use this information when deciding which sounds to trigger + for a given note. + */ + virtual bool appliesToNote (const int midiNoteNumber) = 0; + + /** Returns true if the sound should be triggered by midi events on a given channel. + + The Synthesiser will use this information when deciding which sounds to trigger + for a given note. + */ + virtual bool appliesToChannel (const int midiChannel) = 0; + + /** + */ + typedef ReferenceCountedObjectPtr Ptr; + + juce_UseDebuggingNewOperator +}; + +/** + Represents a voice that a Synthesiser can use to play a SynthesiserSound. + + A voice plays a single sound at a time, and a synthesiser holds an array of + voices so that it can play polyphonically. + + @see Synthesiser, SynthesiserSound +*/ +class JUCE_API SynthesiserVoice +{ +public: + + /** Creates a voice. */ + SynthesiserVoice(); + + /** Destructor. */ + virtual ~SynthesiserVoice(); + + /** Returns the midi note that this voice is currently playing. + + Returns a value less than 0 if no note is playing. + */ + int getCurrentlyPlayingNote() const throw() { return currentlyPlayingNote; } + + /** Returns the sound that this voice is currently playing. + + Returns 0 if it's not playing. + */ + const SynthesiserSound::Ptr getCurrentlyPlayingSound() const throw() { return currentlyPlayingSound; } + + /** Must return true if this voice object is capable of playing the given sound. + + If there are different classes of sound, and different classes of voice, a voice can + choose which ones it wants to take on. + + A typical implementation of this method may just return true if there's only one type + of voice and sound, or it might check the type of the sound object passed-in and + see if it's one that it understands. + */ + virtual bool canPlaySound (SynthesiserSound* sound) = 0; + + /** Called to start a new note. + + This will be called during the rendering callback, so must be fast and thread-safe. + */ + virtual void startNote (const int midiNoteNumber, + const float velocity, + SynthesiserSound* sound, + const int currentPitchWheelPosition) = 0; + + /** Called to stop a note. + + This will be called during the rendering callback, so must be fast and thread-safe. + + If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all + sound immediately, and must call clearCurrentNote() to reset the state of this voice + and allow the synth to reassign it another sound. + + If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to + begin fading out its sound, and it can stop playing until it's finished. As soon as it + finishes playing (during the rendering callback), it must make sure that it calls + clearCurrentNote(). + */ + virtual void stopNote (const bool allowTailOff) = 0; + + /** Called to let the voice know that the pitch wheel has been moved. + + This will be called during the rendering callback, so must be fast and thread-safe. + */ + virtual void pitchWheelMoved (const int newValue) = 0; + + /** Called to let the voice know that a midi controller has been moved. + + This will be called during the rendering callback, so must be fast and thread-safe. + */ + virtual void controllerMoved (const int controllerNumber, + const int newValue) = 0; + + /** Renders the next block of data for this voice. + + The output audio data must be added to the current contents of the buffer provided. + Only the region of the buffer between startSample and (startSample + numSamples) + should be altered by this method. + + If the voice is currently silent, it should just return without doing anything. + + If the sound that the voice is playing finishes during the course of this rendered + block, it must call clearCurrentNote(), to tell the synthesiser that it has finished. + + The size of the blocks that are rendered can change each time it is called, and may + involve rendering as little as 1 sample at a time. In between rendering callbacks, + the voice's methods will be called to tell it about note and controller events. + */ + virtual void renderNextBlock (AudioSampleBuffer& outputBuffer, + int startSample, + int numSamples) = 0; + + /** Returns true if the voice is currently playing a sound which is mapped to the given + midi channel. + + If it's not currently playing, this will return false. + */ + bool isPlayingChannel (const int midiChannel) const; + + /** Changes the voice's reference sample rate. + + The rate is set so that subclasses know the output rate and can set their pitch + accordingly. + + This method is called by the synth, and subclasses can access the current rate with + the currentSampleRate member. + */ + void setCurrentPlaybackSampleRate (const double newRate); + + juce_UseDebuggingNewOperator + +protected: + + /** Returns the current target sample rate at which rendering is being done. + + This is available for subclasses so they can pitch things correctly. + */ + double getSampleRate() const throw() { return currentSampleRate; } + + /** Resets the state of this voice after a sound has finished playing. + + The subclass must call this when it finishes playing a note and becomes available + to play new ones. + + It must either call it in the stopNote() method, or if the voice is tailing off, + then it should call it later during the renderNextBlock method, as soon as it + finishes its tail-off. + + It can also be called at any time during the render callback if the sound happens + to have finished, e.g. if it's playing a sample and the sample finishes. + */ + void clearCurrentNote(); + +private: + + friend class Synthesiser; + + double currentSampleRate; + int currentlyPlayingNote; + uint32 noteOnTime; + SynthesiserSound::Ptr currentlyPlayingSound; +}; + +/** + Base class for a musical device that can play sounds. + + To create a synthesiser, you'll need to create a subclass of SynthesiserSound + to describe each sound available to your synth, and a subclass of SynthesiserVoice + which can play back one of these sounds. + + Then you can use the addVoice() and addSound() methods to give the synthesiser a + set of sounds, and a set of voices it can use to play them. If you only give it + one voice it will be monophonic - the more voices it has, the more polyphony it'll + have available. + + Then repeatedly call the renderNextBlock() method to produce the audio. Any midi + events that go in will be scanned for note on/off messages, and these are used to + start and stop the voices playing the appropriate sounds. + + While it's playing, you can also cause notes to be triggered by calling the noteOn(), + noteOff() and other controller methods. + + Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it + what the target playback rate is. This value is passed on to the voices so that + they can pitch their output correctly. +*/ +class JUCE_API Synthesiser +{ +public: + + /** Creates a new synthesiser. + + You'll need to add some sounds and voices before it'll make any sound.. + */ + Synthesiser(); + + /** Destructor. */ + virtual ~Synthesiser(); + + /** Deletes all voices. */ + void clearVoices(); + + /** Returns the number of voices that have been added. */ + int getNumVoices() const throw() { return voices.size(); } + + /** Returns one of the voices that have been added. */ + SynthesiserVoice* getVoice (const int index) const throw(); + + /** Adds a new voice to the synth. + + All the voices should be the same class of object and are treated equally. + + The object passed in will be managed by the synthesiser, which will delete + it later on when no longer needed. The caller should not retain a pointer to the + voice. + */ + void addVoice (SynthesiserVoice* const newVoice); + + /** Deletes one of the voices. */ + void removeVoice (const int index); + + /** Deletes all sounds. */ + void clearSounds(); + + /** Returns the number of sounds that have been added to the synth. */ + int getNumSounds() const throw() { return sounds.size(); } + + /** Returns one of the sounds. */ + SynthesiserSound* getSound (const int index) const throw() { return sounds [index]; } + + /** Adds a new sound to the synthesiser. + + The object passed in is reference counted, so will be deleted when it is removed + from the synthesiser, and when no voices are still using it. + */ + void addSound (const SynthesiserSound::Ptr& newSound); + + /** Removes and deletes one of the sounds. */ + void removeSound (const int index); + + /** If set to true, then the synth will try to take over an existing voice if + it runs out and needs to play another note. + + The value of this boolean is passed into findFreeVoice(), so the result will + depend on the implementation of this method. + */ + void setNoteStealingEnabled (const bool shouldStealNotes); + + /** Returns true if note-stealing is enabled. + @see setNoteStealingEnabled + */ + bool isNoteStealingEnabled() const throw() { return shouldStealNotes; } + + /** Triggers a note-on event. + + The default method here will find all the sounds that want to be triggered by + this note/channel. For each sound, it'll try to find a free voice, and use the + voice to start playing the sound. + + Subclasses might want to override this if they need a more complex algorithm. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + */ + virtual void noteOn (const int midiChannel, + const int midiNoteNumber, + const float velocity); + + /** Triggers a note-off event. + + This will turn off any voices that are playing a sound for the given note/channel. + + If allowTailOff is true, the voices will be allowed to fade out the notes gracefully + (if they can do). If this is false, the notes will all be cut off immediately. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + */ + virtual void noteOff (const int midiChannel, + const int midiNoteNumber, + const bool allowTailOff); + + /** Turns off all notes. + + This will turn off any voices that are playing a sound on the given midi channel. + + If midiChannel is 0 or less, then all voices will be turned off, regardless of + which channel they're playing. + + If allowTailOff is true, the voices will be allowed to fade out the notes gracefully + (if they can do). If this is false, the notes will all be cut off immediately. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + */ + virtual void allNotesOff (const int midiChannel, + const bool allowTailOff); + + /** Sends a pitch-wheel message. + + This will send a pitch-wheel message to any voices that are playing sounds on + the given midi channel. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + + @param midiChannel the midi channel for the event + @param wheelValue the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue() + */ + virtual void handlePitchWheel (const int midiChannel, + const int wheelValue); + + /** Sends a midi controller message. + + This will send a midi controller message to any voices that are playing sounds on + the given midi channel. + + This method will be called automatically according to the midi data passed into + renderNextBlock(), but may be called explicitly too. + + @param midiChannel the midi channel for the event + @param controllerNumber the midi controller type, as returned by MidiMessage::getControllerNumber() + @param controllerValue the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue() + */ + virtual void handleController (const int midiChannel, + const int controllerNumber, + const int controllerValue); + + /** Tells the synthesiser what the sample rate is for the audio it's being used to + render. + + This value is propagated to the voices so that they can use it to render the correct + pitches. + */ + void setCurrentPlaybackSampleRate (const double sampleRate); + + /** Creates the next block of audio output. + + This will process the next numSamples of data from all the voices, and add that output + to the audio block supplied, starting from the offset specified. Note that the + data will be added to the current contents of the buffer, so you should clear it + before calling this method if necessary. + + The midi events in the inputMidi buffer are parsed for note and controller events, + and these are used to trigger the voices. Note that the startSample offset applies + both to the audio output buffer and the midi input buffer, so any midi events + with timestamps outside the specified region will be ignored. + */ + void renderNextBlock (AudioSampleBuffer& outputAudio, + const MidiBuffer& inputMidi, + int startSample, + int numSamples); + + juce_UseDebuggingNewOperator + +protected: + + /** This is used to control access to the rendering callback and the note trigger methods. */ + CriticalSection lock; + + OwnedArray voices; + ReferenceCountedArray sounds; + + /** The last pitch-wheel values for each midi channel. */ + int lastPitchWheelValues [16]; + + /** Searches through the voices to find one that's not currently playing, and which + can play the given sound. + + Returns 0 if all voices are busy and stealing isn't enabled. + + This can be overridden to implement custom voice-stealing algorithms. + */ + virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay, + const bool stealIfNoneAvailable) const; + + /** Starts a specified voice playing a particular sound. + + You'll probably never need to call this, it's used internally by noteOn(), but + may be needed by subclasses for custom behaviours. + */ + void startVoice (SynthesiserVoice* const voice, + SynthesiserSound* const sound, + const int midiChannel, + const int midiNoteNumber, + const float velocity); + + /** xxx Temporary method here to cause a compiler error - note the new parameters for this method. */ + int findFreeVoice (const bool) const { return 0; } + +private: + double sampleRate; + uint32 lastNoteOnCounter; + bool shouldStealNotes; + + Synthesiser (const Synthesiser&); + const Synthesiser& operator= (const Synthesiser&); +}; + +#endif // __JUCE_SYNTHESISER_JUCEHEADER__ +/********* End of inlined file: juce_Synthesiser.h *********/ + +/** + A subclass of SynthesiserSound that represents a sampled audio clip. + + This is a pretty basic sampler, and just attempts to load the whole audio stream + into memory. + + To use it, create a Synthesiser, add some SamplerVoice objects to it, then + give it some SampledSound objects to play. + + @see SamplerVoice, Synthesiser, SynthesiserSound +*/ +class JUCE_API SamplerSound : public SynthesiserSound +{ +public: + + /** Creates a sampled sound from an audio reader. + + This will attempt to load the audio from the source into memory and store + it in this object. + + @param name a name for the sample + @param source the audio to load. This object can be safely deleted by the + caller after this constructor returns + @param midiNotes the set of midi keys that this sound should be played on. This + is used by the SynthesiserSound::appliesToNote() method + @param midiNoteForNormalPitch the midi note at which the sample should be played + with its natural rate. All other notes will be pitched + up or down relative to this one + @param attackTimeSecs the attack (fade-in) time, in seconds + @param releaseTimeSecs the decay (fade-out) time, in seconds + @param maxSampleLengthSeconds a maximum length of audio to read from the audio + source, in seconds + */ + SamplerSound (const String& name, + AudioFormatReader& source, + const BitArray& midiNotes, + const int midiNoteForNormalPitch, + const double attackTimeSecs, + const double releaseTimeSecs, + const double maxSampleLengthSeconds); + + /** Destructor. */ + ~SamplerSound(); + + /** Returns the sample's name */ + const String& getName() const throw() { return name; } + + /** Returns the audio sample data. + This could be 0 if there was a problem loading it. + */ + AudioSampleBuffer* getAudioData() const throw() { return data; } + + bool appliesToNote (const int midiNoteNumber); + bool appliesToChannel (const int midiChannel); + + juce_UseDebuggingNewOperator + +private: + friend class SamplerVoice; + + String name; + AudioSampleBuffer* data; + double sourceSampleRate; + BitArray midiNotes; + int length, attackSamples, releaseSamples; + int midiRootNote; +}; + +/** + A subclass of SynthesiserVoice that can play a SamplerSound. + + To use it, create a Synthesiser, add some SamplerVoice objects to it, then + give it some SampledSound objects to play. + + @see SamplerSound, Synthesiser, SynthesiserVoice +*/ +class JUCE_API SamplerVoice : public SynthesiserVoice +{ +public: + + /** Creates a SamplerVoice. + */ + SamplerVoice(); + + /** Destructor. */ + ~SamplerVoice(); + + bool canPlaySound (SynthesiserSound* sound); + + void startNote (const int midiNoteNumber, + const float velocity, + SynthesiserSound* sound, + const int currentPitchWheelPosition); + + void stopNote (const bool allowTailOff); + + void pitchWheelMoved (const int newValue); + void controllerMoved (const int controllerNumber, + const int newValue); + + void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples); + + juce_UseDebuggingNewOperator + +private: + double pitchRatio; + double sourceSamplePosition; + float lgain, rgain, attackReleaseLevel, attackDelta, releaseDelta; + bool isInAttack, isInRelease; +}; + +#endif // __JUCE_SAMPLER_JUCEHEADER__ +/********* End of inlined file: juce_Sampler.h *********/ + +#endif +#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ #endif #ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ @@ -39538,1928 +39809,129 @@ private: #ifndef __JUCE_TIMER_JUCEHEADER__ #endif -#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__ +#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ -#endif -#ifndef __JUCE_COLOUR_JUCEHEADER__ +/********* Start of inlined file: juce_ArrowButton.h *********/ +#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ +#define __JUCE_ARROWBUTTON_JUCEHEADER__ -#endif -#ifndef __JUCE_COLOURS_JUCEHEADER__ - -#endif -#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_TYPEFACE_JUCEHEADER__ - -#endif -#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ - -/********* Start of inlined file: juce_TextLayout.h *********/ -#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ -#define __JUCE_TEXTLAYOUT_JUCEHEADER__ - -class Graphics; +/********* Start of inlined file: juce_DropShadowEffect.h *********/ +#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ +#define __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ /** - A laid-out arrangement of text. + An effect filter that adds a drop-shadow behind the image's content. - You can add text in different fonts to a TextLayout object, then call its - layout() method to word-wrap it into lines. The layout can then be drawn - using a graphics context. + (This will only work on images/components that aren't opaque, of course). - It's handy if you've got a message to display, because you can format it, - measure the extent of the layout, and then create a suitably-sized window - to show it in. + When added to a component, this effect will draw a soft-edged + shadow based on what gets drawn inside it. The shadow will also + be applied to the component's children. - @see Font, Graphics::drawFittedText, GlyphArrangement + For speed, this doesn't use a proper gaussian blur, but cheats by + using a simple bilinear filter. If you need a really high-quality + shadow, check out ImageConvolutionKernel::createGaussianBlur() + + @see Component::setComponentEffect */ -class JUCE_API TextLayout +class JUCE_API DropShadowEffect : public ImageEffectFilter { public: - /** Creates an empty text layout. + /** Creates a default drop-shadow effect. - Text can then be appended using the appendText() method. + To customise the shadow's appearance, use the setShadowProperties() + method. */ - TextLayout() throw(); - - /** Creates a copy of another layout object. */ - TextLayout (const TextLayout& other) throw(); - - /** Creates a text layout from an initial string and font. */ - TextLayout (const String& text, const Font& font) throw(); + DropShadowEffect(); /** Destructor. */ - ~TextLayout() throw(); + ~DropShadowEffect(); - /** Copies another layout onto this one. */ - const TextLayout& operator= (const TextLayout& layoutToCopy) throw(); + /** Sets up parameters affecting the shadow's appearance. - /** Clears the layout, removing all its text. */ - void clear() throw(); - - /** Adds a string to the end of the arrangement. - - The string will be broken onto new lines wherever it contains - carriage-returns or linefeeds. After adding it, you can call layout() - to wrap long lines into a paragraph and justify it. + @param newRadius the (approximate) radius of the blur used + @param newOpacity the opacity with which the shadow is rendered + @param newShadowOffsetX allows the shadow to be shifted in relation to the + component's contents + @param newShadowOffsetY allows the shadow to be shifted in relation to the + component's contents */ - void appendText (const String& textToAppend, - const Font& fontToUse) throw(); + void setShadowProperties (const float newRadius, + const float newOpacity, + const int newShadowOffsetX, + const int newShadowOffsetY); - /** Replaces all the text with a new string. - - This is equivalent to calling clear() followed by appendText(). - */ - void setText (const String& newText, - const Font& fontToUse) throw(); - - /** Breaks the text up to form a paragraph with the given width. - - @param maximumWidth any text wider than this will be split - across multiple lines - @param justification how the lines are to be laid-out horizontally - @param attemptToBalanceLineLengths if true, it will try to split the lines at a - width that keeps all the lines of text at a - similar length - this is good when you're displaying - a short message and don't want it to get split - onto two lines with only a couple of words on - the second line, which looks untidy. - */ - void layout (int maximumWidth, - const Justification& justification, - const bool attemptToBalanceLineLengths) throw(); - - /** Returns the overall width of the entire text layout. */ - int getWidth() const throw(); - - /** Returns the overall height of the entire text layout. */ - int getHeight() const throw(); - - /** Returns the total number of lines of text. */ - int getNumLines() const throw() { return totalLines; } - - /** Returns the width of a particular line of text. - - @param lineNumber the line, from 0 to (getNumLines() - 1) - */ - int getLineWidth (const int lineNumber) const throw(); - - /** Renders the text at a specified position using a graphics context. - */ - void draw (Graphics& g, - const int topLeftX, - const int topLeftY) const throw(); - - /** Renders the text within a specified rectangle using a graphics context. - - The justification flags dictate how the block of text should be positioned - within the rectangle. - */ - void drawWithin (Graphics& g, - int x, int y, int w, int h, - const Justification& layoutFlags) const throw(); + /** @internal */ + void applyEffect (Image& sourceImage, Graphics& destContext); juce_UseDebuggingNewOperator private: - VoidArray tokens; - int totalLines; + int offsetX, offsetY; + float radius, opacity; }; -#endif // __JUCE_TEXTLAYOUT_JUCEHEADER__ -/********* End of inlined file: juce_TextLayout.h *********/ - -#endif -#ifndef __JUCE_FONT_JUCEHEADER__ - -#endif -#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ - -/********* Start of inlined file: juce_GlyphArrangement.h *********/ -#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ -#define __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ +#endif // __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ +/********* End of inlined file: juce_DropShadowEffect.h *********/ /** - A glyph from a particular font, with a particular size, style, - typeface and position. + A button with an arrow in it. - @see GlyphArrangement, Font + @see Button */ -class JUCE_API PositionedGlyph +class JUCE_API ArrowButton : public Button { public: - /** Returns the character the glyph represents. */ - juce_wchar getCharacter() const throw() { return character; } - /** Checks whether the glyph is actually empty. */ - bool isWhitespace() const throw() { return CharacterFunctions::isWhitespace (character); } + /** Creates an ArrowButton. - /** Returns the position of the glyph's left-hand edge. */ - float getLeft() const throw() { return x; } - /** Returns the position of the glyph's right-hand edge. */ - float getRight() const throw() { return x + w; } - /** Returns the y position of the glyph's baseline. */ - float getBaselineY() const throw() { return y; } - /** Returns the y position of the top of the glyph. */ - float getTop() const throw() { return y - font.getAscent(); } - /** Returns the y position of the bottom of the glyph. */ - float getBottom() const throw() { return y + font.getDescent(); } - - /** Shifts the glyph's position by a relative amount. */ - void moveBy (const float deltaX, - const float deltaY) throw(); - - /** Draws the glyph into a graphics context. */ - void draw (const Graphics& g) const throw(); - - /** Draws the glyph into a graphics context, with an extra transform applied to it. */ - void draw (const Graphics& g, const AffineTransform& transform) const throw(); - - /** Returns the path for this glyph. - - @param path the glyph's outline will be appended to this path + @param buttonName the name to give the button + @param arrowDirection the direction the arrow should point in, where 0.0 is + pointing right, 0.25 is down, 0.5 is left, 0.75 is up + @param arrowColour the colour to use for the arrow */ - void createPath (Path& path) const throw(); - - /** Checks to see if a point lies within this glyph. */ - bool hitTest (float x, float y) const throw(); - - juce_UseDebuggingNewOperator - -private: - - friend class GlyphArrangement; - float x, y, w; - Font font; - juce_wchar character; - int glyph; - - PositionedGlyph() throw(); -}; - -/** - A set of glyphs, each with a position. - - You can create a GlyphArrangement, text to it and then draw it onto a - graphics context. It's used internally by the text methods in the - Graphics class, but can be used directly if more control is needed. - - @see Font, PositionedGlyph -*/ -class JUCE_API GlyphArrangement -{ -public: - - /** Creates an empty arrangement. */ - GlyphArrangement() throw(); - - /** Takes a copy of another arrangement. */ - GlyphArrangement (const GlyphArrangement& other) throw(); - - /** Copies another arrangement onto this one. - - To add another arrangement without clearing this one, use addGlyphArrangement(). - */ - const GlyphArrangement& operator= (const GlyphArrangement& other) throw(); + ArrowButton (const String& buttonName, + float arrowDirection, + const Colour& arrowColour); /** Destructor. */ - ~GlyphArrangement() throw(); - - /** Returns the total number of glyphs in the arrangement. */ - int getNumGlyphs() const throw() { return glyphs.size(); } - - /** Returns one of the glyphs from the arrangement. - - @param index the glyph's index, from 0 to (getNumGlyphs() - 1). Be - careful not to pass an out-of-range index here, as it - doesn't do any bounds-checking. - */ - PositionedGlyph& getGlyph (const int index) const throw(); - - /** Clears all text from the arrangement and resets it. - */ - void clear() throw(); - - /** Appends a line of text to the arrangement. - - This will add the text as a single line, where x is the left-hand edge of the - first character, and y is the position for the text's baseline. - - If the text contains new-lines or carriage-returns, this will ignore them - use - addJustifiedText() to add multi-line arrangements. - */ - void addLineOfText (const Font& font, - const String& text, - const float x, - const float y) throw(); - - /** Adds a line of text, truncating it if it's wider than a specified size. - - This is the same as addLineOfText(), but if the line's width exceeds the value - specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."), - if useEllipsis is true, or if this is false, it will just drop any subsequent characters. - */ - void addCurtailedLineOfText (const Font& font, - const String& text, - float x, - const float y, - const float maxWidthPixels, - const bool useEllipsis) throw(); - - /** Adds some multi-line text, breaking lines at word-boundaries if they are too wide. - - This will add text to the arrangement, breaking it into new lines either where there - is a new-line or carriage-return character in the text, or where a line's width - exceeds the value set in maxLineWidth. - - Each line that is added will be laid out using the flags set in horizontalLayout, so - the lines can be left- or right-justified, or centred horizontally in the space - between x and (x + maxLineWidth). - - The y co-ordinate is the position of the baseline of the first line of text - subsequent - lines will be placed below it, separated by a distance of font.getHeight(). - */ - void addJustifiedText (const Font& font, - const String& text, - float x, float y, - const float maxLineWidth, - const Justification& horizontalLayout) throw(); - - /** Tries to fit some text withing a given space. - - This does its best to make the given text readable within the specified rectangle, - so it useful for labelling things. - - If the text is too big, it'll be squashed horizontally or broken over multiple lines - if the maximumLinesToUse value allows this. If the text just won't fit into the space, - it'll cram as much as possible in there, and put some ellipsis at the end to show that - it's been truncated. - - A Justification parameter lets you specify how the text is laid out within the rectangle, - both horizontally and vertically. - - @see Graphics::drawFittedText - */ - void addFittedText (const Font& font, - const String& text, - const float x, const float y, - const float width, const float height, - const Justification& layout, - int maximumLinesToUse, - const float minimumHorizontalScale = 0.7f) throw(); - - /** Appends another glyph arrangement to this one. */ - void addGlyphArrangement (const GlyphArrangement& other) throw(); - - /** Draws this glyph arrangement to a graphics context. - - This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&) - method, which renders the glyphs as filled vectors. - */ - void draw (const Graphics& g) const throw(); - - /** Draws this glyph arrangement to a graphics context. - - This renders the paths as filled vectors, so is far slower than the draw (Graphics&) - method for non-transformed arrangements. - */ - void draw (const Graphics& g, const AffineTransform& transform) const throw(); - - /** Converts the set of glyphs into a path. - - @param path the glyphs' outlines will be appended to this path - */ - void createPath (Path& path) const throw(); - - /** Looks for a glyph that contains the given co-ordinate. - - @returns the index of the glyph, or -1 if none were found. - */ - int findGlyphIndexAt (float x, float y) const throw(); - - /** Finds the smallest rectangle that will enclose a subset of the glyphs. - - @param startIndex the first glyph to test - @param numGlyphs the number of glyphs to include; if this is < 0, all glyphs after - startIndex will be included - @param left on return, the leftmost co-ordinate of the rectangle - @param top on return, the top co-ordinate of the rectangle - @param right on return, the rightmost co-ordinate of the rectangle - @param bottom on return, the bottom co-ordinate of the rectangle - @param includeWhitespace if true, the extent of any whitespace characters will also - be taken into account - */ - void getBoundingBox (int startIndex, - int numGlyphs, - float& left, - float& top, - float& right, - float& bottom, - const bool includeWhitespace) const throw(); - - /** Shifts a set of glyphs by a given amount. - - @param startIndex the first glyph to transform - @param numGlyphs the number of glyphs to move; if this is < 0, all glyphs after - startIndex will be used - @param deltaX the amount to add to their x-positions - @param deltaY the amount to add to their y-positions - */ - void moveRangeOfGlyphs (int startIndex, int numGlyphs, - const float deltaX, - const float deltaY) throw(); - - /** Removes a set of glyphs from the arrangement. - - @param startIndex the first glyph to remove - @param numGlyphs the number of glyphs to remove; if this is < 0, all glyphs after - startIndex will be deleted - */ - void removeRangeOfGlyphs (int startIndex, int numGlyphs) throw(); - - /** Expands or compresses a set of glyphs horizontally. - - @param startIndex the first glyph to transform - @param numGlyphs the number of glyphs to stretch; if this is < 0, all glyphs after - startIndex will be used - @param horizontalScaleFactor how much to scale their horizontal width by - */ - void stretchRangeOfGlyphs (int startIndex, int numGlyphs, - const float horizontalScaleFactor) throw(); - - /** Justifies a set of glyphs within a given space. - - This moves the glyphs as a block so that the whole thing is located within the - given rectangle with the specified layout. - - If the Justification::horizontallyJustified flag is specified, each line will - be stretched out to fill the specified width. - */ - void justifyGlyphs (const int startIndex, const int numGlyphs, - const float x, - const float y, - const float width, - const float height, - const Justification& justification) throw(); - - juce_UseDebuggingNewOperator - -private: - OwnedArray glyphs; - - int insertEllipsis (const Font& font, const float maxXPos, const int startIndex, int endIndex) throw(); - int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, - const Justification& justification, float minimumHorizontalScale) throw(); - void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw(); -}; - -#endif // __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ -/********* End of inlined file: juce_GlyphArrangement.h *********/ - -#endif -#ifndef __JUCE_FILLTYPE_JUCEHEADER__ - -#endif -#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ - -#endif -#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_EDGETABLE_JUCEHEADER__ - -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ - -/********* Start of inlined file: juce_LowLevelGraphicsContext.h *********/ -#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ -#define __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ - -/********* Start of inlined file: juce_Image.h *********/ -#ifndef __JUCE_IMAGE_JUCEHEADER__ -#define __JUCE_IMAGE_JUCEHEADER__ - -/** - Holds a fixed-size bitmap. - - The image is stored in either 24-bit RGB or 32-bit premultiplied-ARGB format. - - To draw into an image, create a Graphics object for it. - e.g. @code - - // create a transparent 500x500 image.. - Image myImage (Image::RGB, 500, 500, true); - - Graphics g (myImage); - g.setColour (Colours::red); - g.fillEllipse (20, 20, 300, 200); // draws a red ellipse in our image. - @endcode - - Other useful ways to create an image are with the ImageCache class, or the - ImageFileFormat, which provides a way to load common image files. - - @see Graphics, ImageFileFormat, ImageCache, ImageConvolutionKernel -*/ -class JUCE_API Image -{ -public: - - enum PixelFormat - { - RGB, /**<< each pixel is a 3-byte packed RGB colour value. For byte order, see the PixelRGB class. */ - ARGB, /**<< each pixel is a 4-byte ARGB premultiplied colour value. For byte order, see the PixelARGB class. */ - SingleChannel /**<< each pixel is a 1-byte alpha channel value. */ - }; - - /** Creates an in-memory image with a specified size and format. - - To create an image that can use native OS rendering methods, see createNativeImage(). - - @param format the number of colour channels in the image - @param imageWidth the desired width of the image, in pixels - this value must be - greater than zero (otherwise a width of 1 will be used) - @param imageHeight the desired width of the image, in pixels - this value must be - greater than zero (otherwise a height of 1 will be used) - @param clearImage if true, the image will initially be cleared to black or transparent - black. If false, the image may contain random data, and the - user will have to deal with this - */ - Image (const PixelFormat format, - const int imageWidth, - const int imageHeight, - const bool clearImage); - - /** Creates a copy of another image. - - @see createCopy - */ - Image (const Image& other); - - /** Destructor. */ - virtual ~Image(); - - /** Tries to create an image that is uses native drawing methods when you render - onto it. - - On some platforms this will just return a normal software-based image. - */ - static Image* createNativeImage (const PixelFormat format, - const int imageWidth, - const int imageHeight, - const bool clearImage); - - /** Returns the image's width (in pixels). */ - int getWidth() const throw() { return imageWidth; } - - /** Returns the image's height (in pixels). */ - int getHeight() const throw() { return imageHeight; } - - /** Returns a rectangle with the same size as this image. - The rectangle is always at position (0, 0). - */ - const Rectangle getBounds() const throw() { return Rectangle (0, 0, imageWidth, imageHeight); } - - /** Returns the image's pixel format. */ - PixelFormat getFormat() const throw() { return format; } - - /** True if the image's format is ARGB. */ - bool isARGB() const throw() { return format == ARGB; } - - /** True if the image's format is RGB. */ - bool isRGB() const throw() { return format == RGB; } - - /** True if the image contains an alpha-channel. */ - bool hasAlphaChannel() const throw() { return format != RGB; } - - /** Clears a section of the image with a given colour. - - This won't do any alpha-blending - it just sets all pixels in the image to - the given colour (which may be non-opaque if the image has an alpha channel). - */ - virtual void clear (int x, int y, int w, int h, - const Colour& colourToClearTo = Colour (0x00000000)); - - /** Returns a new image that's a copy of this one. - - A new size for the copied image can be specified, or values less than - zero can be passed-in to use the image's existing dimensions. - - It's up to the caller to delete the image when no longer needed. - */ - virtual Image* createCopy (int newWidth = -1, - int newHeight = -1, - const Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const; - - /** Returns a new single-channel image which is a copy of the alpha-channel of this image. - */ - virtual Image* createCopyOfAlphaChannel() const; - - /** Returns the colour of one of the pixels in the image. - - If the co-ordinates given are beyond the image's boundaries, this will - return Colours::transparentBlack. - - (0, 0) is the image's top-left corner. - - @see getAlphaAt, setPixelAt, blendPixelAt - */ - virtual const Colour getPixelAt (const int x, const int y) const; - - /** Sets the colour of one of the image's pixels. - - If the co-ordinates are beyond the image's boundaries, then nothing will - happen. - - Note that unlike blendPixelAt(), this won't do any alpha-blending, it'll - just replace the existing pixel with the given one. The colour's opacity - will be ignored if this image doesn't have an alpha-channel. - - (0, 0) is the image's top-left corner. - - @see blendPixelAt - */ - virtual void setPixelAt (const int x, const int y, const Colour& colour); - - /** Changes the opacity of a pixel. - - This only has an effect if the image has an alpha channel and if the - given co-ordinates are inside the image's boundary. - - The multiplier must be in the range 0 to 1.0, and the current alpha - at the given co-ordinates will be multiplied by this value. - - @see getAlphaAt, setPixelAt - */ - virtual void multiplyAlphaAt (const int x, const int y, const float multiplier); - - /** Changes the overall opacity of the image. - - This will multiply the alpha value of each pixel in the image by the given - amount (limiting the resulting alpha values between 0 and 255). This allows - you to make an image more or less transparent. - - If the image doesn't have an alpha channel, this won't have any effect. - */ - virtual void multiplyAllAlphas (const float amountToMultiplyBy); - - /** Changes all the colours to be shades of grey, based on their current luminosity. - */ - virtual void desaturate(); - - /** Retrieves a section of an image as raw pixel data, so it can be read or written to. - - You should only use this class as a last resort - messing about with the internals of - an image is only recommended for people who really know what they're doing! - - A BitmapData object should be used as a temporary, stack-based object. Don't keep one - hanging around while the image is being used elsewhere. - - Depending on the way the image class is implemented, this may create a temporary buffer - which is copied back to the image when the object is deleted, or it may just get a pointer - directly into the image's raw data. - - You can use the stride and data values in this class directly, but don't alter them! - The actual format of the pixel data depends on the image's format - see Image::getFormat(), - and the PixelRGB, PixelARGB and PixelAlpha classes for more info. - */ - class BitmapData - { - public: - BitmapData (Image& image, int x, int y, int w, int h, const bool needsToBeWritable) throw(); - BitmapData (const Image& image, int x, int y, int w, int h) throw(); - ~BitmapData() throw(); - - /** Returns a pointer to the start of a line in the image. - The co-ordinate you provide here isn't checked, so it's the caller's responsibility to make - sure it's not out-of-range. - */ - inline uint8* getLinePointer (const int y) const throw() { return data + y * lineStride; } - - /** Returns a pointer to a pixel in the image. - The co-ordinates you give here are not checked, so it's the caller's responsibility to make sure they're - not out-of-range. - */ - inline uint8* getPixelPointer (const int x, const int y) const throw() { return data + y * lineStride + x * pixelStride; } - - uint8* data; - int lineStride, pixelStride, width, height; - - private: - BitmapData (const BitmapData&); - const BitmapData& operator= (const BitmapData&); - }; - - /** Copies some pixel values to a rectangle of the image. - - The format of the pixel data must match that of the image itself, and the - rectangle supplied must be within the image's bounds. - */ - virtual void setPixelData (int destX, int destY, int destW, int destH, - const uint8* sourcePixelData, int sourceLineStride); - - /** Copies a section of the image to somewhere else within itself. - */ - virtual void moveImageSection (int destX, int destY, - int sourceX, int sourceY, - int width, int height); - - /** Creates a RectangleList containing rectangles for all non-transparent pixels - of the image. - - @param result the list that will have the area added to it - @param alphaThreshold for a semi-transparent image, any pixels whose alpha is - above this level will be considered opaque - */ - void createSolidAreaMask (RectangleList& result, - const float alphaThreshold = 0.5f) const; - - juce_UseDebuggingNewOperator - - /** Creates a context suitable for drawing onto this image. - - Don't call this method directly! It's used internally by the Graphics class. - */ - virtual LowLevelGraphicsContext* createLowLevelContext(); - -protected: - friend class BitmapData; - const PixelFormat format; - const int imageWidth, imageHeight; - - /** Used internally so that subclasses can call a constructor that doesn't allocate memory */ - Image (const PixelFormat format, - const int imageWidth, - const int imageHeight); - - int pixelStride, lineStride; - uint8* imageData; - -private: - - const Image& operator= (const Image&); -}; - -#endif // __JUCE_IMAGE_JUCEHEADER__ -/********* End of inlined file: juce_Image.h *********/ - -/** - Interface class for graphics context objects, used internally by the Graphics class. - - Users are not supposed to create instances of this class directly - do your drawing - via the Graphics object instead. - - It's a base class for different types of graphics context, that may perform software-based - or OS-accelerated rendering. - - E.g. the LowLevelGraphicsSoftwareRenderer renders onto an image in memory, but other - subclasses could render directly to a windows HDC, a Quartz context, or an OpenGL - context. -*/ -class JUCE_API LowLevelGraphicsContext -{ -protected: - - LowLevelGraphicsContext(); - -public: - virtual ~LowLevelGraphicsContext(); - - /** Returns true if this device is vector-based, e.g. a printer. */ - virtual bool isVectorDevice() const = 0; - - /** Moves the origin to a new position. - - The co-ords are relative to the current origin, and indicate the new position - of (0, 0). - */ - virtual void setOrigin (int x, int y) = 0; - - virtual bool clipToRectangle (const Rectangle& r) = 0; - virtual bool clipToRectangleList (const RectangleList& clipRegion) = 0; - virtual void excludeClipRectangle (const Rectangle& r) = 0; - virtual void clipToPath (const Path& path, const AffineTransform& transform) = 0; - virtual void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) = 0; - - virtual bool clipRegionIntersects (const Rectangle& r) = 0; - virtual const Rectangle getClipBounds() const = 0; - virtual bool isClipEmpty() const = 0; - - virtual void saveState() = 0; - virtual void restoreState() = 0; - - virtual void setFill (const FillType& fillType) = 0; - virtual void setOpacity (float newOpacity) = 0; - virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0; - - virtual void fillRect (const Rectangle& r, const bool replaceExistingContents) = 0; - virtual void fillPath (const Path& path, const AffineTransform& transform) = 0; - - virtual void drawImage (const Image& sourceImage, const Rectangle& srcClip, - const AffineTransform& transform, const bool fillEntireClipAsTiles) = 0; - - virtual void drawLine (double x1, double y1, double x2, double y2) = 0; - virtual void drawVerticalLine (const int x, double top, double bottom) = 0; - virtual void drawHorizontalLine (const int y, double left, double right) = 0; - - virtual void setFont (const Font& newFont) = 0; - virtual const Font getFont() = 0; - virtual void drawGlyph (int glyphNumber, const AffineTransform& transform) = 0; -}; - -#endif // __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ -/********* End of inlined file: juce_LowLevelGraphicsContext.h *********/ - -#endif -#ifndef __JUCE_GRAPHICS_JUCEHEADER__ - -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ - -/********* Start of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/ -#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ -#define __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ - -class LLGCSavedState; - -/** - A lowest-common-denominator implementation of LowLevelGraphicsContext that does all - its rendering in memory. - - User code is not supposed to create instances of this class directly - do all your - rendering via the Graphics class instead. -*/ -class JUCE_API LowLevelGraphicsSoftwareRenderer : public LowLevelGraphicsContext -{ -public: - - LowLevelGraphicsSoftwareRenderer (Image& imageToRenderOn); - ~LowLevelGraphicsSoftwareRenderer(); - - bool isVectorDevice() const; - - void setOrigin (int x, int y); - - bool clipToRectangle (const Rectangle& r); - bool clipToRectangleList (const RectangleList& clipRegion); - void excludeClipRectangle (const Rectangle& r); - void clipToPath (const Path& path, const AffineTransform& transform); - void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); - - bool clipRegionIntersects (const Rectangle& r); - const Rectangle getClipBounds() const; - bool isClipEmpty() const; - - void saveState(); - void restoreState(); - - void setFill (const FillType& fillType); - void setOpacity (float opacity); - void setInterpolationQuality (Graphics::ResamplingQuality quality); - - void fillRect (const Rectangle& r, const bool replaceExistingContents); - void fillPath (const Path& path, const AffineTransform& transform); - - void drawImage (const Image& sourceImage, const Rectangle& srcClip, - const AffineTransform& transform, const bool fillEntireClipAsTiles); - - void drawLine (double x1, double y1, double x2, double y2); - - void drawVerticalLine (const int x, double top, double bottom); - void drawHorizontalLine (const int x, double top, double bottom); - - void setFont (const Font& newFont); - const Font getFont(); - void drawGlyph (int glyphNumber, float x, float y); - void drawGlyph (int glyphNumber, const AffineTransform& transform); - - juce_UseDebuggingNewOperator - -protected: - - Image& image; - - LLGCSavedState* currentState; - OwnedArray stateStack; - - LowLevelGraphicsSoftwareRenderer (const LowLevelGraphicsSoftwareRenderer& other); - const LowLevelGraphicsSoftwareRenderer& operator= (const LowLevelGraphicsSoftwareRenderer&); -}; - -#endif // __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ -/********* End of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/ - -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ - -/********* Start of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/ -#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ -#define __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ - -/** - An implementation of LowLevelGraphicsContext that turns the drawing operations - into a PostScript document. - -*/ -class JUCE_API LowLevelGraphicsPostScriptRenderer : public LowLevelGraphicsContext -{ -public: - - LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript, - const String& documentTitle, - const int totalWidth, - const int totalHeight); - - ~LowLevelGraphicsPostScriptRenderer(); - - bool isVectorDevice() const; - void setOrigin (int x, int y); - - bool clipToRectangle (const Rectangle& r); - bool clipToRectangleList (const RectangleList& clipRegion); - void excludeClipRectangle (const Rectangle& r); - void clipToPath (const Path& path, const AffineTransform& transform); - void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); - - void saveState(); - void restoreState(); - - bool clipRegionIntersects (const Rectangle& r); - const Rectangle getClipBounds() const; - bool isClipEmpty() const; - - void setFill (const FillType& fillType); - void setOpacity (float opacity); - void setInterpolationQuality (Graphics::ResamplingQuality quality); - - void fillRect (const Rectangle& r, const bool replaceExistingContents); - void fillPath (const Path& path, const AffineTransform& transform); - - void drawImage (const Image& sourceImage, const Rectangle& srcClip, - const AffineTransform& transform, const bool fillEntireClipAsTiles); - - void drawLine (double x1, double y1, double x2, double y2); - - void drawVerticalLine (const int x, double top, double bottom); - void drawHorizontalLine (const int x, double top, double bottom); - - const Font getFont(); - void setFont (const Font& newFont); - void drawGlyph (int glyphNumber, const AffineTransform& transform); - - juce_UseDebuggingNewOperator - -protected: - - OutputStream& out; - int totalWidth, totalHeight; - bool needToClip; - Colour lastColour; - - struct SavedState - { - SavedState(); - ~SavedState(); - - RectangleList clip; - int xOffset, yOffset; - FillType fillType; - Font font; - - private: - const SavedState& operator= (const SavedState&); - }; - - OwnedArray stateStack; - - void writeClip(); - void writeColour (const Colour& colour); - void writePath (const Path& path) const; - void writeXY (const float x, const float y) const; - void writeTransform (const AffineTransform& trans) const; - void writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const; - - LowLevelGraphicsPostScriptRenderer (const LowLevelGraphicsPostScriptRenderer& other); - const LowLevelGraphicsPostScriptRenderer& operator= (const LowLevelGraphicsPostScriptRenderer&); -}; - -#endif // __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ -/********* End of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/ - -#endif -#ifndef __JUCE_PATH_JUCEHEADER__ - -#endif -#ifndef __JUCE_BORDERSIZE_JUCEHEADER__ - -#endif -#ifndef __JUCE_LINE_JUCEHEADER__ - -#endif -#ifndef __JUCE_POINT_JUCEHEADER__ - -#endif -#ifndef __JUCE_RECTANGLE_JUCEHEADER__ - -#endif -#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ - -#endif -#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ - -/********* Start of inlined file: juce_PositionedRectangle.h *********/ -#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ -#define __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ - -/** - A rectangle whose co-ordinates can be defined in terms of absolute or - proportional distances. - - Designed mainly for storing component positions, this gives you a lot of - control over how each co-ordinate is stored, either as an absolute position, - or as a proportion of the size of a parent rectangle. - - It also allows you to define the anchor points by which the rectangle is - positioned, so for example you could specify that the top right of the - rectangle should be an absolute distance from its parent's bottom-right corner. - - This object can be stored as a string, which takes the form "x y w h", including - symbols like '%' and letters to indicate the anchor point. See its toString() - method for more info. - - Example usage: - @code - class MyComponent - { - void resized() - { - // this will set the child component's x to be 20% of our width, its y - // to be 30, its width to be 150, and its height to be 50% of our - // height.. - const PositionedRectangle pos1 ("20% 30 150 50%"); - pos1.applyToComponent (*myChildComponent1); - - // this will inset the child component with a gap of 10 pixels - // around each of its edges.. - const PositionedRectangle pos2 ("10 10 20M 20M"); - pos2.applyToComponent (*myChildComponent2); - } - }; - @endcode -*/ -class JUCE_API PositionedRectangle -{ -public: - - /** Creates an empty rectangle with all co-ordinates set to zero. - - The default anchor point is top-left; the default - */ - PositionedRectangle() throw(); - - /** Initialises a PositionedRectangle from a saved string version. - - The string must be in the format generated by toString(). - */ - PositionedRectangle (const String& stringVersion) throw(); - - /** Creates a copy of another PositionedRectangle. */ - PositionedRectangle (const PositionedRectangle& other) throw(); - - /** Copies another PositionedRectangle. */ - const PositionedRectangle& operator= (const PositionedRectangle& other) throw(); - - /** Destructor. */ - ~PositionedRectangle() throw(); - - /** Returns a string version of this position, from which it can later be - re-generated. - - The format is four co-ordinates, "x y w h". - - - If a co-ordinate is absolute, it is stored as an integer, e.g. "100". - - If a co-ordinate is proportional to its parent's width or height, it is stored - as a percentage, e.g. "80%". - - If the X or Y co-ordinate is relative to the parent's right or bottom edge, the - number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from - the parent's right-hand edge. - - If the X or Y co-ordinate is relative to the parent's centre, the number has "C" - appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre. - - If the X or Y co-ordinate should be anchored at the component's right or bottom - edge, then it has "r" appended to it. So "-50Rr" would mean that this component's - right-hand edge should be 50 pixels left of the parent's right-hand edge. - - If the X or Y co-ordinate should be anchored at the component's centre, then it - has "c" appended to it. So "-50Rc" would mean that this component's - centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that - this component's centre should be placed 40% across the parent's width. - - If it's a width or height that should use the parentSizeMinusAbsolute mode, then - the number has "M" appended to it. - - To reload a stored string, use the constructor that takes a string parameter. - */ - const String toString() const throw(); - - /** Calculates the absolute position, given the size of the space that - it should go in. - - This will work out any proportional distances and sizes relative to the - target rectangle, and will return the absolute position. - - @see applyToComponent - */ - const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw(); - - /** Same as getRectangle(), but returning the values as doubles rather than ints. - */ - void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo, - double& x, - double& y, - double& width, - double& height) const throw(); - - /** This sets the bounds of the given component to this position. - - This is equivalent to writing: - @code - comp.setBounds (getRectangle (Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight()))); - @endcode - - @see getRectangle, updateFromComponent - */ - void applyToComponent (Component& comp) const throw(); - - /** Updates this object's co-ordinates to match the given rectangle. - - This will set all co-ordinates based on the given rectangle, re-calculating - any proportional distances, and using the current anchor points. - - So for example if the x co-ordinate mode is currently proportional, this will - re-calculate x based on the rectangle's relative position within the target - rectangle's width. - - If the target rectangle's width or height are zero then it may not be possible - to re-calculate some proportional co-ordinates. In this case, those co-ordinates - will not be changed. - */ - void updateFrom (const Rectangle& newPosition, - const Rectangle& targetSpaceToBeRelativeTo) throw(); - - /** Same functionality as updateFrom(), but taking doubles instead of ints. - */ - void updateFromDouble (const double x, const double y, - const double width, const double height, - const Rectangle& targetSpaceToBeRelativeTo) throw(); - - /** Updates this object's co-ordinates to match the bounds of this component. - - This is equivalent to calling updateFrom() with the component's bounds and - it parent size. - - If the component doesn't currently have a parent, then proportional co-ordinates - might not be updated because it would need to know the parent's size to do the - maths for this. - */ - void updateFromComponent (const Component& comp) throw(); - - /** Specifies the point within the rectangle, relative to which it should be positioned. */ - enum AnchorPoint - { - anchorAtLeftOrTop = 1 << 0, /**< The x or y co-ordinate specifies where the left or top edge of the rectangle should be. */ - anchorAtRightOrBottom = 1 << 1, /**< The x or y co-ordinate specifies where the right or bottom edge of the rectangle should be. */ - anchorAtCentre = 1 << 2 /**< The x or y co-ordinate specifies where the centre of the rectangle should be. */ - }; - - /** Specifies how an x or y co-ordinate should be interpreted. */ - enum PositionMode - { - absoluteFromParentTopLeft = 1 << 3, /**< The x or y co-ordinate specifies an absolute distance from the parent's top or left edge. */ - absoluteFromParentBottomRight = 1 << 4, /**< The x or y co-ordinate specifies an absolute distance from the parent's bottom or right edge. */ - absoluteFromParentCentre = 1 << 5, /**< The x or y co-ordinate specifies an absolute distance from the parent's centre. */ - proportionOfParentSize = 1 << 6 /**< The x or y co-ordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */ - }; - - /** Specifies how the width or height should be interpreted. */ - enum SizeMode - { - absoluteSize = 1 << 0, /**< The width or height specifies an absolute size. */ - parentSizeMinusAbsolute = 1 << 1, /**< The width or height is an amount that should be subtracted from the parent's width or height. */ - proportionalSize = 1 << 2, /**< The width or height specifies a proportion of the parent's width or height. */ - }; - - /** Sets all options for all co-ordinates. - - This requires a reference rectangle to be specified, because if you're changing any - of the modes from proportional to absolute or vice-versa, then it'll need to convert - the co-ordinates, and will need to know the parent size so it can calculate this. - */ - void setModes (const AnchorPoint xAnchorMode, - const PositionMode xPositionMode, - const AnchorPoint yAnchorMode, - const PositionMode yPositionMode, - const SizeMode widthMode, - const SizeMode heightMode, - const Rectangle& targetSpaceToBeRelativeTo) throw(); - - /** Returns the anchoring mode for the x co-ordinate. - To change any of the modes, use setModes(). - */ - AnchorPoint getAnchorPointX() const throw(); - - /** Returns the positioning mode for the x co-ordinate. - To change any of the modes, use setModes(). - */ - PositionMode getPositionModeX() const throw(); - - /** Returns the raw x co-ordinate. - - If the x position mode is absolute, then this will be the absolute value. If it's - proportional, then this will be a fractional proportion, where 1.0 means the full - width of the parent space. - */ - double getX() const throw() { return x; } - - /** Sets the raw value of the x co-ordinate. - - See getX() for the meaning of this value. - */ - void setX (const double newX) throw() { x = newX; } - - /** Returns the anchoring mode for the y co-ordinate. - To change any of the modes, use setModes(). - */ - AnchorPoint getAnchorPointY() const throw(); - - /** Returns the positioning mode for the y co-ordinate. - To change any of the modes, use setModes(). - */ - PositionMode getPositionModeY() const throw(); - - /** Returns the raw y co-ordinate. - - If the y position mode is absolute, then this will be the absolute value. If it's - proportional, then this will be a fractional proportion, where 1.0 means the full - height of the parent space. - */ - double getY() const throw() { return y; } - - /** Sets the raw value of the y co-ordinate. - - See getY() for the meaning of this value. - */ - void setY (const double newY) throw() { y = newY; } - - /** Returns the mode used to calculate the width. - To change any of the modes, use setModes(). - */ - SizeMode getWidthMode() const throw(); - - /** Returns the raw width value. - - If the width mode is absolute, then this will be the absolute value. If the mode is - proportional, then this will be a fractional proportion, where 1.0 means the full - width of the parent space. - */ - double getWidth() const throw() { return w; } - - /** Sets the raw width value. - - See getWidth() for the details about what this value means. - */ - void setWidth (const double newWidth) throw() { w = newWidth; } - - /** Returns the mode used to calculate the height. - To change any of the modes, use setModes(). - */ - SizeMode getHeightMode() const throw(); - - /** Returns the raw height value. - - If the height mode is absolute, then this will be the absolute value. If the mode is - proportional, then this will be a fractional proportion, where 1.0 means the full - height of the parent space. - */ - double getHeight() const throw() { return h; } - - /** Sets the raw height value. - - See getHeight() for the details about what this value means. - */ - void setHeight (const double newHeight) throw() { h = newHeight; } - - /** If the size and position are constance, and wouldn't be affected by changes - in the parent's size, then this will return true. - */ - bool isPositionAbsolute() const throw(); - - /** Compares two objects. */ - const bool operator== (const PositionedRectangle& other) const throw(); - - /** Compares two objects. */ - const bool operator!= (const PositionedRectangle& other) const throw(); - - juce_UseDebuggingNewOperator - -private: - double x, y, w, h; - uint8 xMode, yMode, wMode, hMode; - - void addPosDescription (String& result, const uint8 mode, const double value) const throw(); - void addSizeDescription (String& result, const uint8 mode, const double value) const throw(); - void decodePosString (const String& s, uint8& mode, double& value) throw(); - void decodeSizeString (const String& s, uint8& mode, double& value) throw(); - void applyPosAndSize (double& xOut, double& wOut, const double x, const double w, - const uint8 xMode, const uint8 wMode, - const int parentPos, const int parentSize) const throw(); - void updatePosAndSize (double& xOut, double& wOut, double x, const double w, - const uint8 xMode, const uint8 wMode, - const int parentPos, const int parentSize) const throw(); -}; - -#endif // __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ -/********* End of inlined file: juce_PositionedRectangle.h *********/ - -#endif -#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ - -#endif -#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ - -/********* Start of inlined file: juce_PathIterator.h *********/ -#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ -#define __JUCE_PATHITERATOR_JUCEHEADER__ - -/** - Flattens a Path object into a series of straight-line sections. - - Use one of these to iterate through a Path object, and it will convert - all the curves into line sections so it's easy to render or perform - geometric operations on. - - @see Path -*/ -class JUCE_API PathFlatteningIterator -{ -public: - - /** Creates a PathFlatteningIterator. - - After creation, use the next() method to initialise the fields in the - object with the first line's position. - - @param path the path to iterate along - @param transform a transform to apply to each point in the path being iterated - @param tolerence the amount by which the curves are allowed to deviate from the - lines into which they are being broken down - a higher tolerence - is a bit faster, but less smooth. - */ - PathFlatteningIterator (const Path& path, - const AffineTransform& transform = AffineTransform::identity, - float tolerence = 6.0f) throw(); - - /** Destructor. */ - ~PathFlatteningIterator() throw(); - - /** Fetches the next line segment from the path. - - This will update the member variables x1, y1, x2, y2, subPathIndex and closesSubPath - so that they describe the new line segment. - - @returns false when there are no more lines to fetch. - */ - bool next() throw(); - - /** The x position of the start of the current line segment. */ - float x1; - /** The y position of the start of the current line segment. */ - float y1; - /** The x position of the end of the current line segment. */ - float x2; - /** The y position of the end of the current line segment. */ - float y2; - - /** Indicates whether the current line segment is closing a sub-path. - - If the current line is the one that connects the end of a sub-path - back to the start again, this will be true. - */ - bool closesSubPath; - - /** The index of the current line within the current sub-path. - - E.g. you can use this to see whether the line is the first one in the - subpath by seeing if it's 0. - */ - int subPathIndex; - - /** Returns true if the current segment is the last in the current sub-path. */ - bool isLastInSubpath() const throw() { return stackPos == stackBase - && (index >= path.numElements - || points [index] == Path::moveMarker); } - - juce_UseDebuggingNewOperator - -private: - const Path& path; - const AffineTransform transform; - float* points; - float tolerence, subPathCloseX, subPathCloseY; - bool isIdentityTransform; - - float* stackBase; - float* stackPos; - int index, stackSize; - - PathFlatteningIterator (const PathFlatteningIterator&); - const PathFlatteningIterator& operator= (const PathFlatteningIterator&); -}; - -#endif // __JUCE_PATHITERATOR_JUCEHEADER__ -/********* End of inlined file: juce_PathIterator.h *********/ - -#endif -#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ - -#endif -#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ - -/********* Start of inlined file: juce_CameraDevice.h *********/ -#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ -#define __JUCE_CAMERADEVICE_JUCEHEADER__ - -#if JUCE_USE_CAMERA - -/** - Receives callbacks with images from a CameraDevice. - - @see CameraDevice::addListener -*/ -class CameraImageListener -{ -public: - CameraImageListener() {} - virtual ~CameraImageListener() {} - - /** This method is called when a new image arrives. - - This may be called by any thread, so be careful about thread-safety, - and make sure that you process the data as quickly as possible to - avoid glitching! - */ - virtual void imageReceived (Image& image) = 0; -}; - -/** - Controls any camera capture devices that might be available. - - Use getAvailableDevices() to list the devices that are attached to the - system, then call openDevice to open one for use. Once you have a CameraDevice - object, you can get a viewer component from it, and use its methods to - stream to a file or capture still-frames. -*/ -class JUCE_API CameraDevice -{ -public: - /** Destructor. */ - virtual ~CameraDevice(); - - /** Returns a list of the available cameras on this machine. - - You can open one of these devices by calling openDevice(). - */ - static const StringArray getAvailableDevices(); - - /** Opens a camera device. - - The index parameter indicates which of the items returned by getAvailableDevices() - to open. - - The size constraints allow the method to choose between different resolutions if - the camera supports this. If the resolution cam't be specified (e.g. on the Mac) - then these will be ignored. - */ - static CameraDevice* openDevice (int deviceIndex, - int minWidth = 128, int minHeight = 64, - int maxWidth = 1024, int maxHeight = 768); - - /** Returns the name of this device */ - const String getName() const throw() { return name; } - - /** Creates a component that can be used to display a preview of the - video from this camera. - */ - Component* createViewerComponent(); - - /** Starts recording video to the specified file. - - You should use getFileExtension() to find out the correct extension to - use for your filename. - - If the file exists, it will be deleted before the recording starts. - - This method may not start recording instantly, so if you need to know the - exact time at which the file begins, you can call getTimeOfFirstRecordedFrame() - after the recording has finished. - */ - void startRecordingToFile (const File& file); - - /** Stops recording, after a call to startRecordingToFile(). - */ - void stopRecording(); - - /** Returns the file extension that should be used for the files - that you pass to startRecordingToFile(). - - This may be platform-specific, e.g. ".mov" or ".avi". - */ - static const String getFileExtension(); - - /** After calling stopRecording(), this method can be called to return the timestamp - of the first frame that was written to the file. - */ - const Time getTimeOfFirstRecordedFrame() const; - - /** Adds a listener to receive images from the camera. - - Be very careful not to delete the listener without first removing it by calling - removeListener(). - */ - void addListener (CameraImageListener* listenerToAdd); - - /** Removes a listener that was previously added with addListener(). - */ - void removeListener (CameraImageListener* listenerToRemove); + ~ArrowButton(); juce_UseDebuggingNewOperator protected: /** @internal */ - CameraDevice (const String& name, int index); + void paintButton (Graphics& g, + bool isMouseOverButton, + bool isButtonDown); -private: - void* internal; - bool isRecording; - String name; - - CameraDevice (const CameraDevice&); - const CameraDevice& operator= (const CameraDevice&); -}; - -#endif -#endif // __JUCE_CAMERADEVICE_JUCEHEADER__ -/********* End of inlined file: juce_CameraDevice.h *********/ - -#endif -#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ - -/********* Start of inlined file: juce_ImageCache.h *********/ -#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ -#define __JUCE_IMAGECACHE_JUCEHEADER__ - -/** - A global cache of images that have been loaded from files or memory. - - If you're loading an image and may need to use the image in more than one - place, this is used to allow the same image to be shared rather than loading - multiple copies into memory. - - Another advantage is that after images are released, they will be kept in - memory for a few seconds before it is actually deleted, so if you're repeatedly - loading/deleting the same image, it'll reduce the chances of having to reload it - each time. - - @see Image, ImageFileFormat -*/ -class JUCE_API ImageCache : private DeletedAtShutdown, - private Timer -{ -public: - - /** Loads an image from a file, (or just returns the image if it's already cached). - - If the cache already contains an image that was loaded from this file, - that image will be returned. Otherwise, this method will try to load the - file, add it to the cache, and return it. - - It's very important not to delete the image that is returned - instead use - the ImageCache::release() method. - - Also, remember that the image returned is shared, so drawing into it might - affect other things that are using it! - - @param file the file to try to load - @returns the image, or null if it there was an error loading it - @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom - */ - static Image* getFromFile (const File& file); - - /** Loads an image from an in-memory image file, (or just returns the image if it's already cached). - - If the cache already contains an image that was loaded from this block of memory, - that image will be returned. Otherwise, this method will try to load the - file, add it to the cache, and return it. - - It's very important not to delete the image that is returned - instead use - the ImageCache::release() method. - - Also, remember that the image returned is shared, so drawing into it might - affect other things that are using it! - - @param imageData the block of memory containing the image data - @param dataSize the data size in bytes - @returns the image, or null if it there was an error loading it - @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom - */ - static Image* getFromMemory (const void* imageData, - const int dataSize); - - /** Releases an image that was previously created by the ImageCache. - - If an image has been returned by the getFromFile() or getFromMemory() methods, - it mustn't be deleted directly, but should be released with this method - instead. - - @see getFromFile, getFromMemory - */ - static void release (Image* const imageToRelease); - - /** Checks whether an image is in the cache or not. - - @returns true if the image is currently in the cache - */ - static bool isImageInCache (Image* const imageToLookFor); - - /** Increments the reference-count for a cached image. - - If the image isn't in the cache, this method won't do anything. - */ - static void incReferenceCount (Image* const image); - - /** Checks the cache for an image with a particular hashcode. - - If there's an image in the cache with this hashcode, it will be returned, - otherwise it will return zero. - - If an image is returned, it must be released with the release() method - when no longer needed, to maintain the correct reference counts. - - @param hashCode the hash code that would have been associated with the - image by addImageToCache() - @see addImageToCache - */ - static Image* getFromHashCode (const int64 hashCode); - - /** Adds an image to the cache with a user-defined hash-code. - - After calling this, responsibilty for deleting the image will be taken - by the ImageCache. - - The image will be initially be given a reference count of 1, so call - the release() method to delete it. - - @param image the image to add - @param hashCode the hash-code to associate with it - @see getFromHashCode - */ - static void addImageToCache (Image* const image, - const int64 hashCode); - - /** Changes the amount of time before an unused image will be removed from the cache. - - By default this is about 5 seconds. - */ - static void setCacheTimeout (const int millisecs); - - juce_UseDebuggingNewOperator + /** @internal */ + void buttonStateChanged(); private: - CriticalSection lock; - VoidArray images; + Colour colour; + DropShadowEffect shadow; + Path path; + int offset; - ImageCache() throw(); - ImageCache (const ImageCache&); - const ImageCache& operator= (const ImageCache&); - ~ImageCache(); - - void timerCallback(); + ArrowButton (const ArrowButton&); + const ArrowButton& operator= (const ArrowButton&); }; -#endif // __JUCE_IMAGECACHE_JUCEHEADER__ -/********* End of inlined file: juce_ImageCache.h *********/ +#endif // __JUCE_ARROWBUTTON_JUCEHEADER__ +/********* End of inlined file: juce_ArrowButton.h *********/ #endif -#ifndef __JUCE_IMAGE_JUCEHEADER__ +#ifndef __JUCE_BUTTON_JUCEHEADER__ #endif -#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ +#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ -/********* Start of inlined file: juce_ImageFileFormat.h *********/ -#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ -#define __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ - -/** - Base-class for codecs that can read and write image file formats such - as PNG, JPEG, etc. - - This class also contains static methods to make it easy to load images - from files, streams or from memory. - - @see Image, ImageCache -*/ -class JUCE_API ImageFileFormat -{ -protected: - - /** Creates an ImageFormat. */ - ImageFileFormat() throw() {} - -public: - /** Destructor. */ - virtual ~ImageFileFormat() throw() {} - - /** Returns a description of this file format. - - E.g. "JPEG", "PNG" - */ - virtual const String getFormatName() = 0; - - /** Returns true if the given stream seems to contain data that this format - understands. - - The format class should only read the first few bytes of the stream and sniff - for header bytes that it understands. - - @see decodeImage - */ - virtual bool canUnderstand (InputStream& input) = 0; - - /** Tries to decode and return an image from the given stream. - - This will be called for an image format after calling its canUnderStand() method - to see if it can handle the stream. - - @param input the stream to read the data from. The stream will be positioned - at the start of the image data (but this may not necessarily - be position 0) - @returns the image that was decoded, or 0 if it fails. It's the - caller's responsibility to delete this image when no longer needed. - @see loadFrom - */ - virtual Image* decodeImage (InputStream& input) = 0; - - /** Attempts to write an image to a stream. - - To specify extra information like encoding quality, there will be appropriate parameters - in the subclasses of the specific file types. - - @returns true if it nothing went wrong. - */ - virtual bool writeImageToStream (const Image& sourceImage, - OutputStream& destStream) = 0; - - /** Tries the built-in decoders to see if it can find one to read this stream. - - There are currently built-in decoders for PNG, JPEG and GIF formats. - - The object that is returned should not be deleted by the caller. - - @see canUnderstand, decodeImage, loadFrom - */ - static ImageFileFormat* findImageFormatForStream (InputStream& input); - - /** Tries to load an image from a stream. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or 0 if it fails to load one. It's the - caller's responsibility to delete this image when no longer needed. - */ - static Image* loadFrom (InputStream& input); - - /** Tries to load an image from a file. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or 0 if it fails to load one. It's the - caller's responsibility to delete this image when no longer needed. - */ - static Image* loadFrom (const File& file); - - /** Tries to load an image from a block of raw image data. - - This will use the findImageFormatForStream() method to locate a suitable - codec, and use that to load the image. - - @returns the image that was decoded, or 0 if it fails to load one. It's the - caller's responsibility to delete this image when no longer needed. - */ - static Image* loadFrom (const void* rawData, - const int numBytesOfData); - -}; - -/** - A type of ImageFileFormat for reading and writing PNG files. - - @see ImageFileFormat, JPEGImageFormat -*/ -class JUCE_API PNGImageFormat : public ImageFileFormat -{ -public: - - PNGImageFormat() throw(); - ~PNGImageFormat() throw(); - - const String getFormatName(); - bool canUnderstand (InputStream& input); - - Image* decodeImage (InputStream& input); - - bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); -}; - -/** - A type of ImageFileFormat for reading and writing JPEG files. - - @see ImageFileFormat, PNGImageFormat -*/ -class JUCE_API JPEGImageFormat : public ImageFileFormat -{ -public: - - JPEGImageFormat() throw(); - ~JPEGImageFormat() throw(); - - /** Specifies the quality to be used when writing a JPEG file. - - @param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or - any negative value is "default" quality - */ - void setQuality (const float newQuality); - - const String getFormatName(); - - bool canUnderstand (InputStream& input); - - Image* decodeImage (InputStream& input); - - bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); - -private: - float quality; -}; - -#endif // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ -/********* End of inlined file: juce_ImageFileFormat.h *********/ - -#endif -#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ - -/********* Start of inlined file: juce_ImageConvolutionKernel.h *********/ -#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ -#define __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ - -/** - Represents a filter kernel to use in convoluting an image. - - @see Image::applyConvolution -*/ -class JUCE_API ImageConvolutionKernel -{ -public: - - /** Creates an empty convulution kernel. - - @param size the length of each dimension of the kernel, so e.g. if the size - is 5, it will create a 5x5 kernel - */ - ImageConvolutionKernel (const int size) throw(); - - /** Destructor. */ - ~ImageConvolutionKernel() throw(); - - /** Resets all values in the kernel to zero. - */ - void clear() throw(); - - /** Sets the value of a specific cell in the kernel. - - The x and y parameters must be in the range 0 < x < getKernelSize(). - - @see setOverallSum - */ - void setKernelValue (const int x, - const int y, - const float value) throw(); - - /** Rescales all values in the kernel to make the total add up to a fixed value. - - This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum). - */ - void setOverallSum (const float desiredTotalSum) throw(); - - /** Multiplies all values in the kernel by a value. */ - void rescaleAllValues (const float multiplier) throw(); - - /** Intialises the kernel for a gaussian blur. - - @param blurRadius this may be larger or smaller than the kernel's actual - size but this will obviously be wasteful or clip at the - edges. Ideally the kernel should be just larger than - (blurRadius * 2). - */ - void createGaussianBlur (const float blurRadius) throw(); - - /** Returns the size of the kernel. - - E.g. if it's a 3x3 kernel, this returns 3. - */ - int getKernelSize() const throw() { return size; } - - /** Returns a 2-dimensional array of the kernel's values. - - The size of each dimension of the array will be getKernelSize(). - */ - float** getValues() const throw() { return values; } - - /** Applies the kernel to an image. - - @param destImage the image that will receive the resultant convoluted pixels. - @param sourceImage an optional source image to read from - if this is 0, then the - destination image will be used as the source. If an image is - specified, it must be exactly the same size and type as the destination - image. - @param x the region of the image to apply the filter to - @param y the region of the image to apply the filter to - @param width the region of the image to apply the filter to - @param height the region of the image to apply the filter to - */ - void applyToImage (Image& destImage, - const Image* sourceImage, - int x, - int y, - int width, - int height) const; - - juce_UseDebuggingNewOperator - -private: - float** values; - int size; - - // no reason not to implement these one day.. - ImageConvolutionKernel (const ImageConvolutionKernel&); - const ImageConvolutionKernel& operator= (const ImageConvolutionKernel&); -}; - -#endif // __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ -/********* End of inlined file: juce_ImageConvolutionKernel.h *********/ - -#endif -#ifndef __JUCE_DRAWABLE_JUCEHEADER__ +/********* Start of inlined file: juce_DrawableButton.h *********/ +#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ +#define __JUCE_DRAWABLEBUTTON_JUCEHEADER__ /********* Start of inlined file: juce_Drawable.h *********/ #ifndef __JUCE_DRAWABLE_JUCEHEADER__ @@ -41629,543 +40101,6 @@ private: #endif // __JUCE_DRAWABLE_JUCEHEADER__ /********* End of inlined file: juce_Drawable.h *********/ -#endif -#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ - -/********* Start of inlined file: juce_DrawableComposite.h *********/ -#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ -#define __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ - -/** - A drawable object which acts as a container for a set of other Drawables. - - @see Drawable -*/ -class JUCE_API DrawableComposite : public Drawable -{ -public: - - /** Creates a composite Drawable. - */ - DrawableComposite(); - - /** Destructor. */ - virtual ~DrawableComposite(); - - /** Adds a new sub-drawable to this one. - - This passes in a Drawable pointer for this object to look after. To add a copy - of a drawable, use the form of this method that takes a Drawable reference instead. - - @param drawable the object to add - this will be deleted automatically - when no longer needed, so the caller mustn't keep any - pointers to it. - @param transform the transform to apply to this drawable when it's being - drawn - @param index where to insert it in the list of drawables. 0 is the back, - -1 is the front, or any value from 0 and getNumDrawables() - can be used - @see removeDrawable - */ - void insertDrawable (Drawable* drawable, - const AffineTransform& transform = AffineTransform::identity, - const int index = -1); - - /** Adds a new sub-drawable to this one. - - This takes a copy of a Drawable and adds it to this object. To pass in a Drawable - for this object to look after, use the form of this method that takes a Drawable - pointer instead. - - @param drawable the object to add - an internal copy will be made of this object - @param transform the transform to apply to this drawable when it's being - drawn - @param index where to insert it in the list of drawables. 0 is the back, - -1 is the front, or any value from 0 and getNumDrawables() - can be used - @see removeDrawable - */ - void insertDrawable (const Drawable& drawable, - const AffineTransform& transform = AffineTransform::identity, - const int index = -1); - - /** Deletes one of the Drawable objects. - - @param index the index of the drawable to delete, between 0 - and (getNumDrawables() - 1). - @param deleteDrawable if this is true, the drawable that is removed will also - be deleted. If false, it'll just be removed. - @see insertDrawable, getNumDrawables - */ - void removeDrawable (const int index, const bool deleteDrawable = true); - - /** Returns the number of drawables contained inside this one. - - @see getDrawable - */ - int getNumDrawables() const throw() { return drawables.size(); } - - /** Returns one of the drawables that are contained in this one. - - Each drawable also has a transform associated with it - you can use getDrawableTransform() - to find it. - - The pointer returned is managed by this object and will be deleted when no longer - needed, so be careful what you do with it. - - @see getNumDrawables - */ - Drawable* getDrawable (const int index) const throw() { return drawables [index]; } - - /** Returns the transform that applies to one of the drawables that are contained in this one. - - The pointer returned is managed by this object and will be deleted when no longer - needed, so be careful what you do with it. - - @see getNumDrawables - */ - const AffineTransform* getDrawableTransform (const int index) const throw() { return transforms [index]; } - - /** Brings one of the Drawables to the front. - - @param index the index of the drawable to move, between 0 - and (getNumDrawables() - 1). - @see insertDrawable, getNumDrawables - */ - void bringToFront (const int index); - - /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - void getBounds (float& x, float& y, float& width, float& height) const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - ValueTree createValueTree() const throw(); - /** @internal */ - static DrawableComposite* createFromValueTree (const ValueTree& tree) throw(); - - juce_UseDebuggingNewOperator - -private: - OwnedArray drawables; - OwnedArray transforms; - - DrawableComposite (const DrawableComposite&); - const DrawableComposite& operator= (const DrawableComposite&); -}; - -#endif // __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ -/********* End of inlined file: juce_DrawableComposite.h *********/ - -#endif -#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ - -/********* Start of inlined file: juce_DrawableImage.h *********/ -#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ -#define __JUCE_DRAWABLEIMAGE_JUCEHEADER__ - -/** - A drawable object which is a bitmap image. - - @see Drawable -*/ -class JUCE_API DrawableImage : public Drawable -{ -public: - - DrawableImage(); - - /** Destructor. */ - virtual ~DrawableImage(); - - /** Sets the image that this drawable will render. - - An internal copy is made of the image passed-in. If you want to provide an - image that this object can take charge of without needing to create a copy, - use the other setImage() method. - */ - void setImage (const Image& imageToCopy); - - /** Sets the image that this drawable will render. - - An internal copy of this will not be made, so the caller mustn't delete - the image while it's still being used by this object. - - A good way to use this is with the ImageCache - if you create an image - with ImageCache and pass it in here with releaseWhenNotNeeded = true, then - it'll be released neatly with its reference count being decreased. - - @param imageToUse the image to render - @param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, - then the image will be deleted when this object no longer - needs it - unless the image was created by the ImageCache, - in which case it will be released with ImageCache::release(). - */ - void setImage (Image* imageToUse, - const bool releaseWhenNotNeeded); - - /** Returns the current image. */ - Image* getImage() const throw() { return image; } - - /** Clears (and possibly deletes) the currently set image. */ - void clearImage(); - - /** Sets the opacity to use when drawing the image. */ - void setOpacity (const float newOpacity); - - /** Returns the image's opacity. */ - float getOpacity() const throw() { return opacity; } - - /** Sets a colour to draw over the image's alpha channel. - - By default this is transparent so isn't drawn, but if you set a non-transparent - colour here, then it will be overlaid on the image, using the image's alpha - channel as a mask. - - This is handy for doing things like darkening or lightening an image by overlaying - it with semi-transparent black or white. - */ - void setOverlayColour (const Colour& newOverlayColour); - - /** Returns the overlay colour. */ - const Colour& getOverlayColour() const throw() { return overlayColour; } - - /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - void getBounds (float& x, float& y, float& width, float& height) const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - ValueTree createValueTree() const throw(); - /** @internal */ - static DrawableImage* createFromValueTree (const ValueTree& tree) throw(); - - juce_UseDebuggingNewOperator - -private: - Image* image; - bool canDeleteImage; - float opacity; - Colour overlayColour; - - DrawableImage (const DrawableImage&); - const DrawableImage& operator= (const DrawableImage&); -}; - -#endif // __JUCE_DRAWABLEIMAGE_JUCEHEADER__ -/********* End of inlined file: juce_DrawableImage.h *********/ - -#endif -#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ - -/********* Start of inlined file: juce_DrawableText.h *********/ -#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ -#define __JUCE_DRAWABLETEXT_JUCEHEADER__ - -/** - A drawable object which renders a line of text. - - @see Drawable -*/ -class JUCE_API DrawableText : public Drawable -{ -public: - - /** Creates a DrawableText object. */ - DrawableText(); - - /** Destructor. */ - virtual ~DrawableText(); - - /** Sets the block of text to render */ - void setText (const GlyphArrangement& newText); - - /** Sets a single line of text to render. - - This is a convenient method of adding a single line - for - more complex text, use the setText() that takes a - GlyphArrangement instead. - */ - void setText (const String& newText, const Font& fontToUse); - - /** Returns the text arrangement that was set with setText(). */ - const GlyphArrangement& getText() const throw() { return text; } - - /** Sets the colour of the text. */ - void setColour (const Colour& newColour); - - /** Returns the current text colour. */ - const Colour& getColour() const throw() { return colour; } - - /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - void getBounds (float& x, float& y, float& width, float& height) const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - ValueTree createValueTree() const throw(); - /** @internal */ - static DrawableText* createFromValueTree (const ValueTree& tree) throw(); - - juce_UseDebuggingNewOperator - -private: - GlyphArrangement text; - Colour colour; - - DrawableText (const DrawableText&); - const DrawableText& operator= (const DrawableText&); -}; - -#endif // __JUCE_DRAWABLETEXT_JUCEHEADER__ -/********* End of inlined file: juce_DrawableText.h *********/ - -#endif -#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ - -/********* Start of inlined file: juce_DrawablePath.h *********/ -#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ -#define __JUCE_DRAWABLEPATH_JUCEHEADER__ - -/** - A drawable object which renders a filled or outlined shape. - - @see Drawable -*/ -class JUCE_API DrawablePath : public Drawable -{ -public: - - /** Creates a DrawablePath. - */ - DrawablePath(); - - /** Destructor. */ - virtual ~DrawablePath(); - - /** Changes the path that will be drawn. - - @see setFillColour, setStrokeType - */ - void setPath (const Path& newPath) throw(); - - /** Returns the current path. */ - const Path& getPath() const throw() { return path; } - - /** Sets a fill type for the path. - - This colour is used to fill the path - if you don't want the path to be - filled (e.g. if you're just drawing an outline), set this to a transparent - colour. - - @see setPath, setStrokeFill - */ - void setFill (const FillType& newFill) throw(); - - /** Returns the current fill type. - @see setFill - */ - const FillType& getFill() const throw() { return mainFill; } - - /** Sets the fill type with which the outline will be drawn. - @see setFill - */ - void setStrokeFill (const FillType& newStrokeFill) throw(); - - /** Returns the current stroke fill. - @see setStrokeFill - */ - const FillType& getStrokeFill() const throw() { return strokeFill; } - - /** Changes the properties of the outline that will be drawn around the path. - If the stroke has 0 thickness, no stroke will be drawn. - @see setStrokeThickness, setStrokeColour - */ - void setStrokeType (const PathStrokeType& newStrokeType) throw(); - - /** Changes the stroke thickness. - This is a shortcut for calling setStrokeType. - */ - void setStrokeThickness (const float newThickness) throw(); - - /** Returns the current outline style. */ - const PathStrokeType& getStrokeType() const throw() { return strokeType; } - - /** @internal */ - void render (const Drawable::RenderingContext& context) const; - /** @internal */ - void getBounds (float& x, float& y, float& width, float& height) const; - /** @internal */ - bool hitTest (float x, float y) const; - /** @internal */ - Drawable* createCopy() const; - /** @internal */ - ValueTree createValueTree() const throw(); - /** @internal */ - static DrawablePath* createFromValueTree (const ValueTree& tree) throw(); - - juce_UseDebuggingNewOperator - -private: - Path path, stroke; - FillType mainFill, strokeFill; - PathStrokeType strokeType; - - void updateOutline(); - - DrawablePath (const DrawablePath&); - const DrawablePath& operator= (const DrawablePath&); -}; - -#endif // __JUCE_DRAWABLEPATH_JUCEHEADER__ -/********* End of inlined file: juce_DrawablePath.h *********/ - -#endif -#ifndef __JUCE_COMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ - -#endif -#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_DESKTOP_JUCEHEADER__ - -#endif -#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ - -/********* Start of inlined file: juce_ArrowButton.h *********/ -#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ -#define __JUCE_ARROWBUTTON_JUCEHEADER__ - -/********* Start of inlined file: juce_DropShadowEffect.h *********/ -#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ -#define __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ - -/** - An effect filter that adds a drop-shadow behind the image's content. - - (This will only work on images/components that aren't opaque, of course). - - When added to a component, this effect will draw a soft-edged - shadow based on what gets drawn inside it. The shadow will also - be applied to the component's children. - - For speed, this doesn't use a proper gaussian blur, but cheats by - using a simple bilinear filter. If you need a really high-quality - shadow, check out ImageConvolutionKernel::createGaussianBlur() - - @see Component::setComponentEffect -*/ -class JUCE_API DropShadowEffect : public ImageEffectFilter -{ -public: - - /** Creates a default drop-shadow effect. - - To customise the shadow's appearance, use the setShadowProperties() - method. - */ - DropShadowEffect(); - - /** Destructor. */ - ~DropShadowEffect(); - - /** Sets up parameters affecting the shadow's appearance. - - @param newRadius the (approximate) radius of the blur used - @param newOpacity the opacity with which the shadow is rendered - @param newShadowOffsetX allows the shadow to be shifted in relation to the - component's contents - @param newShadowOffsetY allows the shadow to be shifted in relation to the - component's contents - */ - void setShadowProperties (const float newRadius, - const float newOpacity, - const int newShadowOffsetX, - const int newShadowOffsetY); - - /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext); - - juce_UseDebuggingNewOperator - -private: - int offsetX, offsetY; - float radius, opacity; -}; - -#endif // __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ -/********* End of inlined file: juce_DropShadowEffect.h *********/ - -/** - A button with an arrow in it. - - @see Button -*/ -class JUCE_API ArrowButton : public Button -{ -public: - - /** Creates an ArrowButton. - - @param buttonName the name to give the button - @param arrowDirection the direction the arrow should point in, where 0.0 is - pointing right, 0.25 is down, 0.5 is left, 0.75 is up - @param arrowColour the colour to use for the arrow - */ - ArrowButton (const String& buttonName, - float arrowDirection, - const Colour& arrowColour); - - /** Destructor. */ - ~ArrowButton(); - - juce_UseDebuggingNewOperator - -protected: - /** @internal */ - void paintButton (Graphics& g, - bool isMouseOverButton, - bool isButtonDown); - - /** @internal */ - void buttonStateChanged(); - -private: - - Colour colour; - DropShadowEffect shadow; - Path path; - int offset; - - ArrowButton (const ArrowButton&); - const ArrowButton& operator= (const ArrowButton&); -}; - -#endif // __JUCE_ARROWBUTTON_JUCEHEADER__ -/********* End of inlined file: juce_ArrowButton.h *********/ - -#endif -#ifndef __JUCE_BUTTON_JUCEHEADER__ - -#endif -#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ - -/********* Start of inlined file: juce_DrawableButton.h *********/ -#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__ -#define __JUCE_DRAWABLEBUTTON_JUCEHEADER__ - /** A button that displays a Drawable. @@ -43607,1296 +41542,7 @@ private: /********* End of inlined file: juce_ToolbarButton.h *********/ #endif -#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ - -#endif -#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ - -/********* Start of inlined file: juce_GlowEffect.h *********/ -#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ -#define __JUCE_GLOWEFFECT_JUCEHEADER__ - -/** - A component effect that adds a coloured blur around the component's contents. - - (This will only work on non-opaque components). - - @see Component::setComponentEffect, DropShadowEffect -*/ -class JUCE_API GlowEffect : public ImageEffectFilter -{ -public: - - /** Creates a default 'glow' effect. - - To customise its appearance, use the setGlowProperties() method. - */ - GlowEffect(); - - /** Destructor. */ - ~GlowEffect(); - - /** Sets the glow's radius and colour. - - The radius is how large the blur should be, and the colour is - used to render it (for a less intense glow, lower the colour's - opacity). - */ - void setGlowProperties (const float newRadius, - const Colour& newColour); - - /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext); - - juce_UseDebuggingNewOperator - -private: - float radius; - Colour colour; -}; - -#endif // __JUCE_GLOWEFFECT_JUCEHEADER__ -/********* End of inlined file: juce_GlowEffect.h *********/ - -#endif -#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ - -#endif -#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ - -/********* Start of inlined file: juce_ReduceOpacityEffect.h *********/ -#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ -#define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ - -/** - An effect filter that reduces the image's opacity. - - This can be used to make a component (and its child components) more - transparent. - - @see Component::setComponentEffect -*/ -class JUCE_API ReduceOpacityEffect : public ImageEffectFilter -{ -public: - - /** Creates the effect object. - - The opacity of the component to which the effect is applied will be - scaled by the given factor (in the range 0 to 1.0f). - */ - ReduceOpacityEffect (const float opacity = 1.0f); - - /** Destructor. */ - ~ReduceOpacityEffect(); - - /** Sets how much to scale the component's opacity. - - @param newOpacity should be between 0 and 1.0f - */ - void setOpacity (const float newOpacity); - - /** @internal */ - void applyEffect (Image& sourceImage, Graphics& destContext); - - juce_UseDebuggingNewOperator - -private: - float opacity; -}; - -#endif // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ -/********* End of inlined file: juce_ReduceOpacityEffect.h *********/ - -#endif -#ifndef __JUCE_KEYLISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_KEYPRESS_JUCEHEADER__ - -#endif -#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ - -/********* Start of inlined file: juce_KeyPressMappingSet.h *********/ -#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ -#define __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ - -/** - Manages and edits a list of keypresses, which it uses to invoke the appropriate - command in a ApplicationCommandManager. - - Normally, you won't actually create a KeyPressMappingSet directly, because - each ApplicationCommandManager contains its own KeyPressMappingSet, so typically - you'd create yourself an ApplicationCommandManager, and call its - ApplicationCommandManager::getKeyMappings() method to get a pointer to its - KeyPressMappingSet. - - For one of these to actually use keypresses, you'll need to add it as a KeyListener - to the top-level component for which you want to handle keystrokes. So for example: - - @code - class MyMainWindow : public Component - { - ApplicationCommandManager* myCommandManager; - - public: - MyMainWindow() - { - myCommandManager = new ApplicationCommandManager(); - - // first, make sure the command manager has registered all the commands that its - // targets can perform.. - myCommandManager->registerAllCommandsForTarget (myCommandTarget1); - myCommandManager->registerAllCommandsForTarget (myCommandTarget2); - - // this will use the command manager to initialise the KeyPressMappingSet with - // the default keypresses that were specified when the targets added their commands - // to the manager. - myCommandManager->getKeyMappings()->resetToDefaultMappings(); - - // having set up the default key-mappings, you might now want to load the last set - // of mappings that the user configured. - myCommandManager->getKeyMappings()->restoreFromXml (lastSavedKeyMappingsXML); - - // Now tell our top-level window to send any keypresses that arrive to the - // KeyPressMappingSet, which will use them to invoke the appropriate commands. - addKeyListener (myCommandManager->getKeyMappings()); - } - - ... - } - @endcode - - KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can - register to be told when a command or mapping is added, removed, etc. - - There's also a UI component called KeyMappingEditorComponent that can be used - to easily edit the key mappings. - - @see Component::addKeyListener(), KeyMappingEditorComponent, ApplicationCommandManager -*/ -class JUCE_API KeyPressMappingSet : public KeyListener, - public ChangeBroadcaster, - public FocusChangeListener -{ -public: - - /** Creates a KeyPressMappingSet for a given command manager. - - Normally, you won't actually create a KeyPressMappingSet directly, because - each ApplicationCommandManager contains its own KeyPressMappingSet, so the - best thing to do is to create your ApplicationCommandManager, and use the - ApplicationCommandManager::getKeyMappings() method to access its mappings. - - When a suitable keypress happens, the manager's invoke() method will be - used to invoke the appropriate command. - - @see ApplicationCommandManager - */ - KeyPressMappingSet (ApplicationCommandManager* const commandManager) throw(); - - /** Creates an copy of a KeyPressMappingSet. */ - KeyPressMappingSet (const KeyPressMappingSet& other) throw(); - - /** Destructor. */ - ~KeyPressMappingSet(); - - ApplicationCommandManager* getCommandManager() const throw() { return commandManager; } - - /** Returns a list of keypresses that are assigned to a particular command. - - @param commandID the command's ID - */ - const Array getKeyPressesAssignedToCommand (const CommandID commandID) const throw(); - - /** Assigns a keypress to a command. - - If the keypress is already assigned to a different command, it will first be - removed from that command, to avoid it triggering multiple functions. - - @param commandID the ID of the command that you want to add a keypress to. If - this is 0, the keypress will be removed from anything that it - was previously assigned to, but not re-assigned - @param newKeyPress the new key-press - @param insertIndex if this is less than zero, the key will be appended to the - end of the list of keypresses; otherwise the new keypress will - be inserted into the existing list at this index - */ - void addKeyPress (const CommandID commandID, - const KeyPress& newKeyPress, - int insertIndex = -1) throw(); - - /** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager. - - @see resetToDefaultMapping - */ - void resetToDefaultMappings() throw(); - - /** Resets all key-mappings to the defaults for a particular command. - - @see resetToDefaultMappings - */ - void resetToDefaultMapping (const CommandID commandID) throw(); - - /** Removes all keypresses that are assigned to any commands. */ - void clearAllKeyPresses() throw(); - - /** Removes all keypresses that are assigned to a particular command. */ - void clearAllKeyPresses (const CommandID commandID) throw(); - - /** Removes one of the keypresses that are assigned to a command. - - See the getKeyPressesAssignedToCommand() for the list of keypresses to - which the keyPressIndex refers. - */ - void removeKeyPress (const CommandID commandID, - const int keyPressIndex) throw(); - - /** Removes a keypress from any command that it may be assigned to. - */ - void removeKeyPress (const KeyPress& keypress) throw(); - - /** Returns true if the given command is linked to this key. */ - bool containsMapping (const CommandID commandID, - const KeyPress& keyPress) const throw(); - - /** Looks for a command that corresponds to a keypress. - - @returns the UID of the command or 0 if none was found - */ - CommandID findCommandForKeyPress (const KeyPress& keyPress) const throw(); - - /** Tries to recreate the mappings from a previously stored state. - - The XML passed in must have been created by the createXml() method. - - If the stored state makes any reference to commands that aren't - currently available, these will be ignored. - - If the set of mappings being loaded was a set of differences (using createXml (true)), - then this will call resetToDefaultMappings() and then merge the saved mappings - on top. If the saved set was created with createXml (false), then this method - will first clear all existing mappings and load the saved ones as a complete set. - - @returns true if it manages to load the XML correctly - @see createXml - */ - bool restoreFromXml (const XmlElement& xmlVersion); - - /** Creates an XML representation of the current mappings. - - This will produce a lump of XML that can be later reloaded using - restoreFromXml() to recreate the current mapping state. - - The object that is returned must be deleted by the caller. - - @param saveDifferencesFromDefaultSet if this is false, then all keypresses - will be saved into the XML. If it's true, then the XML will - only store the differences between the current mappings and - the default mappings you'd get from calling resetToDefaultMappings(). - The advantage of saving a set of differences from the default is that - if you change the default mappings (in a new version of your app, for - example), then these will be merged into a user's saved preferences. - - @see restoreFromXml - */ - XmlElement* createXml (const bool saveDifferencesFromDefaultSet) const; - - /** @internal */ - bool keyPressed (const KeyPress& key, Component* originatingComponent); - /** @internal */ - bool keyStateChanged (const bool isKeyDown, Component* originatingComponent); - /** @internal */ - void globalFocusChanged (Component* focusedComponent); - - juce_UseDebuggingNewOperator - -private: - - ApplicationCommandManager* commandManager; - - struct CommandMapping - { - CommandID commandID; - Array keypresses; - bool wantsKeyUpDownCallbacks; - }; - - OwnedArray mappings; - - struct KeyPressTime - { - KeyPress key; - uint32 timeWhenPressed; - }; - - OwnedArray keysDown; - - void handleMessage (const Message& message); - - void invokeCommand (const CommandID commandID, - const KeyPress& keyPress, - const bool isKeyDown, - const int millisecsSinceKeyPressed, - Component* const originatingComponent) const; - - const KeyPressMappingSet& operator= (const KeyPressMappingSet&); -}; - -#endif // __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ -/********* End of inlined file: juce_KeyPressMappingSet.h *********/ - -#endif -#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ - -#endif -#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ - -#endif -#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_KeyMappingEditorComponent.h *********/ -#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ -#define __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_TreeView.h *********/ -#ifndef __JUCE_TREEVIEW_JUCEHEADER__ -#define __JUCE_TREEVIEW_JUCEHEADER__ - -/********* Start of inlined file: juce_FileDragAndDropTarget.h *********/ -#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ -#define __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ - -/** - Components derived from this class can have files dropped onto them by an external application. - - @see DragAndDropContainer -*/ -class JUCE_API FileDragAndDropTarget -{ -public: - /** Destructor. */ - virtual ~FileDragAndDropTarget() {} - - /** Callback to check whether this target is interested in the set of files being offered. - - Note that this will be called repeatedly when the user is dragging the mouse around over your - component, so don't do anything time-consuming in here, like opening the files to have a look - inside them! - - @param files the set of (absolute) pathnames of the files that the user is dragging - @returns true if this component wants to receive the other callbacks regarging this - type of object; if it returns false, no other callbacks will be made. - */ - virtual bool isInterestedInFileDrag (const StringArray& files) = 0; - - /** Callback to indicate that some files are being dragged over this component. - - This gets called when the user moves the mouse into this component while dragging. - - Use this callback as a trigger to make your component repaint itself to give the - user feedback about whether the files can be dropped here or not. - - @param files the set of (absolute) pathnames of the files that the user is dragging - @param x the mouse x position, relative to this component - @param y the mouse y position, relative to this component - */ - virtual void fileDragEnter (const StringArray& files, int x, int y); - - /** Callback to indicate that the user is dragging some files over this component. - - This gets called when the user moves the mouse over this component while dragging. - Normally overriding itemDragEnter() and itemDragExit() are enough, but - this lets you know what happens in-between. - - @param files the set of (absolute) pathnames of the files that the user is dragging - @param x the mouse x position, relative to this component - @param y the mouse y position, relative to this component - */ - virtual void fileDragMove (const StringArray& files, int x, int y); - - /** Callback to indicate that the mouse has moved away from this component. - - This gets called when the user moves the mouse out of this component while dragging - the files. - - If you've used fileDragEnter() to repaint your component and give feedback, use this - as a signal to repaint it in its normal state. - - @param files the set of (absolute) pathnames of the files that the user is dragging - */ - virtual void fileDragExit (const StringArray& files); - - /** Callback to indicate that the user has dropped the files onto this component. - - When the user drops the files, this get called, and you can use the files in whatever - way is appropriate. - - Note that after this is called, the fileDragExit method may not be called, so you should - clean up in here if there's anything you need to do when the drag finishes. - - @param files the set of (absolute) pathnames of the files that the user is dragging - @param x the mouse x position, relative to this component - @param y the mouse y position, relative to this component - */ - virtual void filesDropped (const StringArray& files, int x, int y) = 0; -}; - -#endif // __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ -/********* End of inlined file: juce_FileDragAndDropTarget.h *********/ - -class TreeView; - -/** - An item in a treeview. - - A TreeViewItem can either be a leaf-node in the tree, or it can contain its - own sub-items. - - To implement an item that contains sub-items, override the itemOpennessChanged() - method so that when it is opened, it adds the new sub-items to itself using the - addSubItem method. Depending on the nature of the item it might choose to only - do this the first time it's opened, or it might want to refresh itself each time. - It also has the option of deleting its sub-items when it is closed, or leaving them - in place. -*/ -class JUCE_API TreeViewItem -{ -public: - - /** Constructor. */ - TreeViewItem(); - - /** Destructor. */ - virtual ~TreeViewItem(); - - /** Returns the number of sub-items that have been added to this item. - - Note that this doesn't mean much if the node isn't open. - - @see getSubItem, mightContainSubItems, addSubItem - */ - int getNumSubItems() const throw(); - - /** Returns one of the item's sub-items. - - Remember that the object returned might get deleted at any time when its parent - item is closed or refreshed, depending on the nature of the items you're using. - - @see getNumSubItems - */ - TreeViewItem* getSubItem (const int index) const throw(); - - /** Removes any sub-items. */ - void clearSubItems(); - - /** Adds a sub-item. - - @param newItem the object to add to the item's sub-item list. Once added, these can be - found using getSubItem(). When the items are later removed with - removeSubItem() (or when this item is deleted), they will be deleted. - @param insertPosition the index which the new item should have when it's added. If this - value is less than 0, the item will be added to the end of the list. - */ - void addSubItem (TreeViewItem* const newItem, - const int insertPosition = -1); - - /** Removes one of the sub-items. - - @param index the item to remove - @param deleteItem if true, the item that is removed will also be deleted. - */ - void removeSubItem (const int index, - const bool deleteItem = true); - - /** Returns the TreeView to which this item belongs. */ - TreeView* getOwnerView() const throw() { return ownerView; } - - /** Returns the item within which this item is contained. */ - TreeViewItem* getParentItem() const throw() { return parentItem; } - - /** True if this item is currently open in the treeview. */ - bool isOpen() const throw(); - - /** Opens or closes the item. - - When opened or closed, the item's itemOpennessChanged() method will be called, - and a subclass should use this callback to create and add any sub-items that - it needs to. - - @see itemOpennessChanged, mightContainSubItems - */ - void setOpen (const bool shouldBeOpen); - - /** True if this item is currently selected. - - Use this when painting the node, to decide whether to draw it as selected or not. - */ - bool isSelected() const throw(); - - /** Selects or deselects the item. - - This will cause a callback to itemSelectionChanged() - */ - void setSelected (const bool shouldBeSelected, - const bool deselectOtherItemsFirst); - - /** Returns the rectangle that this item occupies. - - If relativeToTreeViewTopLeft is true, the co-ordinates are relative to the - top-left of the TreeView comp, so this will depend on the scroll-position of - the tree. If false, it is relative to the top-left of the topmost item in the - tree (so this would be unaffected by scrolling the view). - */ - const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const throw(); - - /** Sends a signal to the treeview to make it refresh itself. - - Call this if your items have changed and you want the tree to update to reflect - this. - */ - void treeHasChanged() const throw(); - - /** Sends a repaint message to redraw just this item. - - Note that you should only call this if you want to repaint a superficial change. If - you're altering the tree's nodes, you should instead call treeHasChanged(). - */ - void repaintItem() const; - - /** Returns the row number of this item in the tree. - - The row number of an item will change according to which items are open. - - @see TreeView::getNumRowsInTree(), TreeView::getItemOnRow() - */ - int getRowNumberInTree() const throw(); - - /** Returns true if all the item's parent nodes are open. - - This is useful to check whether the item might actually be visible or not. - */ - bool areAllParentsOpen() const throw(); - - /** Changes whether lines are drawn to connect any sub-items to this item. - - By default, line-drawing is turned on. - */ - void setLinesDrawnForSubItems (const bool shouldDrawLines) throw(); - - /** Tells the tree whether this item can potentially be opened. - - If your item could contain sub-items, this should return true; if it returns - false then the tree will not try to open the item. This determines whether or - not the item will be drawn with a 'plus' button next to it. - */ - virtual bool mightContainSubItems() = 0; - - /** Returns a string to uniquely identify this item. - - If you're planning on using the TreeView::getOpennessState() method, then - these strings will be used to identify which nodes are open. The string - should be unique amongst the item's sibling items, but it's ok for there - to be duplicates at other levels of the tree. - - If you're not going to store the state, then it's ok not to bother implementing - this method. - */ - virtual const String getUniqueName() const; - - /** Called when an item is opened or closed. - - When setOpen() is called and the item has specified that it might - have sub-items with the mightContainSubItems() method, this method - is called to let the item create or manage its sub-items. - - So when this is called with isNowOpen set to true (i.e. when the item is being - opened), a subclass might choose to use clearSubItems() and addSubItem() to - refresh its sub-item list. - - When this is called with isNowOpen set to false, the subclass might want - to use clearSubItems() to save on space, or it might choose to leave them, - depending on the nature of the tree. - - You could also use this callback as a trigger to start a background process - which asynchronously creates sub-items and adds them, if that's more - appropriate for the task in hand. - - @see mightContainSubItems - */ - virtual void itemOpennessChanged (bool isNowOpen); - - /** Must return the width required by this item. - - If your item needs to have a particular width in pixels, return that value; if - you'd rather have it just fill whatever space is available in the treeview, - return -1. - - If all your items return -1, no horizontal scrollbar will be shown, but if any - items have fixed widths and extend beyond the width of the treeview, a - scrollbar will appear. - - Each item can be a different width, but if they change width, you should call - treeHasChanged() to update the tree. - */ - virtual int getItemWidth() const { return -1; } - - /** Must return the height required by this item. - - This is the height in pixels that the item will take up. Items in the tree - can be different heights, but if they change height, you should call - treeHasChanged() to update the tree. - */ - virtual int getItemHeight() const { return 20; } - - /** You can override this method to return false if you don't want to allow the - user to select this item. - */ - virtual bool canBeSelected() const { return true; } - - /** Creates a component that will be used to represent this item. - - You don't have to implement this method - if it returns 0 then no component - will be used for the item, and you can just draw it using the paintItem() - callback. But if you do return a component, it will be positioned in the - treeview so that it can be used to represent this item. - - The component returned will be managed by the treeview, so always return - a new component, and don't keep a reference to it, as the treeview will - delete it later when it goes off the screen or is no longer needed. Also - bear in mind that if the component keeps a reference to the item that - created it, that item could be deleted before the component. Its position - and size will be completely managed by the tree, so don't attempt to move it - around. - - Something you may want to do with your component is to give it a pointer to - the TreeView that created it. This is perfectly safe, and there's no danger - of it becoming a dangling pointer because the TreeView will always delete - the component before it is itself deleted. - - As long as you stick to these rules you can return whatever kind of - component you like. It's most useful if you're doing things like drag-and-drop - of items, or want to use a Label component to edit item names, etc. - */ - virtual Component* createItemComponent() { return 0; } - - /** Draws the item's contents. - - You can choose to either implement this method and draw each item, or you - can use createItemComponent() to create a component that will represent the - item. - - If all you need in your tree is to be able to draw the items and detect when - the user selects or double-clicks one of them, it's probably enough to - use paintItem(), itemClicked() and itemDoubleClicked(). If you need more - complicated interactions, you may need to use createItemComponent() instead. - - @param g the graphics context to draw into - @param width the width of the area available for drawing - @param height the height of the area available for drawing - */ - virtual void paintItem (Graphics& g, int width, int height); - - /** Draws the item's open/close button. - - If you don't implement this method, the default behaviour is to - call LookAndFeel::drawTreeviewPlusMinusBox(), but you can override - it for custom effects. - */ - virtual void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver); - - /** Called when the user clicks on this item. - - If you're using createItemComponent() to create a custom component for the - item, the mouse-clicks might not make it through to the treeview, but this - is how you find out about clicks when just drawing each item individually. - - The associated mouse-event details are passed in, so you can find out about - which button, where it was, etc. - - @see itemDoubleClicked - */ - virtual void itemClicked (const MouseEvent& e); - - /** Called when the user double-clicks on this item. - - If you're using createItemComponent() to create a custom component for the - item, the mouse-clicks might not make it through to the treeview, but this - is how you find out about clicks when just drawing each item individually. - - The associated mouse-event details are passed in, so you can find out about - which button, where it was, etc. - - If not overridden, the base class method here will open or close the item as - if the 'plus' button had been clicked. - - @see itemClicked - */ - virtual void itemDoubleClicked (const MouseEvent& e); - - /** Called when the item is selected or deselected. - - Use this if you want to do something special when the item's selectedness - changes. By default it'll get repainted when this happens. - */ - virtual void itemSelectionChanged (bool isNowSelected); - - /** The item can return a tool tip string here if it wants to. - @see TooltipClient - */ - virtual const String getTooltip(); - - /** To allow items from your treeview to be dragged-and-dropped, implement this method. - - If this returns a non-empty name then when the user drags an item, the treeview will - try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger - a drag-and-drop operation, using this string as the source description, with the treeview - itself as the source component. - - If you need more complex drag-and-drop behaviour, you can use custom components for - the items, and use those to trigger the drag. - - To accept drag-and-drop in your tree, see isInterestedInDragSource(), - isInterestedInFileDrag(), etc. - - @see DragAndDropContainer::startDragging - */ - virtual const String getDragSourceDescription(); - - /** If you want your item to be able to have files drag-and-dropped onto it, implement this - method and return true. - - If you return true and allow some files to be dropped, you'll also need to implement the - filesDropped() method to do something with them. - - Note that this will be called often, so make your implementation very quick! There's - certainly no time to try opening the files and having a think about what's inside them! - - For responding to internal drag-and-drop of other types of object, see isInterestedInDragSource(). - @see FileDragAndDropTarget::isInterestedInFileDrag, isInterestedInDragSource - */ - virtual bool isInterestedInFileDrag (const StringArray& files); - - /** When files are dropped into this item, this callback is invoked. - - For this to work, you'll need to have also implemented isInterestedInFileDrag(). - The insertIndex value indicates where in the list of sub-items the files were dropped. - @see FileDragAndDropTarget::filesDropped, isInterestedInFileDrag - */ - virtual void filesDropped (const StringArray& files, int insertIndex); - - /** If you want your item to act as a DragAndDropTarget, implement this method and return true. - - If you implement this method, you'll also need to implement itemDropped() in order to handle - the items when they are dropped. - To respond to drag-and-drop of files from external applications, see isInterestedInFileDrag(). - @see DragAndDropTarget::isInterestedInDragSource, itemDropped - */ - virtual bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent); - - /** When a things are dropped into this item, this callback is invoked. - - For this to work, you need to have also implemented isInterestedInDragSource(). - The insertIndex value indicates where in the list of sub-items the new items should be placed. - @see isInterestedInDragSource, DragAndDropTarget::itemDropped - */ - virtual void itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex); - - /** Sets a flag to indicate that the item wants to be allowed - to draw all the way across to the left edge of the treeview. - - By default this is false, which means that when the paintItem() - method is called, its graphics context is clipped to only allow - drawing within the item's rectangle. If this flag is set to true, - then the graphics context isn't clipped on its left side, so it - can draw all the way across to the left margin. Note that the - context will still have its origin in the same place though, so - the coordinates of anything to its left will be negative. It's - mostly useful if you want to draw a wider bar behind the - highlighted item. - */ - void setDrawsInLeftMargin (bool canDrawInLeftMargin) throw(); - - /** Saves the current state of open/closed nodes so it can be restored later. - - This takes a snapshot of which sub-nodes have been explicitly opened or closed, - and records it as XML. To identify node objects it uses the - TreeViewItem::getUniqueName() method to create named paths. This - means that the same state of open/closed nodes can be restored to a - completely different instance of the tree, as long as it contains nodes - whose unique names are the same. - - You'd normally want to use TreeView::getOpennessState() rather than call it - for a specific item, but this can be handy if you need to briefly save the state - for a section of the tree. - - The caller is responsible for deleting the object that is returned. - @see TreeView::getOpennessState, restoreOpennessState - */ - XmlElement* getOpennessState() const throw(); - - /** Restores the openness of this item and all its sub-items from a saved state. - - See TreeView::restoreOpennessState for more details. - - You'd normally want to use TreeView::restoreOpennessState() rather than call it - for a specific item, but this can be handy if you need to briefly save the state - for a section of the tree. - - @see TreeView::restoreOpennessState, getOpennessState - */ - void restoreOpennessState (const XmlElement& xml) throw(); - - /** Returns the index of this item in its parent's sub-items. */ - int getIndexInParent() const throw(); - - /** Returns true if this item is the last of its parent's sub-itens. */ - bool isLastOfSiblings() const throw(); - - /** Creates a string that can be used to uniquely retrieve this item in the tree. - - The string that is returned can be passed to TreeView::findItemFromIdentifierString(). - The string takes the form of a path, constructed from the getUniqueName() of this - item and all its parents, so these must all be correctly implemented for it to work. - @see TreeView::findItemFromIdentifierString, getUniqueName - */ - const String getItemIdentifierString() const; - - juce_UseDebuggingNewOperator - -private: - TreeView* ownerView; - TreeViewItem* parentItem; - OwnedArray subItems; - int y, itemHeight, totalHeight, itemWidth, totalWidth; - int uid; - bool selected : 1; - bool redrawNeeded : 1; - bool drawLinesInside : 1; - bool drawsInLeftMargin : 1; - unsigned int openness : 2; - - friend class TreeView; - friend class TreeViewContentComponent; - - void updatePositions (int newY); - int getIndentX() const throw(); - void setOwnerView (TreeView* const newOwner) throw(); - void paintRecursively (Graphics& g, int width); - TreeViewItem* getTopLevelItem() throw(); - TreeViewItem* findItemRecursively (int y) throw(); - TreeViewItem* getDeepestOpenParentItem() throw(); - int getNumRows() const throw(); - TreeViewItem* getItemOnRow (int index) throw(); - void deselectAllRecursively(); - int countSelectedItemsRecursively() const throw(); - TreeViewItem* getSelectedItemWithIndex (int index) throw(); - TreeViewItem* getNextVisibleItem (const bool recurse) const throw(); - TreeViewItem* findItemFromIdentifierString (const String& identifierString); - - TreeViewItem (const TreeViewItem&); - const TreeViewItem& operator= (const TreeViewItem&); -}; - -/** - A tree-view component. - - Use one of these to hold and display a structure of TreeViewItem objects. - -*/ -class JUCE_API TreeView : public Component, - public SettableTooltipClient, - public FileDragAndDropTarget, - public DragAndDropTarget, - private AsyncUpdater -{ -public: - - /** Creates an empty treeview. - - Once you've got a treeview component, you'll need to give it something to - display, using the setRootItem() method. - */ - TreeView (const String& componentName = String::empty); - - /** Destructor. */ - ~TreeView(); - - /** Sets the item that is displayed in the treeview. - - A tree has a single root item which contains as many sub-items as it needs. If - you want the tree to contain a number of root items, you should still use a single - root item above these, but hide it using setRootItemVisible(). - - You can pass in 0 to this method to clear the tree and remove its current root item. - - The object passed in will not be deleted by the treeview, it's up to the caller - to delete it when no longer needed. BUT make absolutely sure that you don't delete - this item until you've removed it from the tree, either by calling setRootItem (0), - or by deleting the tree first. You can also use deleteRootItem() as a quick way - to delete it. - */ - void setRootItem (TreeViewItem* const newRootItem); - - /** Returns the tree's root item. - - This will be the last object passed to setRootItem(), or 0 if none has been set. - */ - TreeViewItem* getRootItem() const throw() { return rootItem; } - - /** This will remove and delete the current root item. - - It's a convenient way of deleting the item and calling setRootItem (0). - */ - void deleteRootItem(); - - /** Changes whether the tree's root item is shown or not. - - If the root item is hidden, only its sub-items will be shown in the treeview - this - lets you make the tree look as if it's got many root items. If it's hidden, this call - will also make sure the root item is open (otherwise the treeview would look empty). - */ - void setRootItemVisible (const bool shouldBeVisible); - - /** Returns true if the root item is visible. - - @see setRootItemVisible - */ - bool isRootItemVisible() const throw() { return rootItemVisible; } - - /** Sets whether items are open or closed by default. - - Normally, items are closed until the user opens them, but you can use this - to make them default to being open until explicitly closed. - - @see areItemsOpenByDefault - */ - void setDefaultOpenness (const bool isOpenByDefault); - - /** Returns true if the tree's items default to being open. - - @see setDefaultOpenness - */ - bool areItemsOpenByDefault() const throw() { return defaultOpenness; } - - /** This sets a flag to indicate that the tree can be used for multi-selection. - - You can always select multiple items internally by calling the - TreeViewItem::setSelected() method, but this flag indicates whether the user - is allowed to multi-select by clicking on the tree. - - By default it is disabled. - - @see isMultiSelectEnabled - */ - void setMultiSelectEnabled (const bool canMultiSelect); - - /** Returns whether multi-select has been enabled for the tree. - - @see setMultiSelectEnabled - */ - bool isMultiSelectEnabled() const throw() { return multiSelectEnabled; } - - /** Sets a flag to indicate whether to hide the open/close buttons. - - @see areOpenCloseButtonsVisible - */ - void setOpenCloseButtonsVisible (const bool shouldBeVisible); - - /** Returns whether open/close buttons are shown. - - @see setOpenCloseButtonsVisible - */ - bool areOpenCloseButtonsVisible() const throw() { return openCloseButtonsVisible; } - - /** Deselects any items that are currently selected. */ - void clearSelectedItems(); - - /** Returns the number of items that are currently selected. - - @see getSelectedItem, clearSelectedItems - */ - int getNumSelectedItems() const throw(); - - /** Returns one of the selected items in the tree. - - @param index the index, 0 to (getNumSelectedItems() - 1) - */ - TreeViewItem* getSelectedItem (const int index) const throw(); - - /** Returns the number of rows the tree is using. - - This will depend on which items are open. - - @see TreeViewItem::getRowNumberInTree() - */ - int getNumRowsInTree() const; - - /** Returns the item on a particular row of the tree. - - If the index is out of range, this will return 0. - - @see getNumRowsInTree, TreeViewItem::getRowNumberInTree() - */ - TreeViewItem* getItemOnRow (int index) const; - - /** Returns the item that contains a given y position. - The y is relative to the top of the TreeView component. - */ - TreeViewItem* getItemAt (int yPosition) const throw(); - - /** Tries to scroll the tree so that this item is on-screen somewhere. */ - void scrollToKeepItemVisible (TreeViewItem* item); - - /** Returns the treeview's Viewport object. */ - Viewport* getViewport() const throw() { return viewport; } - - /** Returns the number of pixels by which each nested level of the tree is indented. - @see setIndentSize - */ - int getIndentSize() const throw() { return indentSize; } - - /** Changes the distance by which each nested level of the tree is indented. - @see getIndentSize - */ - void setIndentSize (const int newIndentSize); - - /** Searches the tree for an item with the specified identifier. - The identifer string must have been created by calling TreeViewItem::getItemIdentifierString(). - If no such item exists, this will return false. If the item is found, all of its items - will be automatically opened. - */ - TreeViewItem* findItemFromIdentifierString (const String& identifierString) const; - - /** Saves the current state of open/closed nodes so it can be restored later. - - This takes a snapshot of which nodes have been explicitly opened or closed, - and records it as XML. To identify node objects it uses the - TreeViewItem::getUniqueName() method to create named paths. This - means that the same state of open/closed nodes can be restored to a - completely different instance of the tree, as long as it contains nodes - whose unique names are the same. - - The caller is responsible for deleting the object that is returned. - - @param alsoIncludeScrollPosition if this is true, the state will also - include information about where the - tree has been scrolled to vertically, - so this can also be restored - @see restoreOpennessState - */ - XmlElement* getOpennessState (const bool alsoIncludeScrollPosition) const; - - /** Restores a previously saved arrangement of open/closed nodes. - - This will try to restore a snapshot of the tree's state that was created by - the getOpennessState() method. If any of the nodes named in the original - XML aren't present in this tree, they will be ignored. - - @see getOpennessState - */ - void restoreOpennessState (const XmlElement& newState); - - /** A set of colour IDs to use to change the colour of various aspects of the treeview. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1000500, /**< A background colour to fill the component with. */ - linesColourId = 0x1000501, /**< The colour to draw the lines with.*/ - dragAndDropIndicatorColourId = 0x1000502 /**< The colour to use for the drag-and-drop target position indicator. */ - }; - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - void colourChanged(); - /** @internal */ - void enablementChanged(); - /** @internal */ - bool isInterestedInFileDrag (const StringArray& files); - /** @internal */ - void fileDragEnter (const StringArray& files, int x, int y); - /** @internal */ - void fileDragMove (const StringArray& files, int x, int y); - /** @internal */ - void fileDragExit (const StringArray& files); - /** @internal */ - void filesDropped (const StringArray& files, int x, int y); - /** @internal */ - bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent); - /** @internal */ - void itemDragEnter (const String& sourceDescription, Component* sourceComponent, int x, int y); - /** @internal */ - void itemDragMove (const String& sourceDescription, Component* sourceComponent, int x, int y); - /** @internal */ - void itemDragExit (const String& sourceDescription, Component* sourceComponent); - /** @internal */ - void itemDropped (const String& sourceDescription, Component* sourceComponent, int x, int y); - - juce_UseDebuggingNewOperator - -private: - friend class TreeViewItem; - friend class TreeViewContentComponent; - Viewport* viewport; - CriticalSection nodeAlterationLock; - TreeViewItem* rootItem; - Component* dragInsertPointHighlight; - Component* dragTargetGroupHighlight; - int indentSize; - bool defaultOpenness : 1; - bool needsRecalculating : 1; - bool rootItemVisible : 1; - bool multiSelectEnabled : 1; - bool openCloseButtonsVisible : 1; - - void itemsChanged() throw(); - void handleAsyncUpdate(); - void moveSelectedRow (int delta); - void updateButtonUnderMouse (const MouseEvent& e); - void showDragHighlight (TreeViewItem* item, int insertIndex, int x, int y) throw(); - void hideDragHighlight() throw(); - void handleDrag (const StringArray& files, const String& sourceDescription, Component* sourceComponent, int x, int y); - void handleDrop (const StringArray& files, const String& sourceDescription, Component* sourceComponent, int x, int y); - TreeViewItem* getInsertPosition (int& x, int& y, int& insertIndex, - const StringArray& files, const String& sourceDescription, - Component* sourceComponent) const throw(); - - TreeView (const TreeView&); - const TreeView& operator= (const TreeView&); -}; - -#endif // __JUCE_TREEVIEW_JUCEHEADER__ -/********* End of inlined file: juce_TreeView.h *********/ - -/** - A component to allow editing of the keymaps stored by a KeyPressMappingSet - object. - - @see KeyPressMappingSet -*/ -class JUCE_API KeyMappingEditorComponent : public Component, - public TreeViewItem, - public ChangeListener, - private ButtonListener -{ -public: - - /** Creates a KeyMappingEditorComponent. - - @param mappingSet this is the set of mappings to display and - edit. Make sure the mappings object is not - deleted before this component! - @param showResetToDefaultButton if true, then at the bottom of the - list, the component will include a 'reset to - defaults' button. - */ - KeyMappingEditorComponent (KeyPressMappingSet* const mappingSet, - const bool showResetToDefaultButton); - - /** Destructor. */ - virtual ~KeyMappingEditorComponent(); - - /** Sets up the colours to use for parts of the component. - - @param mainBackground colour to use for most of the background - @param textColour colour to use for the text - */ - void setColours (const Colour& mainBackground, - const Colour& textColour); - - /** Returns the KeyPressMappingSet that this component is acting upon. - */ - KeyPressMappingSet* getMappings() const throw() { return mappings; } - - /** Can be overridden if some commands need to be excluded from the list. - - By default this will use the KeyPressMappingSet's shouldCommandBeVisibleInEditor() - method to decide what to return, but you can override it to handle special cases. - */ - virtual bool shouldCommandBeIncluded (const CommandID commandID); - - /** Can be overridden to indicate that some commands are shown as read-only. - - By default this will use the KeyPressMappingSet's shouldCommandBeReadOnlyInEditor() - method to decide what to return, but you can override it to handle special cases. - */ - virtual bool isCommandReadOnly (const CommandID commandID); - - /** This can be overridden to let you change the format of the string used - to describe a keypress. - - This is handy if you're using non-standard KeyPress objects, e.g. for custom - keys that are triggered by something else externally. If you override the - method, be sure to let the base class's method handle keys you're not - interested in. - */ - virtual const String getDescriptionForKeyPress (const KeyPress& key); - - /** A set of colour IDs to use to change the colour of various aspects of the editor. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - To change the colours of the menu that pops up - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x100ad00, /**< The background colour to fill the editor background. */ - textColourId = 0x100ad01, /**< The colour for the text. */ - }; - - /** @internal */ - void parentHierarchyChanged(); - /** @internal */ - void resized(); - /** @internal */ - void changeListenerCallback (void*); - /** @internal */ - bool mightContainSubItems(); - /** @internal */ - const String getUniqueName() const; - /** @internal */ - void buttonClicked (Button* button); - - juce_UseDebuggingNewOperator - -private: - - KeyPressMappingSet* mappings; - TreeView* tree; - friend class KeyMappingTreeViewItem; - friend class KeyCategoryTreeViewItem; - friend class KeyMappingItemComponent; - friend class KeyMappingChangeButton; - TextButton* resetButton; - - void assignNewKey (const CommandID commandID, int index); - - KeyMappingEditorComponent (const KeyMappingEditorComponent&); - const KeyMappingEditorComponent& operator= (const KeyMappingEditorComponent&); -}; - -#endif // __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_KeyMappingEditorComponent.h *********/ - -#endif -#ifndef __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_CodeEditorComponent.h *********/ -#ifndef __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ -#define __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_CODEDOCUMENT_JUCEHEADER__ /********* Start of inlined file: juce_CodeDocument.h *********/ #ifndef __JUCE_CODEDOCUMENT_JUCEHEADER__ @@ -45256,6 +41902,13 @@ private: #endif // __JUCE_CODEDOCUMENT_JUCEHEADER__ /********* End of inlined file: juce_CodeDocument.h *********/ +#endif +#ifndef __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_CodeEditorComponent.h *********/ +#ifndef __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ +#define __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ + /********* Start of inlined file: juce_CodeTokeniser.h *********/ #ifndef __JUCE_CODETOKENISER_JUCEHEADER__ #define __JUCE_CODETOKENISER_JUCEHEADER__ @@ -45550,6 +42203,9 @@ private: #endif // __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ /********* End of inlined file: juce_CodeEditorComponent.h *********/ +#endif +#ifndef __JUCE_CODETOKENISER_JUCEHEADER__ + #endif #ifndef __JUCE_CPLUSPLUSCODETOKENISER_JUCEHEADER__ @@ -45594,1134 +42250,15 @@ public: #endif // __JUCE_CPLUSPLUSCODETOKENISER_JUCEHEADER__ /********* End of inlined file: juce_CPlusPlusCodeTokeniser.h *********/ -#endif -#ifndef __JUCE_CODEDOCUMENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_CODETOKENISER_JUCEHEADER__ - -#endif -#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_MenuBarComponent.h *********/ -#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ -#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_MenuBarModel.h *********/ -#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ -#define __JUCE_MENUBARMODEL_JUCEHEADER__ - -class MenuBarModel; - -/** - A class to receive callbacks when a MenuBarModel changes. - - @see MenuBarModel::addListener, MenuBarModel::removeListener, MenuBarModel::menuItemsChanged -*/ -class JUCE_API MenuBarModelListener -{ -public: - /** Destructor. */ - virtual ~MenuBarModelListener() {} - - /** This callback is made when items are changed in the menu bar model. - */ - virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0; - - /** This callback is made when an application command is invoked that - is represented by one of the items in the menu bar model. - */ - virtual void menuCommandInvoked (MenuBarModel* menuBarModel, - const ApplicationCommandTarget::InvocationInfo& info) = 0; -}; - -/** - A class for controlling MenuBar components. - - This class is used to tell a MenuBar what menus to show, and to respond - to a menu being selected. - - @see MenuBarModelListener, MenuBarComponent, PopupMenu -*/ -class JUCE_API MenuBarModel : private AsyncUpdater, - private ApplicationCommandManagerListener -{ -public: - - MenuBarModel() throw(); - - /** Destructor. */ - virtual ~MenuBarModel(); - - /** Call this when some of your menu items have changed. - - This method will cause a callback to any MenuBarListener objects that - are registered with this model. - - If this model is displaying items from an ApplicationCommandManager, you - can use the setApplicationCommandManagerToWatch() method to cause - change messages to be sent automatically when the ApplicationCommandManager - is changed. - - @see addListener, removeListener, MenuBarListener - */ - void menuItemsChanged(); - - /** Tells the menu bar to listen to the specified command manager, and to update - itself when the commands change. - - This will also allow it to flash a menu name when a command from that menu - is invoked using a keystroke. - */ - void setApplicationCommandManagerToWatch (ApplicationCommandManager* const manager) throw(); - - /** Registers a listener for callbacks when the menu items in this model change. - - The listener object will get callbacks when this object's menuItemsChanged() - method is called. - - @see removeListener - */ - void addListener (MenuBarModelListener* const listenerToAdd) throw(); - - /** Removes a listener. - - @see addListener - */ - void removeListener (MenuBarModelListener* const listenerToRemove) throw(); - - /** This method must return a list of the names of the menus. */ - virtual const StringArray getMenuBarNames() = 0; - - /** This should return the popup menu to display for a given top-level menu. - - @param topLevelMenuIndex the index of the top-level menu to show - @param menuName the name of the top-level menu item to show - */ - virtual const PopupMenu getMenuForIndex (int topLevelMenuIndex, - const String& menuName) = 0; - - /** This is called when a menu item has been clicked on. - - @param menuItemID the item ID of the PopupMenu item that was selected - @param topLevelMenuIndex the index of the top-level menu from which the item was - chosen (just in case you've used duplicate ID numbers - on more than one of the popup menus) - */ - virtual void menuItemSelected (int menuItemID, - int topLevelMenuIndex) = 0; - -#if JUCE_MAC || DOXYGEN - /** MAC ONLY - Sets the model that is currently being shown as the main - menu bar at the top of the screen on the Mac. - - You can pass 0 to stop the current model being displayed. Be careful - not to delete a model while it is being used. - - An optional extra menu can be specified, containing items to add to the top of - the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of - an apple, it's the one next to it, with your application's name at the top - and the services menu etc on it). When one of these items is selected, the - menu bar model will be used to invoke it, and in the menuItemSelected() callback - the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems - object then newMenuBarModel must be non-null. - */ - static void setMacMainMenu (MenuBarModel* newMenuBarModel, - const PopupMenu* extraAppleMenuItems = 0) throw(); - - /** MAC ONLY - Returns the menu model that is currently being shown as - the main menu bar. - */ - static MenuBarModel* getMacMainMenu() throw(); - -#endif - - /** @internal */ - void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info); - /** @internal */ - void applicationCommandListChanged(); - /** @internal */ - void handleAsyncUpdate(); - - juce_UseDebuggingNewOperator - -private: - ApplicationCommandManager* manager; - SortedSet listeners; - - MenuBarModel (const MenuBarModel&); - const MenuBarModel& operator= (const MenuBarModel&); -}; - -#endif // __JUCE_MENUBARMODEL_JUCEHEADER__ -/********* End of inlined file: juce_MenuBarModel.h *********/ - -/** - A menu bar component. - - @see MenuBarModel -*/ -class JUCE_API MenuBarComponent : public Component, - private MenuBarModelListener, - private Timer -{ -public: - - /** Creates a menu bar. - - @param model the model object to use to control this bar. You can - pass 0 into this if you like, and set the model later - using the setModel() method - */ - MenuBarComponent (MenuBarModel* const model); - - /** Destructor. */ - ~MenuBarComponent(); - - /** Changes the model object to use to control the bar. - - This can be 0, in which case the bar will be empty. Don't delete the object - that is passed-in while it's still being used by this MenuBar. - */ - void setModel (MenuBarModel* const newModel); - - /** Pops up one of the menu items. - - This lets you manually open one of the menus - it could be triggered by a - key shortcut, for example. - */ - void showMenu (const int menuIndex); - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void mouseEnter (const MouseEvent& e); - /** @internal */ - void mouseExit (const MouseEvent& e); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - void mouseMove (const MouseEvent& e); - /** @internal */ - void inputAttemptWhenModal(); - /** @internal */ - void handleCommandMessage (int commandId); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - void menuBarItemsChanged (MenuBarModel* menuBarModel); - /** @internal */ - void menuCommandInvoked (MenuBarModel* menuBarModel, - const ApplicationCommandTarget::InvocationInfo& info); - - juce_UseDebuggingNewOperator - -private: - MenuBarModel* model; - - StringArray menuNames; - Array xPositions; - int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain; - int lastMouseX, lastMouseY; - bool inModalState; - Component* currentPopup; - - int getItemAt (int x, int y); - void updateItemUnderMouse (const int x, const int y); - void hideCurrentMenu(); - void timerCallback(); - void repaintMenuItem (int index); - - MenuBarComponent (const MenuBarComponent&); - const MenuBarComponent& operator= (const MenuBarComponent&); -}; - -#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_MenuBarComponent.h *********/ - -#endif -#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ - -#endif -#ifndef __JUCE_POPUPMENU_JUCEHEADER__ - -#endif -#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ - -/********* Start of inlined file: juce_ComponentDragger.h *********/ -#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ -#define __JUCE_COMPONENTDRAGGER_JUCEHEADER__ - -/********* Start of inlined file: juce_ComponentBoundsConstrainer.h *********/ -#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ -#define __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ - -/** - A class that imposes restrictions on a Component's size or position. - - This is used by classes such as ResizableCornerComponent, - ResizableBorderComponent and ResizableWindow. - - The base class can impose some basic size and position limits, but you can - also subclass this for custom uses. - - @see ResizableCornerComponent, ResizableBorderComponent, ResizableWindow -*/ -class JUCE_API ComponentBoundsConstrainer -{ -public: - - /** When first created, the object will not impose any restrictions on the components. */ - ComponentBoundsConstrainer() throw(); - - /** Destructor. */ - virtual ~ComponentBoundsConstrainer(); - - /** Imposes a minimum width limit. */ - void setMinimumWidth (const int minimumWidth) throw(); - - /** Returns the current minimum width. */ - int getMinimumWidth() const throw() { return minW; } - - /** Imposes a maximum width limit. */ - void setMaximumWidth (const int maximumWidth) throw(); - - /** Returns the current maximum width. */ - int getMaximumWidth() const throw() { return maxW; } - - /** Imposes a minimum height limit. */ - void setMinimumHeight (const int minimumHeight) throw(); - - /** Returns the current minimum height. */ - int getMinimumHeight() const throw() { return minH; } - - /** Imposes a maximum height limit. */ - void setMaximumHeight (const int maximumHeight) throw(); - - /** Returns the current maximum height. */ - int getMaximumHeight() const throw() { return maxH; } - - /** Imposes a minimum width and height limit. */ - void setMinimumSize (const int minimumWidth, - const int minimumHeight) throw(); - - /** Imposes a maximum width and height limit. */ - void setMaximumSize (const int maximumWidth, - const int maximumHeight) throw(); - - /** Set all the maximum and minimum dimensions. */ - void setSizeLimits (const int minimumWidth, - const int minimumHeight, - const int maximumWidth, - const int maximumHeight) throw(); - - /** Sets the amount by which the component is allowed to go off-screen. - - The values indicate how many pixels must remain on-screen when dragged off - one of its parent's edges, so e.g. if minimumWhenOffTheTop is set to 10, then - when the component goes off the top of the screen, its y-position will be - clipped so that there are always at least 10 pixels on-screen. In other words, - the lowest y-position it can take would be (10 - the component's height). - - If you pass 0 or less for one of these amounts, the component is allowed - to move beyond that edge completely, with no restrictions at all. - - If you pass a very large number (i.e. larger that the dimensions of the - component itself), then the component won't be allowed to overlap that - edge at all. So e.g. setting minimumWhenOffTheLeft to 0xffffff will mean that - the component will bump into the left side of the screen and go no further. - */ - void setMinimumOnscreenAmounts (const int minimumWhenOffTheTop, - const int minimumWhenOffTheLeft, - const int minimumWhenOffTheBottom, - const int minimumWhenOffTheRight) throw(); - - /** Specifies a width-to-height ratio that the resizer should always maintain. - - If the value is 0, no aspect ratio is enforced. If it's non-zero, the width - will always be maintained as this multiple of the height. - - @see setResizeLimits - */ - void setFixedAspectRatio (const double widthOverHeight) throw(); - - /** Returns the aspect ratio that was set with setFixedAspectRatio(). - - If no aspect ratio is being enforced, this will return 0. - */ - double getFixedAspectRatio() const throw(); - - /** This callback changes the given co-ordinates to impose whatever the current - constraints are set to be. - - @param x the x position that should be examined and adjusted - @param y the y position that should be examined and adjusted - @param w the width that should be examined and adjusted - @param h the height that should be examined and adjusted - @param previousBounds the component's current size - @param limits the region in which the component can be positioned - @param isStretchingTop whether the top edge of the component is being resized - @param isStretchingLeft whether the left edge of the component is being resized - @param isStretchingBottom whether the bottom edge of the component is being resized - @param isStretchingRight whether the right edge of the component is being resized - */ - virtual void checkBounds (int& x, int& y, int& w, int& h, - const Rectangle& previousBounds, - const Rectangle& limits, - const bool isStretchingTop, - const bool isStretchingLeft, - const bool isStretchingBottom, - const bool isStretchingRight); - - /** This callback happens when the resizer is about to start dragging. */ - virtual void resizeStart(); - - /** This callback happens when the resizer has finished dragging. */ - virtual void resizeEnd(); - - /** Checks the given bounds, and then sets the component to the corrected size. */ - void setBoundsForComponent (Component* const component, - int x, int y, int w, int h, - const bool isStretchingTop, - const bool isStretchingLeft, - const bool isStretchingBottom, - const bool isStretchingRight); - - /** Performs a check on the current size of a component, and moves or resizes - it if it fails the constraints. - */ - void checkComponentBounds (Component* component); - - /** Called by setBoundsForComponent() to apply a new constrained size to a - component. - - By default this just calls setBounds(), but it virtual in case it's needed for - extremely cunning purposes. - */ - virtual void applyBoundsToComponent (Component* component, - int x, int y, int w, int h); - - juce_UseDebuggingNewOperator - -private: - int minW, maxW, minH, maxH; - int minOffTop, minOffLeft, minOffBottom, minOffRight; - double aspectRatio; - - ComponentBoundsConstrainer (const ComponentBoundsConstrainer&); - const ComponentBoundsConstrainer& operator= (const ComponentBoundsConstrainer&); -}; - -#endif // __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ -/********* End of inlined file: juce_ComponentBoundsConstrainer.h *********/ - -/** - An object to take care of the logic for dragging components around with the mouse. - - Very easy to use - in your mouseDown() callback, call startDraggingComponent(), - then in your mouseDrag() callback, call dragComponent(). - - When starting a drag, you can give it a ComponentBoundsConstrainer to use - to limit the component's position and keep it on-screen. - - e.g. @code - class MyDraggableComp - { - ComponentDragger myDragger; - - void mouseDown (const MouseEvent& e) - { - myDragger.startDraggingComponent (this, 0); - } - - void mouseDrag (const MouseEvent& e) - { - myDragger.dragComponent (this, e); - } - }; - @endcode -*/ -class JUCE_API ComponentDragger -{ -public: - - /** Creates a ComponentDragger. */ - ComponentDragger(); - - /** Destructor. */ - virtual ~ComponentDragger(); - - /** Call this from your component's mouseDown() method, to prepare for dragging. - - @param componentToDrag the component that you want to drag - @param constrainer a constrainer object to use to keep the component - from going offscreen - @see dragComponent - */ - void startDraggingComponent (Component* const componentToDrag, - ComponentBoundsConstrainer* constrainer); - - /** Call this from your mouseDrag() callback to move the component. - - This will move the component, but will first check the validity of the - component's new position using the checkPosition() method, which you - can override if you need to enforce special positioning limits on the - component. - - @param componentToDrag the component that you want to drag - @param e the current mouse-drag event - @see dragComponent - */ - void dragComponent (Component* const componentToDrag, - const MouseEvent& e); - - juce_UseDebuggingNewOperator - -private: - ComponentBoundsConstrainer* constrainer; - int originalX, originalY; -}; - -#endif // __JUCE_COMPONENTDRAGGER_JUCEHEADER__ -/********* End of inlined file: juce_ComponentDragger.h *********/ - -#endif -#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ - -#endif -#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_LassoComponent.h *********/ -#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ -#define __JUCE_LASSOCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_SelectedItemSet.h *********/ -#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__ -#define __JUCE_SELECTEDITEMSET_JUCEHEADER__ - -/** Manages a list of selectable items. - - Use one of these to keep a track of things that the user has highlighted, like - icons or things in a list. - - The class is templated so that you can use it to hold either a set of pointers - to objects, or a set of ID numbers or handles, for cases where each item may - not always have a corresponding object. - - To be informed when items are selected/deselected, register a ChangeListener with - this object. - - @see SelectableObject -*/ -template -class JUCE_API SelectedItemSet : public ChangeBroadcaster -{ -public: - - /** Creates an empty set. */ - SelectedItemSet() - { - } - - /** Creates a set based on an array of items. */ - SelectedItemSet (const Array & items) - : selectedItems (items) - { - } - - /** Creates a copy of another set. */ - SelectedItemSet (const SelectedItemSet& other) - : selectedItems (other.selectedItems) - { - } - - /** Creates a copy of another set. */ - const SelectedItemSet& operator= (const SelectedItemSet& other) - { - if (selectedItems != other.selectedItems) - { - selectedItems = other.selectedItems; - changed(); - } - - return *this; - } - - /** Destructor. */ - ~SelectedItemSet() - { - } - - /** Clears any other currently selected items, and selects this item. - - If this item is already the only thing selected, no change notification - will be sent out. - - @see addToSelection, addToSelectionBasedOnModifiers - */ - void selectOnly (SelectableItemType item) - { - if (isSelected (item)) - { - for (int i = selectedItems.size(); --i >= 0;) - { - if (selectedItems.getUnchecked(i) != item) - { - deselect (selectedItems.getUnchecked(i)); - i = jmin (i, selectedItems.size()); - } - } - } - else - { - deselectAll(); - changed(); - - selectedItems.add (item); - itemSelected (item); - } - } - - /** Selects an item. - - If the item is already selected, no change notification will be sent out. - - @see selectOnly, addToSelectionBasedOnModifiers - */ - void addToSelection (SelectableItemType item) - { - if (! isSelected (item)) - { - changed(); - - selectedItems.add (item); - itemSelected (item); - } - } - - /** Selects or deselects an item. - - This will use the modifier keys to decide whether to deselect other items - first. - - So if the shift key is held down, the item will be added without deselecting - anything (same as calling addToSelection() ) - - If no modifiers are down, the current selection will be cleared first (same - as calling selectOnly() ) - - If the ctrl (or command on the Mac) key is held down, the item will be toggled - - so it'll be added to the set unless it's already there, in which case it'll be - deselected. - - If the items that you're selecting can also be dragged, you may need to use the - addToSelectionOnMouseDown() and addToSelectionOnMouseUp() calls to handle the - subtleties of this kind of usage. - - @see selectOnly, addToSelection, addToSelectionOnMouseDown, addToSelectionOnMouseUp - */ - void addToSelectionBasedOnModifiers (SelectableItemType item, - const ModifierKeys& modifiers) - { - if (modifiers.isShiftDown()) - { - addToSelection (item); - } - else if (modifiers.isCommandDown()) - { - if (isSelected (item)) - deselect (item); - else - addToSelection (item); - } - else - { - selectOnly (item); - } - } - - /** Selects or deselects items that can also be dragged, based on a mouse-down event. - - If you call addToSelectionOnMouseDown() at the start of your mouseDown event, - and then call addToSelectionOnMouseUp() at the end of your mouseUp event, this - makes it easy to handle multiple-selection of sets of objects that can also - be dragged. - - For example, if you have several items already selected, and you click on - one of them (without dragging), then you'd expect this to deselect the other, and - just select the item you clicked on. But if you had clicked on this item and - dragged it, you'd have expected them all to stay selected. - - When you call this method, you'll need to store the boolean result, because the - addToSelectionOnMouseUp() method will need to be know this value. - - @see addToSelectionOnMouseUp, addToSelectionBasedOnModifiers - */ - bool addToSelectionOnMouseDown (SelectableItemType item, - const ModifierKeys& modifiers) - { - if (isSelected (item)) - { - return ! modifiers.isPopupMenu(); - } - else - { - addToSelectionBasedOnModifiers (item, modifiers); - return false; - } - } - - /** Selects or deselects items that can also be dragged, based on a mouse-up event. - - Call this during a mouseUp callback, when you have previously called the - addToSelectionOnMouseDown() method during your mouseDown event. - - See addToSelectionOnMouseDown() for more info - - @param item the item to select (or deselect) - @param modifiers the modifiers from the mouse-up event - @param wasItemDragged true if your item was dragged during the mouse click - @param resultOfMouseDownSelectMethod this is the boolean return value that came - back from the addToSelectionOnMouseDown() call that you - should have made during the matching mouseDown event - */ - void addToSelectionOnMouseUp (SelectableItemType item, - const ModifierKeys& modifiers, - const bool wasItemDragged, - const bool resultOfMouseDownSelectMethod) - { - if (resultOfMouseDownSelectMethod && ! wasItemDragged) - addToSelectionBasedOnModifiers (item, modifiers); - } - - /** Deselects an item. */ - void deselect (SelectableItemType item) - { - const int i = selectedItems.indexOf (item); - - if (i >= 0) - { - changed(); - itemDeselected (selectedItems.remove (i)); - } - } - - /** Deselects all items. */ - void deselectAll() - { - if (selectedItems.size() > 0) - { - changed(); - - for (int i = selectedItems.size(); --i >= 0;) - { - itemDeselected (selectedItems.remove (i)); - i = jmin (i, selectedItems.size()); - } - } - } - - /** Returns the number of currently selected items. - - @see getSelectedItem - */ - int getNumSelected() const throw() - { - return selectedItems.size(); - } - - /** Returns one of the currently selected items. - - Returns 0 if the index is out-of-range. - - @see getNumSelected - */ - SelectableItemType getSelectedItem (const int index) const throw() - { - return selectedItems [index]; - } - - /** True if this item is currently selected. */ - bool isSelected (const SelectableItemType item) const throw() - { - return selectedItems.contains (item); - } - - const Array & getItemArray() const throw() { return selectedItems; } - - /** Can be overridden to do special handling when an item is selected. - - For example, if the item is an object, you might want to call it and tell - it that it's being selected. - */ - virtual void itemSelected (SelectableItemType item) {} - - /** Can be overridden to do special handling when an item is deselected. - - For example, if the item is an object, you might want to call it and tell - it that it's being deselected. - */ - virtual void itemDeselected (SelectableItemType item) {} - - /** Used internally, but can be called to force a change message to be sent to the ChangeListeners. - */ - void changed (const bool synchronous = false) - { - if (synchronous) - sendSynchronousChangeMessage (this); - else - sendChangeMessage (this); - } - - juce_UseDebuggingNewOperator - -private: - Array selectedItems; -}; - -#endif // __JUCE_SELECTEDITEMSET_JUCEHEADER__ -/********* End of inlined file: juce_SelectedItemSet.h *********/ - -/** - A class used by the LassoComponent to manage the things that it selects. - - This allows the LassoComponent to find out which items are within the lasso, - and to change the list of selected items. - - @see LassoComponent, SelectedItemSet -*/ -template -class LassoSource -{ -public: - /** Destructor. */ - virtual ~LassoSource() {} - - /** Returns the set of items that lie within a given lassoable region. - - Your implementation of this method must find all the relevent items that lie - within the given rectangle. and add them to the itemsFound array. - - The co-ordinates are relative to the top-left of the lasso component's parent - component. (i.e. they are the same as the size and position of the lasso - component itself). - */ - virtual void findLassoItemsInArea (Array & itemsFound, - int x, int y, int width, int height) = 0; - - /** Returns the SelectedItemSet that the lasso should update. - - This set will be continuously updated by the LassoComponent as it gets - dragged around, so make sure that you've got a ChangeListener attached to - the set so that your UI objects will know when the selection changes and - be able to update themselves appropriately. - */ - virtual SelectedItemSet & getLassoSelection() = 0; -}; - -/** - A component that acts as a rectangular selection region, which you drag with - the mouse to select groups of objects (in conjunction with a SelectedItemSet). - - To use one of these: - - - In your mouseDown or mouseDrag event, add the LassoComponent to your parent - component, and call its beginLasso() method, giving it a - suitable LassoSource object that it can use to find out which items are in - the active area. - - - Each time your parent component gets a mouseDrag event, call dragLasso() - to update the lasso's position - it will use its LassoSource to calculate and - update the current selection. - - - After the drag has finished and you get a mouseUp callback, you should call - endLasso() to clean up. This will make the lasso component invisible, and you - can remove it from the parent component, or delete it. - - The class takes into account the modifier keys that are being held down while - the lasso is being dragged, so if shift is pressed, then any lassoed items will - be added to the original selection; if ctrl or command is pressed, they will be - xor'ed with any previously selected items. - - @see LassoSource, SelectedItemSet -*/ -template -class LassoComponent : public Component -{ -public: - - /** Creates a Lasso component. - - The fill colour is used to fill the lasso'ed rectangle, and the outline - colour is used to draw a line around its edge. - */ - LassoComponent (const int outlineThickness_ = 1) - : source (0), - outlineThickness (outlineThickness_) - { - } - - /** Destructor. */ - ~LassoComponent() - { - } - - /** Call this in your mouseDown event, to initialise a drag. - - Pass in a suitable LassoSource object which the lasso will use to find - the items and change the selection. - - After using this method to initialise the lasso, repeatedly call dragLasso() - in your component's mouseDrag callback. - - @see dragLasso, endLasso, LassoSource - */ - void beginLasso (const MouseEvent& e, - LassoSource * const lassoSource) - { - jassert (source == 0); // this suggests that you didn't call endLasso() after the last drag... - jassert (lassoSource != 0); // the source can't be null! - jassert (getParentComponent() != 0); // you need to add this to a parent component for it to work! - - source = lassoSource; - - if (lassoSource != 0) - originalSelection = lassoSource->getLassoSelection().getItemArray(); - - setSize (0, 0); - } - - /** Call this in your mouseDrag event, to update the lasso's position. - - This must be repeatedly calling when the mouse is dragged, after you've - first initialised the lasso with beginLasso(). - - This method takes into account the modifier keys that are being held down, so - if shift is pressed, then the lassoed items will be added to any that were - previously selected; if ctrl or command is pressed, then they will be xor'ed - with previously selected items. - - @see beginLasso, endLasso - */ - void dragLasso (const MouseEvent& e) - { - if (source != 0) - { - const int x1 = e.getMouseDownX(); - const int y1 = e.getMouseDownY(); - - setBounds (jmin (x1, e.x), jmin (y1, e.y), abs (e.x - x1), abs (e.y - y1)); - setVisible (true); - - Array itemsInLasso; - source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); - - if (e.mods.isShiftDown()) - { - itemsInLasso.removeValuesIn (originalSelection); // to avoid duplicates - itemsInLasso.addArray (originalSelection); - } - else if (e.mods.isCommandDown() || e.mods.isAltDown()) - { - Array originalMinusNew (originalSelection); - originalMinusNew.removeValuesIn (itemsInLasso); - - itemsInLasso.removeValuesIn (originalSelection); - itemsInLasso.addArray (originalMinusNew); - } - - source->getLassoSelection() = SelectedItemSet (itemsInLasso); - } - } - - /** Call this in your mouseUp event, after the lasso has been dragged. - - @see beginLasso, dragLasso - */ - void endLasso() - { - source = 0; - originalSelection.clear(); - setVisible (false); - } - - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - Note that you can also use the constants from TextEditor::ColourIds to change the - colour of the text editor that is opened when a label is editable. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - lassoFillColourId = 0x1000440, /**< The colour to fill the lasso rectangle with. */ - lassoOutlineColourId = 0x1000441, /**< The colour to draw the outline with. */ - }; - - /** @internal */ - void paint (Graphics& g) - { - g.fillAll (findColour (lassoFillColourId)); - - g.setColour (findColour (lassoOutlineColourId)); - g.drawRect (0, 0, getWidth(), getHeight(), outlineThickness); - - // this suggests that you've left a lasso comp lying around after the - // mouse drag has finished.. Be careful to call endLasso() when you get a - // mouse-up event. - jassert (isMouseButtonDownAnywhere()); - } - - /** @internal */ - bool hitTest (int x, int y) { return false; } - - juce_UseDebuggingNewOperator - -private: - Array originalSelection; - LassoSource * source; - int outlineThickness; -}; - -#endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_LassoComponent.h *********/ - -#endif -#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__ - -#endif -#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ - -/********* Start of inlined file: juce_MouseHoverDetector.h *********/ -#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ -#define __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ - -/** - Monitors a component for mouse activity, and triggers a callback - when the mouse hovers in one place for a specified length of time. - - To use a hover-detector, just create one and call its setHoverComponent() - method to start it watching a component. You can call setHoverComponent (0) - to make it inactive. - - (Be careful not to delete a component that's being monitored without first - stopping or deleting the hover detector). -*/ -class JUCE_API MouseHoverDetector -{ -public: - - /** Creates a hover detector. - - Initially the object is inactive, and you need to tell it which component - to monitor, using the setHoverComponent() method. - - @param hoverTimeMillisecs the number of milliseconds for which the mouse - needs to stay still before the mouseHovered() method - is invoked. You can change this setting later with - the setHoverTimeMillisecs() method - */ - MouseHoverDetector (const int hoverTimeMillisecs = 400); - - /** Destructor. */ - virtual ~MouseHoverDetector(); - - /** Changes the time for which the mouse has to stay still before it's considered - to be hovering. - */ - void setHoverTimeMillisecs (const int newTimeInMillisecs); - - /** Changes the component that's being monitored for hovering. - - Be careful not to delete a component that's being monitored without first - stopping or deleting the hover detector. - */ - void setHoverComponent (Component* const newSourceComponent); - -protected: - - /** Called back when the mouse hovers. - - After the mouse has stayed still over the component for the length of time - specified by setHoverTimeMillisecs(), this method will be invoked. - - When the mouse is first moved after this callback has occurred, the - mouseMovedAfterHover() method will be called. - - @param mouseX the mouse's X position relative to the component being monitored - @param mouseY the mouse's Y position relative to the component being monitored - */ - virtual void mouseHovered (int mouseX, - int mouseY) = 0; - - /** Called when the mouse is moved away after just having hovered. */ - virtual void mouseMovedAfterHover() = 0; - -private: - - class JUCE_API HoverDetectorInternal : public MouseListener, - public Timer - { - public: - MouseHoverDetector* owner; - int lastX, lastY; - - void timerCallback(); - void mouseEnter (const MouseEvent&); - void mouseExit (const MouseEvent&); - void mouseDown (const MouseEvent&); - void mouseUp (const MouseEvent&); - void mouseMove (const MouseEvent&); - void mouseWheelMove (const MouseEvent&, float, float); - - } internalTimer; - - friend class HoverDetectorInternal; - - Component* source; - int hoverTimeMillisecs; - bool hasJustHovered; - - void hoverTimerCallback(); - void checkJustHoveredCallback(); -}; - -#endif // __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ -/********* End of inlined file: juce_MouseHoverDetector.h *********/ - -#endif -#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ - #endif #ifndef __JUCE_COMBOBOX_JUCEHEADER__ #endif #ifndef __JUCE_LABEL_JUCEHEADER__ +#endif +#ifndef __JUCE_LISTBOX_JUCEHEADER__ + #endif #ifndef __JUCE_PROGRESSBAR_JUCEHEADER__ @@ -48281,9 +43818,15 @@ private: #endif // __JUCE_TABLELISTBOX_JUCEHEADER__ /********* End of inlined file: juce_TableListBox.h *********/ +#endif +#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ + #endif #ifndef __JUCE_TOOLBAR_JUCEHEADER__ +#endif +#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ + #endif #ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ @@ -48369,9 +43912,6 @@ public: #endif // __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ /********* End of inlined file: juce_ToolbarItemFactory.h *********/ -#endif -#ifndef __JUCE_LISTBOX_JUCEHEADER__ - #endif #ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ @@ -48430,327 +43970,4112 @@ private: #endif #ifndef __JUCE_TREEVIEW_JUCEHEADER__ -#endif -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ +/********* Start of inlined file: juce_TreeView.h *********/ +#ifndef __JUCE_TREEVIEW_JUCEHEADER__ +#define __JUCE_TREEVIEW_JUCEHEADER__ -#endif -#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_BooleanPropertyComponent.h *********/ -#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_FileDragAndDropTarget.h *********/ +#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ +#define __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ /** - A PropertyComponent that contains an on/off toggle button. + Components derived from this class can have files dropped onto them by an external application. - This type of property component can be used if you have a boolean value to - toggle on/off. - - @see PropertyComponent + @see DragAndDropContainer */ -class JUCE_API BooleanPropertyComponent : public PropertyComponent, - private ButtonListener +class JUCE_API FileDragAndDropTarget +{ +public: + /** Destructor. */ + virtual ~FileDragAndDropTarget() {} + + /** Callback to check whether this target is interested in the set of files being offered. + + Note that this will be called repeatedly when the user is dragging the mouse around over your + component, so don't do anything time-consuming in here, like opening the files to have a look + inside them! + + @param files the set of (absolute) pathnames of the files that the user is dragging + @returns true if this component wants to receive the other callbacks regarging this + type of object; if it returns false, no other callbacks will be made. + */ + virtual bool isInterestedInFileDrag (const StringArray& files) = 0; + + /** Callback to indicate that some files are being dragged over this component. + + This gets called when the user moves the mouse into this component while dragging. + + Use this callback as a trigger to make your component repaint itself to give the + user feedback about whether the files can be dropped here or not. + + @param files the set of (absolute) pathnames of the files that the user is dragging + @param x the mouse x position, relative to this component + @param y the mouse y position, relative to this component + */ + virtual void fileDragEnter (const StringArray& files, int x, int y); + + /** Callback to indicate that the user is dragging some files over this component. + + This gets called when the user moves the mouse over this component while dragging. + Normally overriding itemDragEnter() and itemDragExit() are enough, but + this lets you know what happens in-between. + + @param files the set of (absolute) pathnames of the files that the user is dragging + @param x the mouse x position, relative to this component + @param y the mouse y position, relative to this component + */ + virtual void fileDragMove (const StringArray& files, int x, int y); + + /** Callback to indicate that the mouse has moved away from this component. + + This gets called when the user moves the mouse out of this component while dragging + the files. + + If you've used fileDragEnter() to repaint your component and give feedback, use this + as a signal to repaint it in its normal state. + + @param files the set of (absolute) pathnames of the files that the user is dragging + */ + virtual void fileDragExit (const StringArray& files); + + /** Callback to indicate that the user has dropped the files onto this component. + + When the user drops the files, this get called, and you can use the files in whatever + way is appropriate. + + Note that after this is called, the fileDragExit method may not be called, so you should + clean up in here if there's anything you need to do when the drag finishes. + + @param files the set of (absolute) pathnames of the files that the user is dragging + @param x the mouse x position, relative to this component + @param y the mouse y position, relative to this component + */ + virtual void filesDropped (const StringArray& files, int x, int y) = 0; +}; + +#endif // __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ +/********* End of inlined file: juce_FileDragAndDropTarget.h *********/ + +class TreeView; + +/** + An item in a treeview. + + A TreeViewItem can either be a leaf-node in the tree, or it can contain its + own sub-items. + + To implement an item that contains sub-items, override the itemOpennessChanged() + method so that when it is opened, it adds the new sub-items to itself using the + addSubItem method. Depending on the nature of the item it might choose to only + do this the first time it's opened, or it might want to refresh itself each time. + It also has the option of deleting its sub-items when it is closed, or leaving them + in place. +*/ +class JUCE_API TreeViewItem { public: - /** Creates a button component. - - @param propertyName the property name to be passed to the PropertyComponent - @param buttonTextWhenTrue the text shown in the button when the value is true - @param buttonTextWhenFalse the text shown in the button when the value is false - */ - BooleanPropertyComponent (const String& propertyName, - const String& buttonTextWhenTrue, - const String& buttonTextWhenFalse); + /** Constructor. */ + TreeViewItem(); /** Destructor. */ - ~BooleanPropertyComponent(); + virtual ~TreeViewItem(); - /** Called to change the state of the boolean value. */ - virtual void setState (const bool newState) = 0; + /** Returns the number of sub-items that have been added to this item. - /** Must return the current value of the property. */ - virtual bool getState() const = 0; + Note that this doesn't mean much if the node isn't open. + + @see getSubItem, mightContainSubItems, addSubItem + */ + int getNumSubItems() const throw(); + + /** Returns one of the item's sub-items. + + Remember that the object returned might get deleted at any time when its parent + item is closed or refreshed, depending on the nature of the items you're using. + + @see getNumSubItems + */ + TreeViewItem* getSubItem (const int index) const throw(); + + /** Removes any sub-items. */ + void clearSubItems(); + + /** Adds a sub-item. + + @param newItem the object to add to the item's sub-item list. Once added, these can be + found using getSubItem(). When the items are later removed with + removeSubItem() (or when this item is deleted), they will be deleted. + @param insertPosition the index which the new item should have when it's added. If this + value is less than 0, the item will be added to the end of the list. + */ + void addSubItem (TreeViewItem* const newItem, + const int insertPosition = -1); + + /** Removes one of the sub-items. + + @param index the item to remove + @param deleteItem if true, the item that is removed will also be deleted. + */ + void removeSubItem (const int index, + const bool deleteItem = true); + + /** Returns the TreeView to which this item belongs. */ + TreeView* getOwnerView() const throw() { return ownerView; } + + /** Returns the item within which this item is contained. */ + TreeViewItem* getParentItem() const throw() { return parentItem; } + + /** True if this item is currently open in the treeview. */ + bool isOpen() const throw(); + + /** Opens or closes the item. + + When opened or closed, the item's itemOpennessChanged() method will be called, + and a subclass should use this callback to create and add any sub-items that + it needs to. + + @see itemOpennessChanged, mightContainSubItems + */ + void setOpen (const bool shouldBeOpen); + + /** True if this item is currently selected. + + Use this when painting the node, to decide whether to draw it as selected or not. + */ + bool isSelected() const throw(); + + /** Selects or deselects the item. + + This will cause a callback to itemSelectionChanged() + */ + void setSelected (const bool shouldBeSelected, + const bool deselectOtherItemsFirst); + + /** Returns the rectangle that this item occupies. + + If relativeToTreeViewTopLeft is true, the co-ordinates are relative to the + top-left of the TreeView comp, so this will depend on the scroll-position of + the tree. If false, it is relative to the top-left of the topmost item in the + tree (so this would be unaffected by scrolling the view). + */ + const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const throw(); + + /** Sends a signal to the treeview to make it refresh itself. + + Call this if your items have changed and you want the tree to update to reflect + this. + */ + void treeHasChanged() const throw(); + + /** Sends a repaint message to redraw just this item. + + Note that you should only call this if you want to repaint a superficial change. If + you're altering the tree's nodes, you should instead call treeHasChanged(). + */ + void repaintItem() const; + + /** Returns the row number of this item in the tree. + + The row number of an item will change according to which items are open. + + @see TreeView::getNumRowsInTree(), TreeView::getItemOnRow() + */ + int getRowNumberInTree() const throw(); + + /** Returns true if all the item's parent nodes are open. + + This is useful to check whether the item might actually be visible or not. + */ + bool areAllParentsOpen() const throw(); + + /** Changes whether lines are drawn to connect any sub-items to this item. + + By default, line-drawing is turned on. + */ + void setLinesDrawnForSubItems (const bool shouldDrawLines) throw(); + + /** Tells the tree whether this item can potentially be opened. + + If your item could contain sub-items, this should return true; if it returns + false then the tree will not try to open the item. This determines whether or + not the item will be drawn with a 'plus' button next to it. + */ + virtual bool mightContainSubItems() = 0; + + /** Returns a string to uniquely identify this item. + + If you're planning on using the TreeView::getOpennessState() method, then + these strings will be used to identify which nodes are open. The string + should be unique amongst the item's sibling items, but it's ok for there + to be duplicates at other levels of the tree. + + If you're not going to store the state, then it's ok not to bother implementing + this method. + */ + virtual const String getUniqueName() const; + + /** Called when an item is opened or closed. + + When setOpen() is called and the item has specified that it might + have sub-items with the mightContainSubItems() method, this method + is called to let the item create or manage its sub-items. + + So when this is called with isNowOpen set to true (i.e. when the item is being + opened), a subclass might choose to use clearSubItems() and addSubItem() to + refresh its sub-item list. + + When this is called with isNowOpen set to false, the subclass might want + to use clearSubItems() to save on space, or it might choose to leave them, + depending on the nature of the tree. + + You could also use this callback as a trigger to start a background process + which asynchronously creates sub-items and adds them, if that's more + appropriate for the task in hand. + + @see mightContainSubItems + */ + virtual void itemOpennessChanged (bool isNowOpen); + + /** Must return the width required by this item. + + If your item needs to have a particular width in pixels, return that value; if + you'd rather have it just fill whatever space is available in the treeview, + return -1. + + If all your items return -1, no horizontal scrollbar will be shown, but if any + items have fixed widths and extend beyond the width of the treeview, a + scrollbar will appear. + + Each item can be a different width, but if they change width, you should call + treeHasChanged() to update the tree. + */ + virtual int getItemWidth() const { return -1; } + + /** Must return the height required by this item. + + This is the height in pixels that the item will take up. Items in the tree + can be different heights, but if they change height, you should call + treeHasChanged() to update the tree. + */ + virtual int getItemHeight() const { return 20; } + + /** You can override this method to return false if you don't want to allow the + user to select this item. + */ + virtual bool canBeSelected() const { return true; } + + /** Creates a component that will be used to represent this item. + + You don't have to implement this method - if it returns 0 then no component + will be used for the item, and you can just draw it using the paintItem() + callback. But if you do return a component, it will be positioned in the + treeview so that it can be used to represent this item. + + The component returned will be managed by the treeview, so always return + a new component, and don't keep a reference to it, as the treeview will + delete it later when it goes off the screen or is no longer needed. Also + bear in mind that if the component keeps a reference to the item that + created it, that item could be deleted before the component. Its position + and size will be completely managed by the tree, so don't attempt to move it + around. + + Something you may want to do with your component is to give it a pointer to + the TreeView that created it. This is perfectly safe, and there's no danger + of it becoming a dangling pointer because the TreeView will always delete + the component before it is itself deleted. + + As long as you stick to these rules you can return whatever kind of + component you like. It's most useful if you're doing things like drag-and-drop + of items, or want to use a Label component to edit item names, etc. + */ + virtual Component* createItemComponent() { return 0; } + + /** Draws the item's contents. + + You can choose to either implement this method and draw each item, or you + can use createItemComponent() to create a component that will represent the + item. + + If all you need in your tree is to be able to draw the items and detect when + the user selects or double-clicks one of them, it's probably enough to + use paintItem(), itemClicked() and itemDoubleClicked(). If you need more + complicated interactions, you may need to use createItemComponent() instead. + + @param g the graphics context to draw into + @param width the width of the area available for drawing + @param height the height of the area available for drawing + */ + virtual void paintItem (Graphics& g, int width, int height); + + /** Draws the item's open/close button. + + If you don't implement this method, the default behaviour is to + call LookAndFeel::drawTreeviewPlusMinusBox(), but you can override + it for custom effects. + */ + virtual void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver); + + /** Called when the user clicks on this item. + + If you're using createItemComponent() to create a custom component for the + item, the mouse-clicks might not make it through to the treeview, but this + is how you find out about clicks when just drawing each item individually. + + The associated mouse-event details are passed in, so you can find out about + which button, where it was, etc. + + @see itemDoubleClicked + */ + virtual void itemClicked (const MouseEvent& e); + + /** Called when the user double-clicks on this item. + + If you're using createItemComponent() to create a custom component for the + item, the mouse-clicks might not make it through to the treeview, but this + is how you find out about clicks when just drawing each item individually. + + The associated mouse-event details are passed in, so you can find out about + which button, where it was, etc. + + If not overridden, the base class method here will open or close the item as + if the 'plus' button had been clicked. + + @see itemClicked + */ + virtual void itemDoubleClicked (const MouseEvent& e); + + /** Called when the item is selected or deselected. + + Use this if you want to do something special when the item's selectedness + changes. By default it'll get repainted when this happens. + */ + virtual void itemSelectionChanged (bool isNowSelected); + + /** The item can return a tool tip string here if it wants to. + @see TooltipClient + */ + virtual const String getTooltip(); + + /** To allow items from your treeview to be dragged-and-dropped, implement this method. + + If this returns a non-empty name then when the user drags an item, the treeview will + try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger + a drag-and-drop operation, using this string as the source description, with the treeview + itself as the source component. + + If you need more complex drag-and-drop behaviour, you can use custom components for + the items, and use those to trigger the drag. + + To accept drag-and-drop in your tree, see isInterestedInDragSource(), + isInterestedInFileDrag(), etc. + + @see DragAndDropContainer::startDragging + */ + virtual const String getDragSourceDescription(); + + /** If you want your item to be able to have files drag-and-dropped onto it, implement this + method and return true. + + If you return true and allow some files to be dropped, you'll also need to implement the + filesDropped() method to do something with them. + + Note that this will be called often, so make your implementation very quick! There's + certainly no time to try opening the files and having a think about what's inside them! + + For responding to internal drag-and-drop of other types of object, see isInterestedInDragSource(). + @see FileDragAndDropTarget::isInterestedInFileDrag, isInterestedInDragSource + */ + virtual bool isInterestedInFileDrag (const StringArray& files); + + /** When files are dropped into this item, this callback is invoked. + + For this to work, you'll need to have also implemented isInterestedInFileDrag(). + The insertIndex value indicates where in the list of sub-items the files were dropped. + @see FileDragAndDropTarget::filesDropped, isInterestedInFileDrag + */ + virtual void filesDropped (const StringArray& files, int insertIndex); + + /** If you want your item to act as a DragAndDropTarget, implement this method and return true. + + If you implement this method, you'll also need to implement itemDropped() in order to handle + the items when they are dropped. + To respond to drag-and-drop of files from external applications, see isInterestedInFileDrag(). + @see DragAndDropTarget::isInterestedInDragSource, itemDropped + */ + virtual bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent); + + /** When a things are dropped into this item, this callback is invoked. + + For this to work, you need to have also implemented isInterestedInDragSource(). + The insertIndex value indicates where in the list of sub-items the new items should be placed. + @see isInterestedInDragSource, DragAndDropTarget::itemDropped + */ + virtual void itemDropped (const String& sourceDescription, Component* sourceComponent, int insertIndex); + + /** Sets a flag to indicate that the item wants to be allowed + to draw all the way across to the left edge of the treeview. + + By default this is false, which means that when the paintItem() + method is called, its graphics context is clipped to only allow + drawing within the item's rectangle. If this flag is set to true, + then the graphics context isn't clipped on its left side, so it + can draw all the way across to the left margin. Note that the + context will still have its origin in the same place though, so + the coordinates of anything to its left will be negative. It's + mostly useful if you want to draw a wider bar behind the + highlighted item. + */ + void setDrawsInLeftMargin (bool canDrawInLeftMargin) throw(); + + /** Saves the current state of open/closed nodes so it can be restored later. + + This takes a snapshot of which sub-nodes have been explicitly opened or closed, + and records it as XML. To identify node objects it uses the + TreeViewItem::getUniqueName() method to create named paths. This + means that the same state of open/closed nodes can be restored to a + completely different instance of the tree, as long as it contains nodes + whose unique names are the same. + + You'd normally want to use TreeView::getOpennessState() rather than call it + for a specific item, but this can be handy if you need to briefly save the state + for a section of the tree. + + The caller is responsible for deleting the object that is returned. + @see TreeView::getOpennessState, restoreOpennessState + */ + XmlElement* getOpennessState() const throw(); + + /** Restores the openness of this item and all its sub-items from a saved state. + + See TreeView::restoreOpennessState for more details. + + You'd normally want to use TreeView::restoreOpennessState() rather than call it + for a specific item, but this can be handy if you need to briefly save the state + for a section of the tree. + + @see TreeView::restoreOpennessState, getOpennessState + */ + void restoreOpennessState (const XmlElement& xml) throw(); + + /** Returns the index of this item in its parent's sub-items. */ + int getIndexInParent() const throw(); + + /** Returns true if this item is the last of its parent's sub-itens. */ + bool isLastOfSiblings() const throw(); + + /** Creates a string that can be used to uniquely retrieve this item in the tree. + + The string that is returned can be passed to TreeView::findItemFromIdentifierString(). + The string takes the form of a path, constructed from the getUniqueName() of this + item and all its parents, so these must all be correctly implemented for it to work. + @see TreeView::findItemFromIdentifierString, getUniqueName + */ + const String getItemIdentifierString() const; + + juce_UseDebuggingNewOperator + +private: + TreeView* ownerView; + TreeViewItem* parentItem; + OwnedArray subItems; + int y, itemHeight, totalHeight, itemWidth, totalWidth; + int uid; + bool selected : 1; + bool redrawNeeded : 1; + bool drawLinesInside : 1; + bool drawsInLeftMargin : 1; + unsigned int openness : 2; + + friend class TreeView; + friend class TreeViewContentComponent; + + void updatePositions (int newY); + int getIndentX() const throw(); + void setOwnerView (TreeView* const newOwner) throw(); + void paintRecursively (Graphics& g, int width); + TreeViewItem* getTopLevelItem() throw(); + TreeViewItem* findItemRecursively (int y) throw(); + TreeViewItem* getDeepestOpenParentItem() throw(); + int getNumRows() const throw(); + TreeViewItem* getItemOnRow (int index) throw(); + void deselectAllRecursively(); + int countSelectedItemsRecursively() const throw(); + TreeViewItem* getSelectedItemWithIndex (int index) throw(); + TreeViewItem* getNextVisibleItem (const bool recurse) const throw(); + TreeViewItem* findItemFromIdentifierString (const String& identifierString); + + TreeViewItem (const TreeViewItem&); + const TreeViewItem& operator= (const TreeViewItem&); +}; + +/** + A tree-view component. + + Use one of these to hold and display a structure of TreeViewItem objects. + +*/ +class JUCE_API TreeView : public Component, + public SettableTooltipClient, + public FileDragAndDropTarget, + public DragAndDropTarget, + private AsyncUpdater +{ +public: + + /** Creates an empty treeview. + + Once you've got a treeview component, you'll need to give it something to + display, using the setRootItem() method. + */ + TreeView (const String& componentName = String::empty); + + /** Destructor. */ + ~TreeView(); + + /** Sets the item that is displayed in the treeview. + + A tree has a single root item which contains as many sub-items as it needs. If + you want the tree to contain a number of root items, you should still use a single + root item above these, but hide it using setRootItemVisible(). + + You can pass in 0 to this method to clear the tree and remove its current root item. + + The object passed in will not be deleted by the treeview, it's up to the caller + to delete it when no longer needed. BUT make absolutely sure that you don't delete + this item until you've removed it from the tree, either by calling setRootItem (0), + or by deleting the tree first. You can also use deleteRootItem() as a quick way + to delete it. + */ + void setRootItem (TreeViewItem* const newRootItem); + + /** Returns the tree's root item. + + This will be the last object passed to setRootItem(), or 0 if none has been set. + */ + TreeViewItem* getRootItem() const throw() { return rootItem; } + + /** This will remove and delete the current root item. + + It's a convenient way of deleting the item and calling setRootItem (0). + */ + void deleteRootItem(); + + /** Changes whether the tree's root item is shown or not. + + If the root item is hidden, only its sub-items will be shown in the treeview - this + lets you make the tree look as if it's got many root items. If it's hidden, this call + will also make sure the root item is open (otherwise the treeview would look empty). + */ + void setRootItemVisible (const bool shouldBeVisible); + + /** Returns true if the root item is visible. + + @see setRootItemVisible + */ + bool isRootItemVisible() const throw() { return rootItemVisible; } + + /** Sets whether items are open or closed by default. + + Normally, items are closed until the user opens them, but you can use this + to make them default to being open until explicitly closed. + + @see areItemsOpenByDefault + */ + void setDefaultOpenness (const bool isOpenByDefault); + + /** Returns true if the tree's items default to being open. + + @see setDefaultOpenness + */ + bool areItemsOpenByDefault() const throw() { return defaultOpenness; } + + /** This sets a flag to indicate that the tree can be used for multi-selection. + + You can always select multiple items internally by calling the + TreeViewItem::setSelected() method, but this flag indicates whether the user + is allowed to multi-select by clicking on the tree. + + By default it is disabled. + + @see isMultiSelectEnabled + */ + void setMultiSelectEnabled (const bool canMultiSelect); + + /** Returns whether multi-select has been enabled for the tree. + + @see setMultiSelectEnabled + */ + bool isMultiSelectEnabled() const throw() { return multiSelectEnabled; } + + /** Sets a flag to indicate whether to hide the open/close buttons. + + @see areOpenCloseButtonsVisible + */ + void setOpenCloseButtonsVisible (const bool shouldBeVisible); + + /** Returns whether open/close buttons are shown. + + @see setOpenCloseButtonsVisible + */ + bool areOpenCloseButtonsVisible() const throw() { return openCloseButtonsVisible; } + + /** Deselects any items that are currently selected. */ + void clearSelectedItems(); + + /** Returns the number of items that are currently selected. + + @see getSelectedItem, clearSelectedItems + */ + int getNumSelectedItems() const throw(); + + /** Returns one of the selected items in the tree. + + @param index the index, 0 to (getNumSelectedItems() - 1) + */ + TreeViewItem* getSelectedItem (const int index) const throw(); + + /** Returns the number of rows the tree is using. + + This will depend on which items are open. + + @see TreeViewItem::getRowNumberInTree() + */ + int getNumRowsInTree() const; + + /** Returns the item on a particular row of the tree. + + If the index is out of range, this will return 0. + + @see getNumRowsInTree, TreeViewItem::getRowNumberInTree() + */ + TreeViewItem* getItemOnRow (int index) const; + + /** Returns the item that contains a given y position. + The y is relative to the top of the TreeView component. + */ + TreeViewItem* getItemAt (int yPosition) const throw(); + + /** Tries to scroll the tree so that this item is on-screen somewhere. */ + void scrollToKeepItemVisible (TreeViewItem* item); + + /** Returns the treeview's Viewport object. */ + Viewport* getViewport() const throw() { return viewport; } + + /** Returns the number of pixels by which each nested level of the tree is indented. + @see setIndentSize + */ + int getIndentSize() const throw() { return indentSize; } + + /** Changes the distance by which each nested level of the tree is indented. + @see getIndentSize + */ + void setIndentSize (const int newIndentSize); + + /** Searches the tree for an item with the specified identifier. + The identifer string must have been created by calling TreeViewItem::getItemIdentifierString(). + If no such item exists, this will return false. If the item is found, all of its items + will be automatically opened. + */ + TreeViewItem* findItemFromIdentifierString (const String& identifierString) const; + + /** Saves the current state of open/closed nodes so it can be restored later. + + This takes a snapshot of which nodes have been explicitly opened or closed, + and records it as XML. To identify node objects it uses the + TreeViewItem::getUniqueName() method to create named paths. This + means that the same state of open/closed nodes can be restored to a + completely different instance of the tree, as long as it contains nodes + whose unique names are the same. + + The caller is responsible for deleting the object that is returned. + + @param alsoIncludeScrollPosition if this is true, the state will also + include information about where the + tree has been scrolled to vertically, + so this can also be restored + @see restoreOpennessState + */ + XmlElement* getOpennessState (const bool alsoIncludeScrollPosition) const; + + /** Restores a previously saved arrangement of open/closed nodes. + + This will try to restore a snapshot of the tree's state that was created by + the getOpennessState() method. If any of the nodes named in the original + XML aren't present in this tree, they will be ignored. + + @see getOpennessState + */ + void restoreOpennessState (const XmlElement& newState); + + /** A set of colour IDs to use to change the colour of various aspects of the treeview. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x1000500, /**< A background colour to fill the component with. */ + linesColourId = 0x1000501, /**< The colour to draw the lines with.*/ + dragAndDropIndicatorColourId = 0x1000502 /**< The colour to use for the drag-and-drop target position indicator. */ + }; /** @internal */ void paint (Graphics& g); /** @internal */ - void refresh(); + void resized(); /** @internal */ - void buttonClicked (Button*); + bool keyPressed (const KeyPress& key); + /** @internal */ + void colourChanged(); + /** @internal */ + void enablementChanged(); + /** @internal */ + bool isInterestedInFileDrag (const StringArray& files); + /** @internal */ + void fileDragEnter (const StringArray& files, int x, int y); + /** @internal */ + void fileDragMove (const StringArray& files, int x, int y); + /** @internal */ + void fileDragExit (const StringArray& files); + /** @internal */ + void filesDropped (const StringArray& files, int x, int y); + /** @internal */ + bool isInterestedInDragSource (const String& sourceDescription, Component* sourceComponent); + /** @internal */ + void itemDragEnter (const String& sourceDescription, Component* sourceComponent, int x, int y); + /** @internal */ + void itemDragMove (const String& sourceDescription, Component* sourceComponent, int x, int y); + /** @internal */ + void itemDragExit (const String& sourceDescription, Component* sourceComponent); + /** @internal */ + void itemDropped (const String& sourceDescription, Component* sourceComponent, int x, int y); juce_UseDebuggingNewOperator private: - ToggleButton* button; - String onText, offText; + friend class TreeViewItem; + friend class TreeViewContentComponent; + Viewport* viewport; + CriticalSection nodeAlterationLock; + TreeViewItem* rootItem; + Component* dragInsertPointHighlight; + Component* dragTargetGroupHighlight; + int indentSize; + bool defaultOpenness : 1; + bool needsRecalculating : 1; + bool rootItemVisible : 1; + bool multiSelectEnabled : 1; + bool openCloseButtonsVisible : 1; + + void itemsChanged() throw(); + void handleAsyncUpdate(); + void moveSelectedRow (int delta); + void updateButtonUnderMouse (const MouseEvent& e); + void showDragHighlight (TreeViewItem* item, int insertIndex, int x, int y) throw(); + void hideDragHighlight() throw(); + void handleDrag (const StringArray& files, const String& sourceDescription, Component* sourceComponent, int x, int y); + void handleDrop (const StringArray& files, const String& sourceDescription, Component* sourceComponent, int x, int y); + TreeViewItem* getInsertPosition (int& x, int& y, int& insertIndex, + const StringArray& files, const String& sourceDescription, + Component* sourceComponent) const throw(); + + TreeView (const TreeView&); + const TreeView& operator= (const TreeView&); }; -#endif // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_BooleanPropertyComponent.h *********/ +#endif // __JUCE_TREEVIEW_JUCEHEADER__ +/********* End of inlined file: juce_TreeView.h *********/ #endif -#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_ButtonPropertyComponent.h *********/ -#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +#define __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_DirectoryContentsList.h *********/ +#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ +#define __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ + +/********* Start of inlined file: juce_FileFilter.h *********/ +#ifndef __JUCE_FILEFILTER_JUCEHEADER__ +#define __JUCE_FILEFILTER_JUCEHEADER__ /** - A PropertyComponent that contains a button. + Interface for deciding which files are suitable for something. - This type of property component can be used if you need a button to trigger some - kind of action. + For example, this is used by DirectoryContentsList to select which files + go into the list. - @see PropertyComponent + @see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent */ -class JUCE_API ButtonPropertyComponent : public PropertyComponent, - private ButtonListener +class JUCE_API FileFilter { public: - /** Creates a button component. + /** Creates a filter with the given description. - @param propertyName the property name to be passed to the PropertyComponent - @param triggerOnMouseDown this is passed to the Button::setTriggeredOnMouseDown() method + The description can be returned later with the getDescription() method. */ - ButtonPropertyComponent (const String& propertyName, - const bool triggerOnMouseDown); + FileFilter (const String& filterDescription); /** Destructor. */ - ~ButtonPropertyComponent(); + virtual ~FileFilter(); - /** Called when the user clicks the button. + /** Returns the description that the filter was created with. */ + const String& getDescription() const throw(); + + /** Should return true if this file is suitable for inclusion in whatever context + the object is being used. */ - virtual void buttonClicked() = 0; + virtual bool isFileSuitable (const File& file) const = 0; - /** Returns the string that should be displayed in the button. - - If you need to change this string, call refresh() to update the component. + /** Should return true if this directory is suitable for inclusion in whatever context + the object is being used. */ - virtual const String getButtonText() const = 0; + virtual bool isDirectorySuitable (const File& file) const = 0; - /** @internal */ +protected: + + String description; +}; + +#endif // __JUCE_FILEFILTER_JUCEHEADER__ +/********* End of inlined file: juce_FileFilter.h *********/ + +/********* Start of inlined file: juce_Image.h *********/ +#ifndef __JUCE_IMAGE_JUCEHEADER__ +#define __JUCE_IMAGE_JUCEHEADER__ + +/** + Holds a fixed-size bitmap. + + The image is stored in either 24-bit RGB or 32-bit premultiplied-ARGB format. + + To draw into an image, create a Graphics object for it. + e.g. @code + + // create a transparent 500x500 image.. + Image myImage (Image::RGB, 500, 500, true); + + Graphics g (myImage); + g.setColour (Colours::red); + g.fillEllipse (20, 20, 300, 200); // draws a red ellipse in our image. + @endcode + + Other useful ways to create an image are with the ImageCache class, or the + ImageFileFormat, which provides a way to load common image files. + + @see Graphics, ImageFileFormat, ImageCache, ImageConvolutionKernel +*/ +class JUCE_API Image +{ +public: + + enum PixelFormat + { + RGB, /**<< each pixel is a 3-byte packed RGB colour value. For byte order, see the PixelRGB class. */ + ARGB, /**<< each pixel is a 4-byte ARGB premultiplied colour value. For byte order, see the PixelARGB class. */ + SingleChannel /**<< each pixel is a 1-byte alpha channel value. */ + }; + + /** Creates an in-memory image with a specified size and format. + + To create an image that can use native OS rendering methods, see createNativeImage(). + + @param format the number of colour channels in the image + @param imageWidth the desired width of the image, in pixels - this value must be + greater than zero (otherwise a width of 1 will be used) + @param imageHeight the desired width of the image, in pixels - this value must be + greater than zero (otherwise a height of 1 will be used) + @param clearImage if true, the image will initially be cleared to black or transparent + black. If false, the image may contain random data, and the + user will have to deal with this + */ + Image (const PixelFormat format, + const int imageWidth, + const int imageHeight, + const bool clearImage); + + /** Creates a copy of another image. + + @see createCopy + */ + Image (const Image& other); + + /** Destructor. */ + virtual ~Image(); + + /** Tries to create an image that is uses native drawing methods when you render + onto it. + + On some platforms this will just return a normal software-based image. + */ + static Image* createNativeImage (const PixelFormat format, + const int imageWidth, + const int imageHeight, + const bool clearImage); + + /** Returns the image's width (in pixels). */ + int getWidth() const throw() { return imageWidth; } + + /** Returns the image's height (in pixels). */ + int getHeight() const throw() { return imageHeight; } + + /** Returns a rectangle with the same size as this image. + The rectangle is always at position (0, 0). + */ + const Rectangle getBounds() const throw() { return Rectangle (0, 0, imageWidth, imageHeight); } + + /** Returns the image's pixel format. */ + PixelFormat getFormat() const throw() { return format; } + + /** True if the image's format is ARGB. */ + bool isARGB() const throw() { return format == ARGB; } + + /** True if the image's format is RGB. */ + bool isRGB() const throw() { return format == RGB; } + + /** True if the image contains an alpha-channel. */ + bool hasAlphaChannel() const throw() { return format != RGB; } + + /** Clears a section of the image with a given colour. + + This won't do any alpha-blending - it just sets all pixels in the image to + the given colour (which may be non-opaque if the image has an alpha channel). + */ + virtual void clear (int x, int y, int w, int h, + const Colour& colourToClearTo = Colour (0x00000000)); + + /** Returns a new image that's a copy of this one. + + A new size for the copied image can be specified, or values less than + zero can be passed-in to use the image's existing dimensions. + + It's up to the caller to delete the image when no longer needed. + */ + virtual Image* createCopy (int newWidth = -1, + int newHeight = -1, + const Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const; + + /** Returns a new single-channel image which is a copy of the alpha-channel of this image. + */ + virtual Image* createCopyOfAlphaChannel() const; + + /** Returns the colour of one of the pixels in the image. + + If the co-ordinates given are beyond the image's boundaries, this will + return Colours::transparentBlack. + + (0, 0) is the image's top-left corner. + + @see getAlphaAt, setPixelAt, blendPixelAt + */ + virtual const Colour getPixelAt (const int x, const int y) const; + + /** Sets the colour of one of the image's pixels. + + If the co-ordinates are beyond the image's boundaries, then nothing will + happen. + + Note that unlike blendPixelAt(), this won't do any alpha-blending, it'll + just replace the existing pixel with the given one. The colour's opacity + will be ignored if this image doesn't have an alpha-channel. + + (0, 0) is the image's top-left corner. + + @see blendPixelAt + */ + virtual void setPixelAt (const int x, const int y, const Colour& colour); + + /** Changes the opacity of a pixel. + + This only has an effect if the image has an alpha channel and if the + given co-ordinates are inside the image's boundary. + + The multiplier must be in the range 0 to 1.0, and the current alpha + at the given co-ordinates will be multiplied by this value. + + @see getAlphaAt, setPixelAt + */ + virtual void multiplyAlphaAt (const int x, const int y, const float multiplier); + + /** Changes the overall opacity of the image. + + This will multiply the alpha value of each pixel in the image by the given + amount (limiting the resulting alpha values between 0 and 255). This allows + you to make an image more or less transparent. + + If the image doesn't have an alpha channel, this won't have any effect. + */ + virtual void multiplyAllAlphas (const float amountToMultiplyBy); + + /** Changes all the colours to be shades of grey, based on their current luminosity. + */ + virtual void desaturate(); + + /** Retrieves a section of an image as raw pixel data, so it can be read or written to. + + You should only use this class as a last resort - messing about with the internals of + an image is only recommended for people who really know what they're doing! + + A BitmapData object should be used as a temporary, stack-based object. Don't keep one + hanging around while the image is being used elsewhere. + + Depending on the way the image class is implemented, this may create a temporary buffer + which is copied back to the image when the object is deleted, or it may just get a pointer + directly into the image's raw data. + + You can use the stride and data values in this class directly, but don't alter them! + The actual format of the pixel data depends on the image's format - see Image::getFormat(), + and the PixelRGB, PixelARGB and PixelAlpha classes for more info. + */ + class BitmapData + { + public: + BitmapData (Image& image, int x, int y, int w, int h, const bool needsToBeWritable) throw(); + BitmapData (const Image& image, int x, int y, int w, int h) throw(); + ~BitmapData() throw(); + + /** Returns a pointer to the start of a line in the image. + The co-ordinate you provide here isn't checked, so it's the caller's responsibility to make + sure it's not out-of-range. + */ + inline uint8* getLinePointer (const int y) const throw() { return data + y * lineStride; } + + /** Returns a pointer to a pixel in the image. + The co-ordinates you give here are not checked, so it's the caller's responsibility to make sure they're + not out-of-range. + */ + inline uint8* getPixelPointer (const int x, const int y) const throw() { return data + y * lineStride + x * pixelStride; } + + uint8* data; + int lineStride, pixelStride, width, height; + + private: + BitmapData (const BitmapData&); + const BitmapData& operator= (const BitmapData&); + }; + + /** Copies some pixel values to a rectangle of the image. + + The format of the pixel data must match that of the image itself, and the + rectangle supplied must be within the image's bounds. + */ + virtual void setPixelData (int destX, int destY, int destW, int destH, + const uint8* sourcePixelData, int sourceLineStride); + + /** Copies a section of the image to somewhere else within itself. + */ + virtual void moveImageSection (int destX, int destY, + int sourceX, int sourceY, + int width, int height); + + /** Creates a RectangleList containing rectangles for all non-transparent pixels + of the image. + + @param result the list that will have the area added to it + @param alphaThreshold for a semi-transparent image, any pixels whose alpha is + above this level will be considered opaque + */ + void createSolidAreaMask (RectangleList& result, + const float alphaThreshold = 0.5f) const; + + juce_UseDebuggingNewOperator + + /** Creates a context suitable for drawing onto this image. + + Don't call this method directly! It's used internally by the Graphics class. + */ + virtual LowLevelGraphicsContext* createLowLevelContext(); + +protected: + friend class BitmapData; + const PixelFormat format; + const int imageWidth, imageHeight; + + /** Used internally so that subclasses can call a constructor that doesn't allocate memory */ + Image (const PixelFormat format, + const int imageWidth, + const int imageHeight); + + int pixelStride, lineStride; + HeapBlock imageDataAllocated; + uint8* imageData; + +private: + + const Image& operator= (const Image&); +}; + +#endif // __JUCE_IMAGE_JUCEHEADER__ +/********* End of inlined file: juce_Image.h *********/ + +/** + A class to asynchronously scan for details about the files in a directory. + + This keeps a list of files and some information about them, using a background + thread to scan for more files. As files are found, it broadcasts change messages + to tell any listeners. + + @see FileListComponent, FileBrowserComponent +*/ +class JUCE_API DirectoryContentsList : public ChangeBroadcaster, + public TimeSliceClient +{ +public: + + /** Creates a directory list. + + To set the directory it should point to, use setDirectory(), which will + also start it scanning for files on the background thread. + + When the background thread finds and adds new files to this list, the + ChangeBroadcaster class will send a change message, so you can register + listeners and update them when the list changes. + + @param fileFilter an optional filter to select which files are + included in the list. If this is 0, then all files + and directories are included. Make sure that the + filter doesn't get deleted during the lifetime of this + object + @param threadToUse a thread object that this list can use + to scan for files as a background task. Make sure + that the thread you give it has been started, or you + won't get any files! + */ + DirectoryContentsList (const FileFilter* const fileFilter, + TimeSliceThread& threadToUse); + + /** Destructor. */ + ~DirectoryContentsList(); + + /** Sets the directory to look in for files. + + If the directory that's passed in is different to the current one, this will + also start the background thread scanning it for files. + */ + void setDirectory (const File& directory, + const bool includeDirectories, + const bool includeFiles); + + /** Returns the directory that's currently being used. */ + const File& getDirectory() const throw(); + + /** Clears the list, and stops the thread scanning for files. */ + void clear(); + + /** Clears the list and restarts scanning the directory for files. */ void refresh(); + + /** True if the background thread hasn't yet finished scanning for files. */ + bool isStillLoading() const; + + /** Tells the list whether or not to ignore hidden files. + + By default these are ignored. + */ + void setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles); + + /** Returns true if hidden files are ignored. + @see setIgnoresHiddenFiles + */ + bool ignoresHiddenFiles() const throw() { return ignoreHiddenFiles; } + + /** Contains cached information about one of the files in a DirectoryContentsList. + */ + struct FileInfo + { + + /** The filename. + + This isn't a full pathname, it's just the last part of the path, same as you'd + get from File::getFileName(). + + To get the full pathname, use DirectoryContentsList::getDirectory().getChildFile (filename). + */ + String filename; + + /** File size in bytes. */ + int64 fileSize; + + /** File modification time. + + As supplied by File::getLastModificationTime(). + */ + Time modificationTime; + + /** File creation time. + + As supplied by File::getCreationTime(). + */ + Time creationTime; + + /** True if the file is a directory. */ + bool isDirectory; + + /** True if the file is read-only. */ + bool isReadOnly; + }; + + /** Returns the number of files currently available in the list. + + The info about one of these files can be retrieved with getFileInfo() or + getFile(). + + Obviously as the background thread runs and scans the directory for files, this + number will change. + + @see getFileInfo, getFile + */ + int getNumFiles() const; + + /** Returns the cached information about one of the files in the list. + + If the index is in-range, this will return true and will copy the file's details + to the structure that is passed-in. + + If it returns false, then the index wasn't in range, and the structure won't + be affected. + + @see getNumFiles, getFile + */ + bool getFileInfo (const int index, + FileInfo& resultInfo) const; + + /** Returns one of the files in the list. + + @param index should be less than getNumFiles(). If this is out-of-range, the + return value will be File::nonexistent + @see getNumFiles, getFileInfo + */ + const File getFile (const int index) const; + + /** Returns the file filter being used. + + The filter is specified in the constructor. + */ + const FileFilter* getFilter() const throw() { return fileFilter; } + /** @internal */ - void buttonClicked (Button*); + bool useTimeSlice(); + /** @internal */ + TimeSliceThread& getTimeSliceThread() throw() { return thread; } + /** @internal */ + static int compareElements (const DirectoryContentsList::FileInfo* const first, + const DirectoryContentsList::FileInfo* const second) throw(); juce_UseDebuggingNewOperator private: - TextButton* button; + File root; + const FileFilter* fileFilter; + TimeSliceThread& thread; + bool includeDirectories, includeFiles, ignoreHiddenFiles; + + CriticalSection fileListLock; + OwnedArray files; + + void* volatile fileFindHandle; + bool volatile shouldStop; + + void changed(); + bool checkNextFile (bool& hasChanged); + bool addFile (const String& filename, const bool isDir, const bool isHidden, + const int64 fileSize, const Time& modTime, + const Time& creationTime, const bool isReadOnly); + + DirectoryContentsList (const DirectoryContentsList&); + const DirectoryContentsList& operator= (const DirectoryContentsList&); }; -#endif // __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ButtonPropertyComponent.h *********/ +#endif // __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ +/********* End of inlined file: juce_DirectoryContentsList.h *********/ -#endif -#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_ChoicePropertyComponent.h *********/ -#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_FileBrowserListener.h *********/ +#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ +#define __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ /** - A PropertyComponent that shows its value as a combo box. + A listener for user selection events in a file browser. - This type of property component contains a list of options and has a - combo box to choose one. - - Your subclass's constructor must add some strings to the choices StringArray - and these are shown in the list. - - The getIndex() method will be called to find out which option is the currently - selected one. If you call refresh() it will call getIndex() to check whether - the value has changed, and will update the combo box if needed. - - If the user selects a different item from the list, setIndex() will be - called to let your class process this. - - @see PropertyComponent, PropertyPanel + This is used by a FileBrowserComponent or FileListComponent. */ -class JUCE_API ChoicePropertyComponent : public PropertyComponent, - private ComboBoxListener +class JUCE_API FileBrowserListener { public: - /** Creates the component. - - Your subclass's constructor must add a list of options to the choices - member variable. - */ - ChoicePropertyComponent (const String& propertyName); /** Destructor. */ - ~ChoicePropertyComponent(); + virtual ~FileBrowserListener(); - /** Called when the user selects an item from the combo box. + /** Callback when the user selects a different file in the browser. */ + virtual void selectionChanged() = 0; - Your subclass must use this callback to update the value that this component - represents. The index is the index of the chosen item in the choices - StringArray. + /** Callback when the user clicks on a file in the browser. */ + virtual void fileClicked (const File& file, const MouseEvent& e) = 0; + + /** Callback when the user double-clicks on a file in the browser. */ + virtual void fileDoubleClicked (const File& file) = 0; +}; + +#endif // __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ +/********* End of inlined file: juce_FileBrowserListener.h *********/ + +/** + A base class for components that display a list of the files in a directory. + + @see DirectoryContentsList +*/ +class JUCE_API DirectoryContentsDisplayComponent +{ +public: + + /** */ - virtual void setIndex (const int newIndex) = 0; + DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow); - /** Returns the index of the item that should currently be shown. + /** Destructor. */ + virtual ~DirectoryContentsDisplayComponent(); - This is the index of the item in the choices StringArray that will be - shown. + /** Returns the number of files the user has got selected. + @see getSelectedFile */ - virtual int getIndex() const = 0; + virtual int getNumSelectedFiles() const = 0; - /** Returns the list of options. */ - const StringArray& getChoices() const throw(); + /** Returns one of the files that the user has currently selected. + The index should be in the range 0 to (getNumSelectedFiles() - 1). + @see getNumSelectedFiles + */ + virtual const File getSelectedFile (int index) const = 0; + + /** Scrolls this view to the top. */ + virtual void scrollToTop() = 0; + + /** Adds a listener to be told when files are selected or clicked. + + @see removeListener + */ + void addListener (FileBrowserListener* const listener) throw(); + + /** Removes a listener. + + @see addListener + */ + void removeListener (FileBrowserListener* const listener) throw(); + + /** A set of colour IDs to use to change the colour of various aspects of the label. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + Note that you can also use the constants from TextEditor::ColourIds to change the + colour of the text editor that is opened when a label is editable. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */ + textColourId = 0x1000541, /**< The colour for the text. */ + }; /** @internal */ - void refresh(); + void sendSelectionChangeMessage(); /** @internal */ - void comboBoxChanged (ComboBox*); + void sendDoubleClickMessage (const File& file); + /** @internal */ + void sendMouseClickMessage (const File& file, const MouseEvent& e); juce_UseDebuggingNewOperator protected: - /** The list of options that will be shown in the combo box. + DirectoryContentsList& fileList; + SortedSet listeners; - Your subclass must populate this array in its constructor. If any empty - strings are added, these will be replaced with horizontal separators (see - ComboBox::addSeparator() for more info). - */ - StringArray choices; - -private: - ComboBox* comboBox; + DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); + const DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); }; -#endif // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ChoicePropertyComponent.h *********/ +#endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ #endif -#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ +#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ #endif -#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -#endif -#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_FileBrowserComponent.h *********/ +#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ +#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_SliderPropertyComponent.h *********/ -#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ +/********* Start of inlined file: juce_FilePreviewComponent.h *********/ +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ /** - A PropertyComponent that shows its value as a slider. + Base class for components that live inside a file chooser dialog box and + show previews of the files that get selected. - @see PropertyComponent, Slider + One of these allows special extra information to be displayed for files + in a dialog box as the user selects them. Each time the current file or + directory is changed, the selectedFileChanged() method will be called + to allow it to update itself appropriately. + + @see FileChooser, ImagePreviewComponent */ -class JUCE_API SliderPropertyComponent : public PropertyComponent, - private SliderListener +class JUCE_API FilePreviewComponent : public Component { public: - /** Creates the property component. - - The ranges, interval and skew factor are passed to the Slider component. - - If you need to customise the slider in other ways, your constructor can - access the slider member variable and change it directly. - */ - SliderPropertyComponent (const String& propertyName, - const double rangeMin, - const double rangeMax, - const double interval, - const double skewFactor = 1.0); + /** Creates a FilePreviewComponent. */ + FilePreviewComponent(); /** Destructor. */ - ~SliderPropertyComponent(); + ~FilePreviewComponent(); - /** Called when the user moves the slider to change its value. + /** Called to indicate that the user's currently selected file has changed. - Your subclass must use this method to update whatever item this property - represents. + @param newSelectedFile the newly selected file or directory, which may be + File::nonexistent if none is selected. */ - virtual void setValue (const double newValue) = 0; + virtual void selectedFileChanged (const File& newSelectedFile) = 0; - /** Returns the value that the slider should show. */ - virtual const double getValue() const = 0; + juce_UseDebuggingNewOperator + +private: + FilePreviewComponent (const FilePreviewComponent&); + const FilePreviewComponent& operator= (const FilePreviewComponent&); +}; + +#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FilePreviewComponent.h *********/ + +/** + A component for browsing and selecting a file or directory to open or save. + + This contains a FileListComponent and adds various boxes and controls for + navigating and selecting a file. It can work in different modes so that it can + be used for loading or saving a file, or for choosing a directory. + + @see FileChooserDialogBox, FileChooser, FileListComponent +*/ +class JUCE_API FileBrowserComponent : public Component, + public ChangeBroadcaster, + private FileBrowserListener, + private TextEditorListener, + private ButtonListener, + private ComboBoxListener, + private FileFilter +{ +public: + + /** Various options for the browser. + + A combination of these is passed into the FileBrowserComponent constructor. + */ + enum FileChooserFlags + { + openMode = 1, /**< specifies that the component should allow the user to + choose an existing file with the intention of opening it. */ + saveMode = 2, /**< specifies that the component should allow the user to specify + the name of a file that will be used to save something. */ + canSelectFiles = 4, /**< specifies that the user can select files (can be used in + conjunction with canSelectDirectories). */ + canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in + conjuction with canSelectFiles). */ + canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */ + useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */ + filenameBoxIsReadOnly = 64 /**< specifies that the user can't type directly into the filename box. */ + }; + + /** Creates a FileBrowserComponent. + + @param flags A combination of flags from the FileChooserFlags enumeration, + used to specify the component's behaviour. The flags must contain + either openMode or saveMode, and canSelectFiles and/or + canSelectDirectories. + @param initialFileOrDirectory The file or directory that should be selected when + the component begins. If this is File::nonexistent, + a default directory will be chosen. + @param fileFilter an optional filter to use to determine which files + are shown. If this is 0 then all files are displayed. Note + that a pointer is kept internally to this object, so + make sure that it is not deleted before the browser object + is deleted. + @param previewComp an optional preview component that will be used to + show previews of files that the user selects + */ + FileBrowserComponent (int flags, + const File& initialFileOrDirectory, + const FileFilter* fileFilter, + FilePreviewComponent* previewComp); + + /** Destructor. */ + ~FileBrowserComponent(); + + /** Returns the number of files that the user has got selected. + If multiple select isn't active, this will only be 0 or 1. To get the complete + list of files they've chosen, pass an index to getCurrentFile(). + */ + int getNumSelectedFiles() const throw(); + + /** Returns one of the files that the user has chosen. + If the box has multi-select enabled, the index lets you specify which of the files + to get - see getNumSelectedFiles() to find out how many files were chosen. + @see getHighlightedFile + */ + const File getSelectedFile (int index) const throw(); + + /** Returns true if the currently selected file(s) are usable. + + This can be used to decide whether the user can press "ok" for the + current file. What it does depends on the mode, so for example in an "open" + mode, this only returns true if a file has been selected and if it exists. + In a "save" mode, a non-existent file would also be valid. + */ + bool currentFileIsValid() const; + + /** This returns the last item in the view that the user has highlighted. + This may be different from getCurrentFile(), which returns the value + that is shown in the filename box, and if there are multiple selections, + this will only return one of them. + @see getCurrentFile + */ + const File getHighlightedFile() const throw(); + + /** Returns the directory whose contents are currently being shown in the listbox. */ + const File getRoot() const; + + /** Changes the directory that's being shown in the listbox. */ + void setRoot (const File& newRootDirectory); + + /** Equivalent to pressing the "up" button to browse the parent directory. */ + void goUp(); + + /** Refreshes the directory that's currently being listed. */ + void refresh(); + + /** Returns a verb to describe what should happen when the file is accepted. + + E.g. if browsing in "load file" mode, this will be "Open", if in "save file" + mode, it'll be "Save", etc. + */ + virtual const String getActionVerb() const; + + /** Returns true if the saveMode flag was set when this component was created. + */ + bool isSaveMode() const throw(); + + /** Adds a listener to be told when the user selects and clicks on files. + + @see removeListener + */ + void addListener (FileBrowserListener* const listener) throw(); + + /** Removes a listener. + + @see addListener + */ + void removeListener (FileBrowserListener* const listener) throw(); /** @internal */ - void refresh(); + void resized(); + /** @internal */ + void buttonClicked (Button* b); + /** @internal */ + void comboBoxChanged (ComboBox*); + /** @internal */ + void textEditorTextChanged (TextEditor& editor); + /** @internal */ + void textEditorReturnKeyPressed (TextEditor& editor); + /** @internal */ + void textEditorEscapeKeyPressed (TextEditor& editor); + /** @internal */ + void textEditorFocusLost (TextEditor& editor); + /** @internal */ + bool keyPressed (const KeyPress& key); + /** @internal */ + void selectionChanged(); + /** @internal */ + void fileClicked (const File& f, const MouseEvent& e); + /** @internal */ + void fileDoubleClicked (const File& f); + /** @internal */ + bool isFileSuitable (const File& file) const; + /** @internal */ + bool isDirectorySuitable (const File&) const; + + /** @internal */ + FilePreviewComponent* getPreviewComponent() const throw(); + + juce_UseDebuggingNewOperator + +protected: + virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths); + +private: + + DirectoryContentsList* fileList; + const FileFilter* fileFilter; + + int flags; + File currentRoot; + OwnedArray chosenFiles; + SortedSet listeners; + + DirectoryContentsDisplayComponent* fileListComponent; + FilePreviewComponent* previewComp; + ComboBox* currentPathBox; + TextEditor* filenameBox; + Button* goUpButton; + + TimeSliceThread thread; + + void sendListenerChangeMessage(); + bool isFileOrDirSuitable (const File& f) const; + + FileBrowserComponent (const FileBrowserComponent&); + const FileBrowserComponent& operator= (const FileBrowserComponent&); +}; + +#endif // __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileBrowserComponent.h *********/ + +#endif +#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ + +/********* Start of inlined file: juce_FileChooser.h *********/ +#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ +#define __JUCE_FILECHOOSER_JUCEHEADER__ + +/** + Creates a dialog box to choose a file or directory to load or save. + + To use a FileChooser: + - create one (as a local stack variable is the neatest way) + - call one of its browseFor.. methods + - if this returns true, the user has selected a file, so you can retrieve it + with the getResult() method. + + e.g. @code + void loadMooseFile() + { + FileChooser myChooser ("Please select the moose you want to load...", + File::getSpecialLocation (File::userHomeDirectory), + "*.moose"); + + if (myChooser.browseForFileToOpen()) + { + File mooseFile (myChooser.getResult()); + + loadMoose (mooseFile); + } + } + @endcode +*/ +class JUCE_API FileChooser +{ +public: + + /** Creates a FileChooser. + + After creating one of these, use one of the browseFor... methods to display it. + + @param dialogBoxTitle a text string to display in the dialog box to + tell the user what's going on + @param initialFileOrDirectory the file or directory that should be selected when + the dialog box opens. If this parameter is set to + File::nonexistent, a sensible default directory + will be used instead. + @param filePatternsAllowed a set of file patterns to specify which files can be + selected - each pattern should be separated by a + comma or semi-colon, e.g. "*" or "*.jpg;*.gif". An + empty string means that all files are allowed + @param useOSNativeDialogBox if true, then a native dialog box will be used if + possible; if false, then a Juce-based browser dialog + box will always be used + @see browseForFileToOpen, browseForFileToSave, browseForDirectory + */ + FileChooser (const String& dialogBoxTitle, + const File& initialFileOrDirectory = File::nonexistent, + const String& filePatternsAllowed = String::empty, + const bool useOSNativeDialogBox = true); + + /** Destructor. */ + ~FileChooser(); + + /** Shows a dialog box to choose a file to open. + + This will display the dialog box modally, using an "open file" mode, so that + it won't allow non-existent files or directories to be chosen. + + @param previewComponent an optional component to display inside the dialog + box to show special info about the files that the user + is browsing. The component will not be deleted by this + object, so the caller must take care of it. + @returns true if the user selected a file, in which case, use the getResult() + method to find out what it was. Returns false if they cancelled instead. + @see browseForFileToSave, browseForDirectory + */ + bool browseForFileToOpen (FilePreviewComponent* previewComponent = 0); + + /** Same as browseForFileToOpen, but allows the user to select multiple files. + + The files that are returned can be obtained by calling getResults(). See + browseForFileToOpen() for more info about the behaviour of this method. + */ + bool browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent = 0); + + /** Shows a dialog box to choose a file to save. + + This will display the dialog box modally, using an "save file" mode, so it + will allow non-existent files to be chosen, but not directories. + + @param warnAboutOverwritingExistingFiles if true, the dialog box will ask + the user if they're sure they want to overwrite a file that already + exists + @returns true if the user chose a file and pressed 'ok', in which case, use + the getResult() method to find out what the file was. Returns false + if they cancelled instead. + @see browseForFileToOpen, browseForDirectory + */ + bool browseForFileToSave (const bool warnAboutOverwritingExistingFiles); + + /** Shows a dialog box to choose a directory. + + This will display the dialog box modally, using an "open directory" mode, so it + will only allow directories to be returned, not files. + + @returns true if the user chose a directory and pressed 'ok', in which case, use + the getResult() method to find out what they chose. Returns false + if they cancelled instead. + @see browseForFileToOpen, browseForFileToSave + */ + bool browseForDirectory(); + + /** Same as browseForFileToOpen, but allows the user to select multiple files and directories. + + The files that are returned can be obtained by calling getResults(). See + browseForFileToOpen() for more info about the behaviour of this method. + */ + bool browseForMultipleFilesOrDirectories (FilePreviewComponent* previewComponent = 0); + + /** Returns the last file that was chosen by one of the browseFor methods. + + After calling the appropriate browseFor... method, this method lets you + find out what file or directory they chose. + + Note that the file returned is only valid if the browse method returned true (i.e. + if the user pressed 'ok' rather than cancelling). + + If you're using a multiple-file select, then use the getResults() method instead, + to obtain the list of all files chosen. + + @see getResults + */ + const File getResult() const; + + /** Returns a list of all the files that were chosen during the last call to a + browse method. + + This array may be empty if no files were chosen, or can contain multiple entries + if multiple files were chosen. + + @see getResult + */ + const OwnedArray & getResults() const; + + juce_UseDebuggingNewOperator + +private: + String title, filters; + File startingFile; + OwnedArray results; + bool useNativeDialogBox; + + bool showDialog (const bool selectsDirectories, + const bool selectsFiles, + const bool isSave, + const bool warnAboutOverwritingExistingFiles, + const bool selectMultipleFiles, + FilePreviewComponent* const previewComponent); + + static void showPlatformDialog (OwnedArray& results, + const String& title, + const File& file, + const String& filters, + bool selectsDirectories, + bool selectsFiles, + bool isSave, + bool warnAboutOverwritingExistingFiles, + bool selectMultipleFiles, + FilePreviewComponent* previewComponent); +}; + +#endif // __JUCE_FILECHOOSER_JUCEHEADER__ +/********* End of inlined file: juce_FileChooser.h *********/ + +#endif +#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ + +/********* Start of inlined file: juce_FileChooserDialogBox.h *********/ +#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ +#define __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ + +/********* Start of inlined file: juce_ResizableWindow.h *********/ +#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ +#define __JUCE_RESIZABLEWINDOW_JUCEHEADER__ + +/********* Start of inlined file: juce_TopLevelWindow.h *********/ +#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ +#define __JUCE_TOPLEVELWINDOW_JUCEHEADER__ + +/********* Start of inlined file: juce_DropShadower.h *********/ +#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__ +#define __JUCE_DROPSHADOWER_JUCEHEADER__ + +/** + Adds a drop-shadow to a component. + + This object creates and manages a set of components which sit around a + component, creating a gaussian shadow around it. The components will track + the position of the component and if it's brought to the front they'll also + follow this. + + For desktop windows you don't need to use this class directly - just + set the Component::windowHasDropShadow flag when calling + Component::addToDesktop(), and the system will create one of these if it's + needed (which it obviously isn't on the Mac, for example). +*/ +class JUCE_API DropShadower : public ComponentListener +{ +public: + + /** Creates a DropShadower. + + @param alpha the opacity of the shadows, from 0 to 1.0 + @param xOffset the horizontal displacement of the shadow, in pixels + @param yOffset the vertical displacement of the shadow, in pixels + @param blurRadius the radius of the blur to use for creating the shadow + */ + DropShadower (const float alpha = 0.5f, + const int xOffset = 1, + const int yOffset = 5, + const float blurRadius = 10.0f); + + /** Destructor. */ + virtual ~DropShadower(); + + /** Attaches the DropShadower to the component you want to shadow. */ + void setOwner (Component* componentToFollow); + + /** @internal */ + void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); + /** @internal */ + void componentBroughtToFront (Component& component); + /** @internal */ + void componentChildrenChanged (Component& component); + /** @internal */ + void componentParentHierarchyChanged (Component& component); + /** @internal */ + void componentVisibilityChanged (Component& component); + + juce_UseDebuggingNewOperator + +private: + + Component* owner; + int numShadows; + Component* shadowWindows[4]; + Image* shadowImageSections[12]; + const int shadowEdge, xOffset, yOffset; + const float alpha, blurRadius; + bool inDestructor, reentrant; + + void updateShadows(); + void setShadowImage (Image* const src, + const int num, + const int w, const int h, + const int sx, const int sy) throw(); + + void bringShadowWindowsToFront(); + void deleteShadowWindows(); + + DropShadower (const DropShadower&); + const DropShadower& operator= (const DropShadower&); +}; + +#endif // __JUCE_DROPSHADOWER_JUCEHEADER__ +/********* End of inlined file: juce_DropShadower.h *********/ + +/** + A base class for top-level windows. + + This class is used for components that are considered a major part of your + application - e.g. ResizableWindow, DocumentWindow, DialogWindow, AlertWindow, + etc. Things like menus that pop up briefly aren't derived from it. + + A TopLevelWindow is probably on the desktop, but this isn't mandatory - it + could itself be the child of another component. + + The class manages a list of all instances of top-level windows that are in use, + and each one is also given the concept of being "active". The active window is + one that is actively being used by the user. This isn't quite the same as the + component with the keyboard focus, because there may be a popup menu or other + temporary window which gets keyboard focus while the active top level window is + unchanged. + + A top-level window also has an optional drop-shadow. + + @see ResizableWindow, DocumentWindow, DialogWindow +*/ +class JUCE_API TopLevelWindow : public Component +{ +public: + + /** Creates a TopLevelWindow. + + @param name the name to give the component + @param addToDesktop if true, the window will be automatically added to the + desktop; if false, you can use it as a child component + */ + TopLevelWindow (const String& name, + const bool addToDesktop); + + /** Destructor. */ + ~TopLevelWindow(); + + /** True if this is currently the TopLevelWindow that is actively being used. + + This isn't quite the same as having keyboard focus, because the focus may be + on a child component or a temporary pop-up menu, etc, while this window is + still considered to be active. + + @see activeWindowStatusChanged + */ + bool isActiveWindow() const throw() { return windowIsActive_; } + + /** This will set the bounds of the window so that it's centred in front of another + window. + + If your app has a few windows open and want to pop up a dialog box for one of + them, you can use this to show it in front of the relevent parent window, which + is a bit neater than just having it appear in the middle of the screen. + + If componentToCentreAround is 0, then the currently active TopLevelWindow will + be used instead. If no window is focused, it'll just default to the middle of the + screen. + */ + void centreAroundComponent (Component* componentToCentreAround, + const int width, const int height); + + /** Turns the drop-shadow on and off. */ + void setDropShadowEnabled (const bool useShadow); + + /** Sets whether an OS-native title bar will be used, or a Juce one. + + @see isUsingNativeTitleBar + */ + void setUsingNativeTitleBar (const bool useNativeTitleBar); + + /** Returns true if the window is currently using an OS-native title bar. + + @see setUsingNativeTitleBar + */ + bool isUsingNativeTitleBar() const throw() { return useNativeTitleBar && isOnDesktop(); } + + /** Returns the number of TopLevelWindow objects currently in use. + + @see getTopLevelWindow + */ + static int getNumTopLevelWindows() throw(); + + /** Returns one of the TopLevelWindow objects currently in use. + + The index is 0 to (getNumTopLevelWindows() - 1). + */ + static TopLevelWindow* getTopLevelWindow (const int index) throw(); + + /** Returns the currently-active top level window. + + There might not be one, of course, so this can return 0. + */ + static TopLevelWindow* getActiveTopLevelWindow() throw(); + + juce_UseDebuggingNewOperator + + /** @internal */ + virtual void addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo = 0); + +protected: + + /** This callback happens when this window becomes active or inactive. + + @see isActiveWindow + */ + virtual void activeWindowStatusChanged(); + + /** @internal */ + void focusOfChildComponentChanged (FocusChangeType cause); + /** @internal */ + void parentHierarchyChanged(); + /** @internal */ + void visibilityChanged(); + /** @internal */ + virtual int getDesktopWindowStyleFlags() const; + /** @internal */ + void recreateDesktopWindow(); + +private: + friend class TopLevelWindowManager; + bool useDropShadow, useNativeTitleBar, windowIsActive_; + DropShadower* shadower; + + void setWindowActive (const bool isNowActive) throw(); + + TopLevelWindow (const TopLevelWindow&); + const TopLevelWindow& operator= (const TopLevelWindow&); +}; + +#endif // __JUCE_TOPLEVELWINDOW_JUCEHEADER__ +/********* End of inlined file: juce_TopLevelWindow.h *********/ + +/********* Start of inlined file: juce_ComponentDragger.h *********/ +#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ +#define __JUCE_COMPONENTDRAGGER_JUCEHEADER__ + +/********* Start of inlined file: juce_ComponentBoundsConstrainer.h *********/ +#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ +#define __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ + +/** + A class that imposes restrictions on a Component's size or position. + + This is used by classes such as ResizableCornerComponent, + ResizableBorderComponent and ResizableWindow. + + The base class can impose some basic size and position limits, but you can + also subclass this for custom uses. + + @see ResizableCornerComponent, ResizableBorderComponent, ResizableWindow +*/ +class JUCE_API ComponentBoundsConstrainer +{ +public: + + /** When first created, the object will not impose any restrictions on the components. */ + ComponentBoundsConstrainer() throw(); + + /** Destructor. */ + virtual ~ComponentBoundsConstrainer(); + + /** Imposes a minimum width limit. */ + void setMinimumWidth (const int minimumWidth) throw(); + + /** Returns the current minimum width. */ + int getMinimumWidth() const throw() { return minW; } + + /** Imposes a maximum width limit. */ + void setMaximumWidth (const int maximumWidth) throw(); + + /** Returns the current maximum width. */ + int getMaximumWidth() const throw() { return maxW; } + + /** Imposes a minimum height limit. */ + void setMinimumHeight (const int minimumHeight) throw(); + + /** Returns the current minimum height. */ + int getMinimumHeight() const throw() { return minH; } + + /** Imposes a maximum height limit. */ + void setMaximumHeight (const int maximumHeight) throw(); + + /** Returns the current maximum height. */ + int getMaximumHeight() const throw() { return maxH; } + + /** Imposes a minimum width and height limit. */ + void setMinimumSize (const int minimumWidth, + const int minimumHeight) throw(); + + /** Imposes a maximum width and height limit. */ + void setMaximumSize (const int maximumWidth, + const int maximumHeight) throw(); + + /** Set all the maximum and minimum dimensions. */ + void setSizeLimits (const int minimumWidth, + const int minimumHeight, + const int maximumWidth, + const int maximumHeight) throw(); + + /** Sets the amount by which the component is allowed to go off-screen. + + The values indicate how many pixels must remain on-screen when dragged off + one of its parent's edges, so e.g. if minimumWhenOffTheTop is set to 10, then + when the component goes off the top of the screen, its y-position will be + clipped so that there are always at least 10 pixels on-screen. In other words, + the lowest y-position it can take would be (10 - the component's height). + + If you pass 0 or less for one of these amounts, the component is allowed + to move beyond that edge completely, with no restrictions at all. + + If you pass a very large number (i.e. larger that the dimensions of the + component itself), then the component won't be allowed to overlap that + edge at all. So e.g. setting minimumWhenOffTheLeft to 0xffffff will mean that + the component will bump into the left side of the screen and go no further. + */ + void setMinimumOnscreenAmounts (const int minimumWhenOffTheTop, + const int minimumWhenOffTheLeft, + const int minimumWhenOffTheBottom, + const int minimumWhenOffTheRight) throw(); + + /** Specifies a width-to-height ratio that the resizer should always maintain. + + If the value is 0, no aspect ratio is enforced. If it's non-zero, the width + will always be maintained as this multiple of the height. + + @see setResizeLimits + */ + void setFixedAspectRatio (const double widthOverHeight) throw(); + + /** Returns the aspect ratio that was set with setFixedAspectRatio(). + + If no aspect ratio is being enforced, this will return 0. + */ + double getFixedAspectRatio() const throw(); + + /** This callback changes the given co-ordinates to impose whatever the current + constraints are set to be. + + @param x the x position that should be examined and adjusted + @param y the y position that should be examined and adjusted + @param w the width that should be examined and adjusted + @param h the height that should be examined and adjusted + @param previousBounds the component's current size + @param limits the region in which the component can be positioned + @param isStretchingTop whether the top edge of the component is being resized + @param isStretchingLeft whether the left edge of the component is being resized + @param isStretchingBottom whether the bottom edge of the component is being resized + @param isStretchingRight whether the right edge of the component is being resized + */ + virtual void checkBounds (int& x, int& y, int& w, int& h, + const Rectangle& previousBounds, + const Rectangle& limits, + const bool isStretchingTop, + const bool isStretchingLeft, + const bool isStretchingBottom, + const bool isStretchingRight); + + /** This callback happens when the resizer is about to start dragging. */ + virtual void resizeStart(); + + /** This callback happens when the resizer has finished dragging. */ + virtual void resizeEnd(); + + /** Checks the given bounds, and then sets the component to the corrected size. */ + void setBoundsForComponent (Component* const component, + int x, int y, int w, int h, + const bool isStretchingTop, + const bool isStretchingLeft, + const bool isStretchingBottom, + const bool isStretchingRight); + + /** Performs a check on the current size of a component, and moves or resizes + it if it fails the constraints. + */ + void checkComponentBounds (Component* component); + + /** Called by setBoundsForComponent() to apply a new constrained size to a + component. + + By default this just calls setBounds(), but it virtual in case it's needed for + extremely cunning purposes. + */ + virtual void applyBoundsToComponent (Component* component, + int x, int y, int w, int h); + + juce_UseDebuggingNewOperator + +private: + int minW, maxW, minH, maxH; + int minOffTop, minOffLeft, minOffBottom, minOffRight; + double aspectRatio; + + ComponentBoundsConstrainer (const ComponentBoundsConstrainer&); + const ComponentBoundsConstrainer& operator= (const ComponentBoundsConstrainer&); +}; + +#endif // __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__ +/********* End of inlined file: juce_ComponentBoundsConstrainer.h *********/ + +/** + An object to take care of the logic for dragging components around with the mouse. + + Very easy to use - in your mouseDown() callback, call startDraggingComponent(), + then in your mouseDrag() callback, call dragComponent(). + + When starting a drag, you can give it a ComponentBoundsConstrainer to use + to limit the component's position and keep it on-screen. + + e.g. @code + class MyDraggableComp + { + ComponentDragger myDragger; + + void mouseDown (const MouseEvent& e) + { + myDragger.startDraggingComponent (this, 0); + } + + void mouseDrag (const MouseEvent& e) + { + myDragger.dragComponent (this, e); + } + }; + @endcode +*/ +class JUCE_API ComponentDragger +{ +public: + + /** Creates a ComponentDragger. */ + ComponentDragger(); + + /** Destructor. */ + virtual ~ComponentDragger(); + + /** Call this from your component's mouseDown() method, to prepare for dragging. + + @param componentToDrag the component that you want to drag + @param constrainer a constrainer object to use to keep the component + from going offscreen + @see dragComponent + */ + void startDraggingComponent (Component* const componentToDrag, + ComponentBoundsConstrainer* constrainer); + + /** Call this from your mouseDrag() callback to move the component. + + This will move the component, but will first check the validity of the + component's new position using the checkPosition() method, which you + can override if you need to enforce special positioning limits on the + component. + + @param componentToDrag the component that you want to drag + @param e the current mouse-drag event + @see dragComponent + */ + void dragComponent (Component* const componentToDrag, + const MouseEvent& e); + + juce_UseDebuggingNewOperator + +private: + ComponentBoundsConstrainer* constrainer; + int originalX, originalY; +}; + +#endif // __JUCE_COMPONENTDRAGGER_JUCEHEADER__ +/********* End of inlined file: juce_ComponentDragger.h *********/ + +/********* Start of inlined file: juce_ResizableBorderComponent.h *********/ +#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ +#define __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ + +/** + A component that resizes its parent window when dragged. + + This component forms a frame around the edge of a component, allowing it to + be dragged by the edges or corners to resize it - like the way windows are + resized in MSWindows or Linux. + + To use it, just add it to your component, making it fill the entire parent component + (there's a mouse hit-test that only traps mouse-events which land around the + edge of the component, so it's even ok to put it on top of any other components + you're using). Make sure you rescale the resizer component to fill the parent + each time the parent's size changes. + + @see ResizableCornerComponent +*/ +class JUCE_API ResizableBorderComponent : public Component +{ +public: + + /** Creates a resizer. + + Pass in the target component which you want to be resized when this one is + dragged. + + The target component will usually be a parent of the resizer component, but this + isn't mandatory. + + Remember that when the target component is resized, it'll need to move and + resize this component to keep it in place, as this won't happen automatically. + + If the constrainer parameter is non-zero, then this object will be used to enforce + limits on the size and position that the component can be stretched to. Make sure + that the constrainer isn't deleted while still in use by this object. + + @see ComponentBoundsConstrainer + */ + ResizableBorderComponent (Component* const componentToResize, + ComponentBoundsConstrainer* const constrainer); + + /** Destructor. */ + ~ResizableBorderComponent(); + + /** Specifies how many pixels wide the draggable edges of this component are. + + @see getBorderThickness + */ + void setBorderThickness (const BorderSize& newBorderSize) throw(); + + /** Returns the number of pixels wide that the draggable edges of this component are. + + @see setBorderThickness + */ + const BorderSize getBorderThickness() const throw(); + + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void mouseEnter (const MouseEvent& e); + /** @internal */ + void mouseMove (const MouseEvent& e); + /** @internal */ + void mouseDown (const MouseEvent& e); + /** @internal */ + void mouseDrag (const MouseEvent& e); + /** @internal */ + void mouseUp (const MouseEvent& e); + /** @internal */ + bool hitTest (int x, int y); + +private: + Component* const component; + ComponentBoundsConstrainer* constrainer; + BorderSize borderSize; + int originalX, originalY, originalW, originalH; + int mouseZone; + + void updateMouseZone (const MouseEvent& e) throw(); + + ResizableBorderComponent (const ResizableBorderComponent&); + const ResizableBorderComponent& operator= (const ResizableBorderComponent&); +}; + +#endif // __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ResizableBorderComponent.h *********/ + +/********* Start of inlined file: juce_ResizableCornerComponent.h *********/ +#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ +#define __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ + +/** A component that resizes a parent window when dragged. + + This is the small triangular stripey resizer component you get in the bottom-right + of windows (more commonly on the Mac than Windows). Put one in the corner of + a larger component and it will automatically resize its parent when it gets dragged + around. + + @see ResizableFrameComponent +*/ +class JUCE_API ResizableCornerComponent : public Component +{ +public: + + /** Creates a resizer. + + Pass in the target component which you want to be resized when this one is + dragged. + + The target component will usually be a parent of the resizer component, but this + isn't mandatory. + + Remember that when the target component is resized, it'll need to move and + resize this component to keep it in place, as this won't happen automatically. + + If the constrainer parameter is non-zero, then this object will be used to enforce + limits on the size and position that the component can be stretched to. Make sure + that the constrainer isn't deleted while still in use by this object. If you + pass a zero in here, no limits will be put on the sizes it can be stretched to. + + @see ComponentBoundsConstrainer + */ + ResizableCornerComponent (Component* const componentToResize, + ComponentBoundsConstrainer* const constrainer); + + /** Destructor. */ + ~ResizableCornerComponent(); + + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void mouseDown (const MouseEvent& e); + /** @internal */ + void mouseDrag (const MouseEvent& e); + /** @internal */ + void mouseUp (const MouseEvent& e); + /** @internal */ + bool hitTest (int x, int y); + +private: + + Component* const component; + ComponentBoundsConstrainer* constrainer; + int originalX, originalY, originalW, originalH; + + ResizableCornerComponent (const ResizableCornerComponent&); + const ResizableCornerComponent& operator= (const ResizableCornerComponent&); +}; + +#endif // __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ResizableCornerComponent.h *********/ + +/** + A base class for top-level windows that can be dragged around and resized. + + To add content to the window, use its setContentComponent() method to + give it a component that will remain positioned inside it (leaving a gap around + the edges for a border). + + It's not advisable to add child components directly to a ResizableWindow: put them + inside your content component instead. And overriding methods like resized(), moved(), etc + is also not recommended - instead override these methods for your content component. + (If for some obscure reason you do need to override these methods, always remember to + call the super-class's resized() method too, otherwise it'll fail to lay out the window + decorations correctly). + + By default resizing isn't enabled - use the setResizable() method to enable it and + to choose the style of resizing to use. + + @see TopLevelWindow +*/ +class JUCE_API ResizableWindow : public TopLevelWindow +{ +public: + + /** Creates a ResizableWindow. + + This constructor doesn't specify a background colour, so the LookAndFeel's default + background colour will be used. + + @param name the name to give the component + @param addToDesktop if true, the window will be automatically added to the + desktop; if false, you can use it as a child component + */ + ResizableWindow (const String& name, + const bool addToDesktop); + + /** Creates a ResizableWindow. + + @param name the name to give the component + @param backgroundColour the colour to use for filling the window's background. + @param addToDesktop if true, the window will be automatically added to the + desktop; if false, you can use it as a child component + */ + ResizableWindow (const String& name, + const Colour& backgroundColour, + const bool addToDesktop); + + /** Destructor. + + If a content component has been set with setContentComponent(), it + will be deleted. + */ + ~ResizableWindow(); + + /** Returns the colour currently being used for the window's background. + + As a convenience the window will fill itself with this colour, but you + can override the paint() method if you need more customised behaviour. + + This method is the same as retrieving the colour for ResizableWindow::backgroundColourId. + + @see setBackgroundColour + */ + const Colour getBackgroundColour() const throw(); + + /** Changes the colour currently being used for the window's background. + + As a convenience the window will fill itself with this colour, but you + can override the paint() method if you need more customised behaviour. + + Note that the opaque state of this window is altered by this call to reflect + the opacity of the colour passed-in. On window systems which can't support + semi-transparent windows this might cause problems, (though it's unlikely you'll + be using this class as a base for a semi-transparent component anyway). + + You can also use the ResizableWindow::backgroundColourId colour id to set + this colour. + + @see getBackgroundColour + */ + void setBackgroundColour (const Colour& newColour); + + /** Make the window resizable or fixed. + + @param shouldBeResizable whether it's resizable at all + @param useBottomRightCornerResizer if true, it'll add a ResizableCornerComponent at the + bottom-right; if false, it'll use a ResizableBorderComponent + around the edge + @see setResizeLimits, isResizable + */ + void setResizable (const bool shouldBeResizable, + const bool useBottomRightCornerResizer); + + /** True if resizing is enabled. + + @see setResizable + */ + bool isResizable() const throw(); + + /** This sets the maximum and minimum sizes for the window. + + If the window's current size is outside these limits, it will be resized to + make sure it's within them. + + Calling setBounds() on the component will bypass any size checking - it's only when + the window is being resized by the user that these values are enforced. + + @see setResizable, setFixedAspectRatio + */ + void setResizeLimits (const int newMinimumWidth, + const int newMinimumHeight, + const int newMaximumWidth, + const int newMaximumHeight) throw(); + + /** Returns the bounds constrainer object that this window is using. + + You can access this to change its properties. + */ + ComponentBoundsConstrainer* getConstrainer() throw() { return constrainer; } + + /** Sets the bounds-constrainer object to use for resizing and dragging this window. + + A pointer to the object you pass in will be kept, but it won't be deleted + by this object, so it's the caller's responsiblity to manage it. + + If you pass 0, then no contraints will be placed on the positioning of the window. + */ + void setConstrainer (ComponentBoundsConstrainer* newConstrainer); + + /** Calls the window's setBounds method, after first checking these bounds + with the current constrainer. + + @see setConstrainer + */ + void setBoundsConstrained (int x, int y, int width, int height); + + /** Returns true if the window is currently in full-screen mode. + + @see setFullScreen + */ + bool isFullScreen() const; + + /** Puts the window into full-screen mode, or restores it to its normal size. + + If true, the window will become full-screen; if false, it will return to the + last size it was before being made full-screen. + + @see isFullScreen + */ + void setFullScreen (const bool shouldBeFullScreen); + + /** Returns true if the window is currently minimised. + + @see setMinimised + */ + bool isMinimised() const; + + /** Minimises the window, or restores it to its previous position and size. + + When being un-minimised, it'll return to the last position and size it + was in before being minimised. + + @see isMinimised + */ + void setMinimised (const bool shouldMinimise); + + /** Returns a string which encodes the window's current size and position. + + This string will encapsulate the window's size, position, and whether it's + in full-screen mode. It's intended for letting your application save and + restore a window's position. + + Use the restoreWindowStateFromString() to restore from a saved state. + + @see restoreWindowStateFromString + */ + const String getWindowStateAsString(); + + /** Restores the window to a previously-saved size and position. + + This restores the window's size, positon and full-screen status from an + string that was previously created with the getWindowStateAsString() + method. + + @returns false if the string wasn't a valid window state + @see getWindowStateAsString + */ + bool restoreWindowStateFromString (const String& previousState); + + /** Returns the current content component. + + This will be the component set by setContentComponent(), or 0 if none + has yet been specified. + + @see setContentComponent + */ + Component* getContentComponent() const throw() { return contentComponent; } + + /** Changes the current content component. + + This sets a component that will be placed in the centre of the ResizableWindow, + (leaving a space around the edge for the border). + + You should never add components directly to a ResizableWindow (or any of its subclasses) + with addChildComponent(). Instead, add them to the content component. + + @param newContentComponent the new component to use (or null to not use one) - this + component will be deleted either when replaced by another call + to this method, or when the ResizableWindow is deleted. + To remove a content component without deleting it, use + setContentComponent (0, false). + @param deleteOldOne if true, the previous content component will be deleted; if + false, the previous component will just be removed without + deleting it. + @param resizeToFit if true, the ResizableWindow will maintain its size such that + it always fits around the size of the content component. If false, the + new content will be resized to fit the current space available. + */ + void setContentComponent (Component* const newContentComponent, + const bool deleteOldOne = true, + const bool resizeToFit = false); + + /** Changes the window so that the content component ends up with the specified size. + + This is basically a setSize call on the window, but which adds on the borders, + so you can specify the content component's target size. + */ + void setContentComponentSize (int width, int height); + + /** A set of colour IDs to use to change the colour of various aspects of the window. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */ + }; + + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + void paint (Graphics& g); + /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */ + void moved(); + /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */ + void resized(); + /** @internal */ + void mouseDown (const MouseEvent& e); + /** @internal */ + void mouseDrag (const MouseEvent& e); + /** @internal */ + void lookAndFeelChanged(); + /** @internal */ + void childBoundsChanged (Component* child); + /** @internal */ + void parentSizeChanged(); + /** @internal */ + void visibilityChanged(); + /** @internal */ + void activeWindowStatusChanged(); + /** @internal */ + int getDesktopWindowStyleFlags() const; + + /** Returns the width of the border to use around the window. + + @see getContentComponentBorder + */ + virtual const BorderSize getBorderThickness(); + + /** Returns the insets to use when positioning the content component. + + @see getBorderThickness + */ + virtual const BorderSize getContentComponentBorder(); + +#ifdef JUCE_DEBUG + /** Overridden to warn people about adding components directly to this component + instead of using setContentComponent(). + + If you know what you're doing and are sure you really want to add a component, specify + a base-class method call to Component::addAndMakeVisible(), to side-step this warning. + */ + void addChildComponent (Component* const child, int zOrder = -1); + /** Overridden to warn people about adding components directly to this component + instead of using setContentComponent(). + + If you know what you're doing and are sure you really want to add a component, specify + a base-class method call to Component::addAndMakeVisible(), to side-step this warning. + */ + void addAndMakeVisible (Component* const child, int zOrder = -1); + +#endif + + ResizableCornerComponent* resizableCorner; + ResizableBorderComponent* resizableBorder; + +private: + Component* contentComponent; + bool resizeToFitContent, fullscreen; + ComponentDragger dragger; + Rectangle lastNonFullScreenPos; + ComponentBoundsConstrainer defaultConstrainer; + ComponentBoundsConstrainer* constrainer; + #ifdef JUCE_DEBUG + bool hasBeenResized; + #endif + + void updateLastPos(); + + ResizableWindow (const ResizableWindow&); + const ResizableWindow& operator= (const ResizableWindow&); + + // (xxx remove these eventually) + // temporarily here to stop old code compiling, as the parameters for these methods have changed.. + void getBorderThickness (int& left, int& top, int& right, int& bottom); + // temporarily here to stop old code compiling, as the parameters for these methods have changed.. + void getContentComponentBorder (int& left, int& top, int& right, int& bottom); +}; + +#endif // __JUCE_RESIZABLEWINDOW_JUCEHEADER__ +/********* End of inlined file: juce_ResizableWindow.h *********/ + +/********* Start of inlined file: juce_GlyphArrangement.h *********/ +#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ +#define __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ + +/** + A glyph from a particular font, with a particular size, style, + typeface and position. + + @see GlyphArrangement, Font +*/ +class JUCE_API PositionedGlyph +{ +public: + + /** Returns the character the glyph represents. */ + juce_wchar getCharacter() const throw() { return character; } + /** Checks whether the glyph is actually empty. */ + bool isWhitespace() const throw() { return CharacterFunctions::isWhitespace (character); } + + /** Returns the position of the glyph's left-hand edge. */ + float getLeft() const throw() { return x; } + /** Returns the position of the glyph's right-hand edge. */ + float getRight() const throw() { return x + w; } + /** Returns the y position of the glyph's baseline. */ + float getBaselineY() const throw() { return y; } + /** Returns the y position of the top of the glyph. */ + float getTop() const throw() { return y - font.getAscent(); } + /** Returns the y position of the bottom of the glyph. */ + float getBottom() const throw() { return y + font.getDescent(); } + + /** Shifts the glyph's position by a relative amount. */ + void moveBy (const float deltaX, + const float deltaY) throw(); + + /** Draws the glyph into a graphics context. */ + void draw (const Graphics& g) const throw(); + + /** Draws the glyph into a graphics context, with an extra transform applied to it. */ + void draw (const Graphics& g, const AffineTransform& transform) const throw(); + + /** Returns the path for this glyph. + + @param path the glyph's outline will be appended to this path + */ + void createPath (Path& path) const throw(); + + /** Checks to see if a point lies within this glyph. */ + bool hitTest (float x, float y) const throw(); + + juce_UseDebuggingNewOperator + +private: + + friend class GlyphArrangement; + float x, y, w; + Font font; + juce_wchar character; + int glyph; + + PositionedGlyph() throw(); +}; + +/** + A set of glyphs, each with a position. + + You can create a GlyphArrangement, text to it and then draw it onto a + graphics context. It's used internally by the text methods in the + Graphics class, but can be used directly if more control is needed. + + @see Font, PositionedGlyph +*/ +class JUCE_API GlyphArrangement +{ +public: + + /** Creates an empty arrangement. */ + GlyphArrangement() throw(); + + /** Takes a copy of another arrangement. */ + GlyphArrangement (const GlyphArrangement& other) throw(); + + /** Copies another arrangement onto this one. + + To add another arrangement without clearing this one, use addGlyphArrangement(). + */ + const GlyphArrangement& operator= (const GlyphArrangement& other) throw(); + + /** Destructor. */ + ~GlyphArrangement() throw(); + + /** Returns the total number of glyphs in the arrangement. */ + int getNumGlyphs() const throw() { return glyphs.size(); } + + /** Returns one of the glyphs from the arrangement. + + @param index the glyph's index, from 0 to (getNumGlyphs() - 1). Be + careful not to pass an out-of-range index here, as it + doesn't do any bounds-checking. + */ + PositionedGlyph& getGlyph (const int index) const throw(); + + /** Clears all text from the arrangement and resets it. + */ + void clear() throw(); + + /** Appends a line of text to the arrangement. + + This will add the text as a single line, where x is the left-hand edge of the + first character, and y is the position for the text's baseline. + + If the text contains new-lines or carriage-returns, this will ignore them - use + addJustifiedText() to add multi-line arrangements. + */ + void addLineOfText (const Font& font, + const String& text, + const float x, + const float y) throw(); + + /** Adds a line of text, truncating it if it's wider than a specified size. + + This is the same as addLineOfText(), but if the line's width exceeds the value + specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."), + if useEllipsis is true, or if this is false, it will just drop any subsequent characters. + */ + void addCurtailedLineOfText (const Font& font, + const String& text, + float x, + const float y, + const float maxWidthPixels, + const bool useEllipsis) throw(); + + /** Adds some multi-line text, breaking lines at word-boundaries if they are too wide. + + This will add text to the arrangement, breaking it into new lines either where there + is a new-line or carriage-return character in the text, or where a line's width + exceeds the value set in maxLineWidth. + + Each line that is added will be laid out using the flags set in horizontalLayout, so + the lines can be left- or right-justified, or centred horizontally in the space + between x and (x + maxLineWidth). + + The y co-ordinate is the position of the baseline of the first line of text - subsequent + lines will be placed below it, separated by a distance of font.getHeight(). + */ + void addJustifiedText (const Font& font, + const String& text, + float x, float y, + const float maxLineWidth, + const Justification& horizontalLayout) throw(); + + /** Tries to fit some text withing a given space. + + This does its best to make the given text readable within the specified rectangle, + so it useful for labelling things. + + If the text is too big, it'll be squashed horizontally or broken over multiple lines + if the maximumLinesToUse value allows this. If the text just won't fit into the space, + it'll cram as much as possible in there, and put some ellipsis at the end to show that + it's been truncated. + + A Justification parameter lets you specify how the text is laid out within the rectangle, + both horizontally and vertically. + + @see Graphics::drawFittedText + */ + void addFittedText (const Font& font, + const String& text, + const float x, const float y, + const float width, const float height, + const Justification& layout, + int maximumLinesToUse, + const float minimumHorizontalScale = 0.7f) throw(); + + /** Appends another glyph arrangement to this one. */ + void addGlyphArrangement (const GlyphArrangement& other) throw(); + + /** Draws this glyph arrangement to a graphics context. + + This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&) + method, which renders the glyphs as filled vectors. + */ + void draw (const Graphics& g) const throw(); + + /** Draws this glyph arrangement to a graphics context. + + This renders the paths as filled vectors, so is far slower than the draw (Graphics&) + method for non-transformed arrangements. + */ + void draw (const Graphics& g, const AffineTransform& transform) const throw(); + + /** Converts the set of glyphs into a path. + + @param path the glyphs' outlines will be appended to this path + */ + void createPath (Path& path) const throw(); + + /** Looks for a glyph that contains the given co-ordinate. + + @returns the index of the glyph, or -1 if none were found. + */ + int findGlyphIndexAt (float x, float y) const throw(); + + /** Finds the smallest rectangle that will enclose a subset of the glyphs. + + @param startIndex the first glyph to test + @param numGlyphs the number of glyphs to include; if this is < 0, all glyphs after + startIndex will be included + @param left on return, the leftmost co-ordinate of the rectangle + @param top on return, the top co-ordinate of the rectangle + @param right on return, the rightmost co-ordinate of the rectangle + @param bottom on return, the bottom co-ordinate of the rectangle + @param includeWhitespace if true, the extent of any whitespace characters will also + be taken into account + */ + void getBoundingBox (int startIndex, + int numGlyphs, + float& left, + float& top, + float& right, + float& bottom, + const bool includeWhitespace) const throw(); + + /** Shifts a set of glyphs by a given amount. + + @param startIndex the first glyph to transform + @param numGlyphs the number of glyphs to move; if this is < 0, all glyphs after + startIndex will be used + @param deltaX the amount to add to their x-positions + @param deltaY the amount to add to their y-positions + */ + void moveRangeOfGlyphs (int startIndex, int numGlyphs, + const float deltaX, + const float deltaY) throw(); + + /** Removes a set of glyphs from the arrangement. + + @param startIndex the first glyph to remove + @param numGlyphs the number of glyphs to remove; if this is < 0, all glyphs after + startIndex will be deleted + */ + void removeRangeOfGlyphs (int startIndex, int numGlyphs) throw(); + + /** Expands or compresses a set of glyphs horizontally. + + @param startIndex the first glyph to transform + @param numGlyphs the number of glyphs to stretch; if this is < 0, all glyphs after + startIndex will be used + @param horizontalScaleFactor how much to scale their horizontal width by + */ + void stretchRangeOfGlyphs (int startIndex, int numGlyphs, + const float horizontalScaleFactor) throw(); + + /** Justifies a set of glyphs within a given space. + + This moves the glyphs as a block so that the whole thing is located within the + given rectangle with the specified layout. + + If the Justification::horizontallyJustified flag is specified, each line will + be stretched out to fill the specified width. + */ + void justifyGlyphs (const int startIndex, const int numGlyphs, + const float x, + const float y, + const float width, + const float height, + const Justification& justification) throw(); + + juce_UseDebuggingNewOperator + +private: + OwnedArray glyphs; + + int insertEllipsis (const Font& font, const float maxXPos, const int startIndex, int endIndex) throw(); + int fitLineIntoSpace (int start, int numGlyphs, float x, float y, float w, float h, const Font& font, + const Justification& justification, float minimumHorizontalScale) throw(); + void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw(); +}; + +#endif // __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ +/********* End of inlined file: juce_GlyphArrangement.h *********/ + +/** + A file open/save dialog box. + + This is a Juce-based file dialog box; to use a native file chooser, see the + FileChooser class. + + To use one of these, create it and call its show() method. e.g. + + @code + { + WildcardFileFilter wildcardFilter (T("*.foo"), T("Foo files")); + + FileBrowserComponent browser (FileBrowserComponent::loadFileMode, + File::nonexistent, + &wildcardFilter, + 0); + + FileChooserDialogBox dialogBox (T("Open some kind of file"), + T("Please choose some kind of file that you want to open..."), + browser, + getLookAndFeel().alertWindowBackground); + + if (dialogBox.show()) + { + File selectedFile = browser.getCurrentFile(); + ... + } + } + @endcode + + @see FileChooser +*/ +class JUCE_API FileChooserDialogBox : public ResizableWindow, + public ButtonListener, + public FileBrowserListener +{ +public: + + /** Creates a file chooser box. + + @param title the main title to show at the top of the box + @param instructions an optional longer piece of text to show below the title in + a smaller font, describing in more detail what's required. + @param browserComponent a FileBrowserComponent that will be shown inside this dialog + box. Make sure you delete this after (but not before!) the + dialog box has been deleted. + @param warnAboutOverwritingExistingFiles if true, then the user will be asked to confirm + if they try to select a file that already exists. (This + flag is only used when saving files) + @param backgroundColour the background colour for the top level window + + @see FileBrowserComponent, FilePreviewComponent + */ + FileChooserDialogBox (const String& title, + const String& instructions, + FileBrowserComponent& browserComponent, + const bool warnAboutOverwritingExistingFiles, + const Colour& backgroundColour); + + /** Destructor. */ + ~FileChooserDialogBox(); + + /** Displays and runs the dialog box modally. + + This will show the box with the specified size, returning true if the user + pressed 'ok', or false if they cancelled. + + Leave the width or height as 0 to use the default size + */ + bool show (int width = 0,int height = 0); + + /** @internal */ + void buttonClicked (Button* button); + /** @internal */ + void closeButtonPressed(); + /** @internal */ + void selectionChanged(); + /** @internal */ + void fileClicked (const File& file, const MouseEvent& e); + /** @internal */ + void fileDoubleClicked (const File& file); + + juce_UseDebuggingNewOperator + +private: + class ContentComponent : public Component + { + public: + ContentComponent(); + ~ContentComponent(); + + void paint (Graphics& g); + void resized(); + + String instructions; + GlyphArrangement text; + + FileBrowserComponent* chooserComponent; + FilePreviewComponent* previewComponent; + TextButton* okButton; + TextButton* cancelButton; + }; + + ContentComponent* content; + const bool warnAboutOverwritingExistingFiles; + + FileChooserDialogBox (const FileChooserDialogBox&); + const FileChooserDialogBox& operator= (const FileChooserDialogBox&); +}; + +#endif // __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ +/********* End of inlined file: juce_FileChooserDialogBox.h *********/ + +#endif +#ifndef __JUCE_FILEFILTER_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FileListComponent.h *********/ +#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ +#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__ + +/** + A component that displays the files in a directory as a listbox. + + This implements the DirectoryContentsDisplayComponent base class so that + it can be used in a FileBrowserComponent. + + To attach a listener to it, use its DirectoryContentsDisplayComponent base + class and the FileBrowserListener class. + + @see DirectoryContentsList, FileTreeComponent +*/ +class JUCE_API FileListComponent : public ListBox, + public DirectoryContentsDisplayComponent, + private ListBoxModel, + private ChangeListener +{ +public: + + /** Creates a listbox to show the contents of a specified directory. + */ + FileListComponent (DirectoryContentsList& listToShow); + + /** Destructor. */ + ~FileListComponent(); + + /** Returns the number of files the user has got selected. + @see getSelectedFile + */ + int getNumSelectedFiles() const; + + /** Returns one of the files that the user has currently selected. + The index should be in the range 0 to (getNumSelectedFiles() - 1). + @see getNumSelectedFiles + */ + const File getSelectedFile (int index = 0) const; + + /** Scrolls to the top of the list. */ + void scrollToTop(); + /** @internal */ void changeListenerCallback (void*); /** @internal */ - void sliderValueChanged (Slider*); - - juce_UseDebuggingNewOperator - -protected: - - /** The slider component being used in this component. - - Your subclass has access to this in case it needs to customise it in some way. - */ - Slider* slider; -}; - -#endif // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_SliderPropertyComponent.h *********/ - -#endif -#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_TextPropertyComponent.h *********/ -#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ -#define __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ - -/** - A PropertyComponent that shows its value as editable text. - - @see PropertyComponent -*/ -class JUCE_API TextPropertyComponent : public PropertyComponent -{ -public: - - /** Creates a text property component. - - The maxNumChars is used to set the length of string allowable, and isMultiLine - sets whether the text editor allows carriage returns. - - @see TextEditor - */ - TextPropertyComponent (const String& propertyName, - const int maxNumChars, - const bool isMultiLine); - - /** Destructor. */ - ~TextPropertyComponent(); - - /** Called when the user edits the text. - - Your subclass must use this callback to change the value of whatever item - this property component represents. - */ - virtual void setText (const String& newText) = 0; - - /** Returns the text that should be shown in the text editor. - */ - virtual const String getText() const = 0; - + int getNumRows(); /** @internal */ - void refresh(); + void paintListBoxItem (int, Graphics&, int, int, bool); /** @internal */ - void textWasEdited(); + Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); + /** @internal */ + void selectedRowsChanged (int lastRowSelected); + /** @internal */ + void deleteKeyPressed (int currentSelectedRow); + /** @internal */ + void returnKeyPressed (int currentSelectedRow); juce_UseDebuggingNewOperator private: - Label* textEditor; + FileListComponent (const FileListComponent&); + const FileListComponent& operator= (const FileListComponent&); + + File lastDirectory; }; -#endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_TextPropertyComponent.h *********/ +#endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileListComponent.h *********/ + +#endif +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FilenameComponent.h *********/ +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ +#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + +class FilenameComponent; + +/** + Listens for events happening to a FilenameComponent. + + Use FilenameComponent::addListener() and FilenameComponent::removeListener() to + register one of these objects for event callbacks when the filename is changed. + + @see FilenameComponent +*/ +class JUCE_API FilenameComponentListener +{ +public: + /** Destructor. */ + virtual ~FilenameComponentListener() {} + + /** This method is called after the FilenameComponent's file has been changed. */ + virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0; +}; + +/** + Shows a filename as an editable text box, with a 'browse' button and a + drop-down list for recently selected files. + + A handy component for dialogue boxes where you want the user to be able to + select a file or directory. + + Attach an FilenameComponentListener using the addListener() method, and it will + get called each time the user changes the filename, either by browsing for a file + and clicking 'ok', or by typing a new filename into the box and pressing return. + + @see FileChooser, ComboBox +*/ +class JUCE_API FilenameComponent : public Component, + public SettableTooltipClient, + public FileDragAndDropTarget, + private AsyncUpdater, + private ButtonListener, + private ComboBoxListener +{ +public: + + /** Creates a FilenameComponent. + + @param name the name for this component. + @param currentFile the file to initially show in the box + @param canEditFilename if true, the user can manually edit the filename; if false, + they can only change it by browsing for a new file + @param isDirectory if true, the file will be treated as a directory, and + an appropriate directory browser used + @param isForSaving if true, the file browser will allow non-existent files to + be picked, as the file is assumed to be used for saving rather + than loading + @param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo". + If an empty string is passed in, then the pattern is assumed to be "*" + @param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added + to any filenames that are entered or chosen + @param textWhenNothingSelected the message to display in the box before any filename is entered. (This + will only appear if the initial file isn't valid) + */ + FilenameComponent (const String& name, + const File& currentFile, + const bool canEditFilename, + const bool isDirectory, + const bool isForSaving, + const String& fileBrowserWildcard, + const String& enforcedSuffix, + const String& textWhenNothingSelected); + + /** Destructor. */ + ~FilenameComponent(); + + /** Returns the currently displayed filename. */ + const File getCurrentFile() const; + + /** Changes the current filename. + + If addToRecentlyUsedList is true, the filename will also be added to the + drop-down list of recent files. + + If sendChangeNotification is false, then the listeners won't be told of the + change. + */ + void setCurrentFile (File newFile, + const bool addToRecentlyUsedList, + const bool sendChangeNotification = true); + + /** Changes whether the use can type into the filename box. + */ + void setFilenameIsEditable (const bool shouldBeEditable); + + /** Sets a file or directory to be the default starting point for the browser to show. + + This is only used if the current file hasn't been set. + */ + void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); + + /** Returns all the entries on the recent files list. + + This can be used in conjunction with setRecentlyUsedFilenames() for saving the + state of this list. + + @see setRecentlyUsedFilenames + */ + const StringArray getRecentlyUsedFilenames() const; + + /** Sets all the entries on the recent files list. + + This can be used in conjunction with getRecentlyUsedFilenames() for saving the + state of this list. + + @see getRecentlyUsedFilenames, addRecentlyUsedFile + */ + void setRecentlyUsedFilenames (const StringArray& filenames); + + /** Adds an entry to the recently-used files dropdown list. + + If the file is already in the list, it will be moved to the top. A limit + is also placed on the number of items that are kept in the list. + + @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles + */ + void addRecentlyUsedFile (const File& file); + + /** Changes the limit for the number of files that will be stored in the recent-file list. + */ + void setMaxNumberOfRecentFiles (const int newMaximum); + + /** Changes the text shown on the 'browse' button. + + By default this button just says "..." but you can change it. The button itself + can be changed using the look-and-feel classes, so it might not actually have any + text on it. + */ + void setBrowseButtonText (const String& browseButtonText); + + /** Adds a listener that will be called when the selected file is changed. */ + void addListener (FilenameComponentListener* const listener) throw(); + + /** Removes a previously-registered listener. */ + void removeListener (FilenameComponentListener* const listener) throw(); + + /** Gives the component a tooltip. */ + void setTooltip (const String& newTooltip); + + /** @internal */ + void paintOverChildren (Graphics& g); + /** @internal */ + void resized(); + /** @internal */ + void lookAndFeelChanged(); + /** @internal */ + bool isInterestedInFileDrag (const StringArray& files); + /** @internal */ + void filesDropped (const StringArray& files, int, int); + /** @internal */ + void fileDragEnter (const StringArray& files, int, int); + /** @internal */ + void fileDragExit (const StringArray& files); + + juce_UseDebuggingNewOperator + +private: + + ComboBox* filenameBox; + String lastFilename; + Button* browseButton; + int maxRecentFiles; + bool isDir, isSaving, isFileDragOver; + String wildcard, enforcedSuffix, browseButtonText; + SortedSet listeners; + File defaultBrowseFile; + + void comboBoxChanged (ComboBox*); + void buttonClicked (Button* button); + void handleAsyncUpdate(); + + FilenameComponent (const FilenameComponent&); + const FilenameComponent& operator= (const FilenameComponent&); +}; + +#endif // __JUCE_FILENAMECOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FilenameComponent.h *********/ + +#endif +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/ +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ +#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ + +/** + Shows a set of file paths in a list, allowing them to be added, removed or + re-ordered. + + @see FileSearchPath +*/ +class JUCE_API FileSearchPathListComponent : public Component, + public SettableTooltipClient, + public FileDragAndDropTarget, + private ButtonListener, + private ListBoxModel +{ +public: + + /** Creates an empty FileSearchPathListComponent. + + */ + FileSearchPathListComponent(); + + /** Destructor. */ + ~FileSearchPathListComponent(); + + /** Returns the path as it is currently shown. */ + const FileSearchPath& getPath() const throw() { return path; } + + /** Changes the current path. */ + void setPath (const FileSearchPath& newPath); + + /** Sets a file or directory to be the default starting point for the browser to show. + + This is only used if the current file hasn't been set. + */ + void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); + + /** A set of colour IDs to use to change the colour of various aspects of the label. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x1004100, /**< The background colour to fill the component with. + Make this transparent if you don't want the background to be filled. */ + }; + + /** @internal */ + int getNumRows(); + /** @internal */ + void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); + /** @internal */ + void deleteKeyPressed (int lastRowSelected); + /** @internal */ + void returnKeyPressed (int lastRowSelected); + /** @internal */ + void listBoxItemDoubleClicked (int row, const MouseEvent&); + /** @internal */ + void selectedRowsChanged (int lastRowSelected); + /** @internal */ + void resized(); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + bool isInterestedInFileDrag (const StringArray& files); + /** @internal */ + void filesDropped (const StringArray& files, int, int); + /** @internal */ + void buttonClicked (Button* button); + + juce_UseDebuggingNewOperator + +private: + + FileSearchPath path; + File defaultBrowseTarget; + + ListBox* listBox; + Button* addButton; + Button* removeButton; + Button* changeButton; + Button* upButton; + Button* downButton; + + void changed() throw(); + void updateButtons() throw(); + + FileSearchPathListComponent (const FileSearchPathListComponent&); + const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&); +}; + +#endif // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileSearchPathListComponent.h *********/ + +#endif +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_FileTreeComponent.h *********/ +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ +#define __JUCE_FILETREECOMPONENT_JUCEHEADER__ + +/** + A component that displays the files in a directory as a treeview. + + This implements the DirectoryContentsDisplayComponent base class so that + it can be used in a FileBrowserComponent. + + To attach a listener to it, use its DirectoryContentsDisplayComponent base + class and the FileBrowserListener class. + + @see DirectoryContentsList, FileListComponent +*/ +class JUCE_API FileTreeComponent : public TreeView, + public DirectoryContentsDisplayComponent +{ +public: + + /** Creates a listbox to show the contents of a specified directory. + */ + FileTreeComponent (DirectoryContentsList& listToShow); + + /** Destructor. */ + ~FileTreeComponent(); + + /** Returns the number of files the user has got selected. + @see getSelectedFile + */ + int getNumSelectedFiles() const { return TreeView::getNumSelectedItems(); } + + /** Returns one of the files that the user has currently selected. + The index should be in the range 0 to (getNumSelectedFiles() - 1). + @see getNumSelectedFiles + */ + const File getSelectedFile (int index = 0) const; + + /** Scrolls the list to the top. */ + void scrollToTop(); + + /** Setting a name for this allows tree items to be dragged. + + The string that you pass in here will be returned by the getDragSourceDescription() + of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription(). + */ + void setDragAndDropDescription (const String& description) throw(); + + /** Returns the last value that was set by setDragAndDropDescription(). + */ + const String& getDragAndDropDescription() const throw() { return dragAndDropDescription; } + + juce_UseDebuggingNewOperator + +private: + String dragAndDropDescription; + + FileTreeComponent (const FileTreeComponent&); + const FileTreeComponent& operator= (const FileTreeComponent&); +}; + +#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_FileTreeComponent.h *********/ + +#endif +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_ImagePreviewComponent.h *********/ +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ +#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + +/** + A simple preview component that shows thumbnails of image files. + + @see FileChooserDialogBox, FilePreviewComponent +*/ +class JUCE_API ImagePreviewComponent : public FilePreviewComponent, + private Timer +{ +public: + + /** Creates an ImagePreviewComponent. */ + ImagePreviewComponent(); + + /** Destructor. */ + ~ImagePreviewComponent(); + + /** @internal */ + void selectedFileChanged (const File& newSelectedFile); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void timerCallback(); + + juce_UseDebuggingNewOperator + +private: + File fileToLoad; + Image* currentThumbnail; + String currentDetails; + + void getThumbSize (int& w, int& h) const; + + ImagePreviewComponent (const ImagePreviewComponent&); + const ImagePreviewComponent& operator= (const ImagePreviewComponent&); +}; + +#endif // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ImagePreviewComponent.h *********/ + +#endif +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ + +/********* Start of inlined file: juce_WildcardFileFilter.h *********/ +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ +#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ + +/** + A type of FileFilter that works by wildcard pattern matching. + + This filter only allows files that match one of the specified patterns, but + allows all directories through. + + @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent +*/ +class JUCE_API WildcardFileFilter : public FileFilter +{ +public: + + /** + Creates a wildcard filter for one or more patterns. + + The wildcardPatterns parameter is a comma or semicolon-delimited set of + patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav + or .aiff. + + The description is a name to show the user in a list of possible patterns, so + for the wav/aiff example, your description might be "audio files". + */ + WildcardFileFilter (const String& fileWildcardPatterns, + const String& directoryWildcardPatterns, + const String& description); + + /** Destructor. */ + ~WildcardFileFilter(); + + /** Returns true if the filename matches one of the patterns specified. */ + bool isFileSuitable (const File& file) const; + + /** This always returns true. */ + bool isDirectorySuitable (const File& file) const; + + juce_UseDebuggingNewOperator + +private: + StringArray fileWildcards, directoryWildcards; + + static void parse (const String& pattern, StringArray& result) throw(); + static bool match (const File& file, const StringArray& wildcards) throw(); +}; + +#endif // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ +/********* End of inlined file: juce_WildcardFileFilter.h *********/ + +#endif +#ifndef __JUCE_COMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ + +#endif +#ifndef __JUCE_DESKTOP_JUCEHEADER__ + +#endif +#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ + +#endif +#ifndef __JUCE_KEYLISTENER_JUCEHEADER__ + +#endif +#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_KeyMappingEditorComponent.h *********/ +#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ +#define __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_KeyPressMappingSet.h *********/ +#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ +#define __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ + +/** + Manages and edits a list of keypresses, which it uses to invoke the appropriate + command in a ApplicationCommandManager. + + Normally, you won't actually create a KeyPressMappingSet directly, because + each ApplicationCommandManager contains its own KeyPressMappingSet, so typically + you'd create yourself an ApplicationCommandManager, and call its + ApplicationCommandManager::getKeyMappings() method to get a pointer to its + KeyPressMappingSet. + + For one of these to actually use keypresses, you'll need to add it as a KeyListener + to the top-level component for which you want to handle keystrokes. So for example: + + @code + class MyMainWindow : public Component + { + ApplicationCommandManager* myCommandManager; + + public: + MyMainWindow() + { + myCommandManager = new ApplicationCommandManager(); + + // first, make sure the command manager has registered all the commands that its + // targets can perform.. + myCommandManager->registerAllCommandsForTarget (myCommandTarget1); + myCommandManager->registerAllCommandsForTarget (myCommandTarget2); + + // this will use the command manager to initialise the KeyPressMappingSet with + // the default keypresses that were specified when the targets added their commands + // to the manager. + myCommandManager->getKeyMappings()->resetToDefaultMappings(); + + // having set up the default key-mappings, you might now want to load the last set + // of mappings that the user configured. + myCommandManager->getKeyMappings()->restoreFromXml (lastSavedKeyMappingsXML); + + // Now tell our top-level window to send any keypresses that arrive to the + // KeyPressMappingSet, which will use them to invoke the appropriate commands. + addKeyListener (myCommandManager->getKeyMappings()); + } + + ... + } + @endcode + + KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can + register to be told when a command or mapping is added, removed, etc. + + There's also a UI component called KeyMappingEditorComponent that can be used + to easily edit the key mappings. + + @see Component::addKeyListener(), KeyMappingEditorComponent, ApplicationCommandManager +*/ +class JUCE_API KeyPressMappingSet : public KeyListener, + public ChangeBroadcaster, + public FocusChangeListener +{ +public: + + /** Creates a KeyPressMappingSet for a given command manager. + + Normally, you won't actually create a KeyPressMappingSet directly, because + each ApplicationCommandManager contains its own KeyPressMappingSet, so the + best thing to do is to create your ApplicationCommandManager, and use the + ApplicationCommandManager::getKeyMappings() method to access its mappings. + + When a suitable keypress happens, the manager's invoke() method will be + used to invoke the appropriate command. + + @see ApplicationCommandManager + */ + KeyPressMappingSet (ApplicationCommandManager* const commandManager) throw(); + + /** Creates an copy of a KeyPressMappingSet. */ + KeyPressMappingSet (const KeyPressMappingSet& other) throw(); + + /** Destructor. */ + ~KeyPressMappingSet(); + + ApplicationCommandManager* getCommandManager() const throw() { return commandManager; } + + /** Returns a list of keypresses that are assigned to a particular command. + + @param commandID the command's ID + */ + const Array getKeyPressesAssignedToCommand (const CommandID commandID) const throw(); + + /** Assigns a keypress to a command. + + If the keypress is already assigned to a different command, it will first be + removed from that command, to avoid it triggering multiple functions. + + @param commandID the ID of the command that you want to add a keypress to. If + this is 0, the keypress will be removed from anything that it + was previously assigned to, but not re-assigned + @param newKeyPress the new key-press + @param insertIndex if this is less than zero, the key will be appended to the + end of the list of keypresses; otherwise the new keypress will + be inserted into the existing list at this index + */ + void addKeyPress (const CommandID commandID, + const KeyPress& newKeyPress, + int insertIndex = -1) throw(); + + /** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager. + + @see resetToDefaultMapping + */ + void resetToDefaultMappings() throw(); + + /** Resets all key-mappings to the defaults for a particular command. + + @see resetToDefaultMappings + */ + void resetToDefaultMapping (const CommandID commandID) throw(); + + /** Removes all keypresses that are assigned to any commands. */ + void clearAllKeyPresses() throw(); + + /** Removes all keypresses that are assigned to a particular command. */ + void clearAllKeyPresses (const CommandID commandID) throw(); + + /** Removes one of the keypresses that are assigned to a command. + + See the getKeyPressesAssignedToCommand() for the list of keypresses to + which the keyPressIndex refers. + */ + void removeKeyPress (const CommandID commandID, + const int keyPressIndex) throw(); + + /** Removes a keypress from any command that it may be assigned to. + */ + void removeKeyPress (const KeyPress& keypress) throw(); + + /** Returns true if the given command is linked to this key. */ + bool containsMapping (const CommandID commandID, + const KeyPress& keyPress) const throw(); + + /** Looks for a command that corresponds to a keypress. + + @returns the UID of the command or 0 if none was found + */ + CommandID findCommandForKeyPress (const KeyPress& keyPress) const throw(); + + /** Tries to recreate the mappings from a previously stored state. + + The XML passed in must have been created by the createXml() method. + + If the stored state makes any reference to commands that aren't + currently available, these will be ignored. + + If the set of mappings being loaded was a set of differences (using createXml (true)), + then this will call resetToDefaultMappings() and then merge the saved mappings + on top. If the saved set was created with createXml (false), then this method + will first clear all existing mappings and load the saved ones as a complete set. + + @returns true if it manages to load the XML correctly + @see createXml + */ + bool restoreFromXml (const XmlElement& xmlVersion); + + /** Creates an XML representation of the current mappings. + + This will produce a lump of XML that can be later reloaded using + restoreFromXml() to recreate the current mapping state. + + The object that is returned must be deleted by the caller. + + @param saveDifferencesFromDefaultSet if this is false, then all keypresses + will be saved into the XML. If it's true, then the XML will + only store the differences between the current mappings and + the default mappings you'd get from calling resetToDefaultMappings(). + The advantage of saving a set of differences from the default is that + if you change the default mappings (in a new version of your app, for + example), then these will be merged into a user's saved preferences. + + @see restoreFromXml + */ + XmlElement* createXml (const bool saveDifferencesFromDefaultSet) const; + + /** @internal */ + bool keyPressed (const KeyPress& key, Component* originatingComponent); + /** @internal */ + bool keyStateChanged (const bool isKeyDown, Component* originatingComponent); + /** @internal */ + void globalFocusChanged (Component* focusedComponent); + + juce_UseDebuggingNewOperator + +private: + + ApplicationCommandManager* commandManager; + + struct CommandMapping + { + CommandID commandID; + Array keypresses; + bool wantsKeyUpDownCallbacks; + }; + + OwnedArray mappings; + + struct KeyPressTime + { + KeyPress key; + uint32 timeWhenPressed; + }; + + OwnedArray keysDown; + + void handleMessage (const Message& message); + + void invokeCommand (const CommandID commandID, + const KeyPress& keyPress, + const bool isKeyDown, + const int millisecsSinceKeyPressed, + Component* const originatingComponent) const; + + const KeyPressMappingSet& operator= (const KeyPressMappingSet&); +}; + +#endif // __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ +/********* End of inlined file: juce_KeyPressMappingSet.h *********/ + +/** + A component to allow editing of the keymaps stored by a KeyPressMappingSet + object. + + @see KeyPressMappingSet +*/ +class JUCE_API KeyMappingEditorComponent : public Component, + public TreeViewItem, + public ChangeListener, + private ButtonListener +{ +public: + + /** Creates a KeyMappingEditorComponent. + + @param mappingSet this is the set of mappings to display and + edit. Make sure the mappings object is not + deleted before this component! + @param showResetToDefaultButton if true, then at the bottom of the + list, the component will include a 'reset to + defaults' button. + */ + KeyMappingEditorComponent (KeyPressMappingSet* const mappingSet, + const bool showResetToDefaultButton); + + /** Destructor. */ + virtual ~KeyMappingEditorComponent(); + + /** Sets up the colours to use for parts of the component. + + @param mainBackground colour to use for most of the background + @param textColour colour to use for the text + */ + void setColours (const Colour& mainBackground, + const Colour& textColour); + + /** Returns the KeyPressMappingSet that this component is acting upon. + */ + KeyPressMappingSet* getMappings() const throw() { return mappings; } + + /** Can be overridden if some commands need to be excluded from the list. + + By default this will use the KeyPressMappingSet's shouldCommandBeVisibleInEditor() + method to decide what to return, but you can override it to handle special cases. + */ + virtual bool shouldCommandBeIncluded (const CommandID commandID); + + /** Can be overridden to indicate that some commands are shown as read-only. + + By default this will use the KeyPressMappingSet's shouldCommandBeReadOnlyInEditor() + method to decide what to return, but you can override it to handle special cases. + */ + virtual bool isCommandReadOnly (const CommandID commandID); + + /** This can be overridden to let you change the format of the string used + to describe a keypress. + + This is handy if you're using non-standard KeyPress objects, e.g. for custom + keys that are triggered by something else externally. If you override the + method, be sure to let the base class's method handle keys you're not + interested in. + */ + virtual const String getDescriptionForKeyPress (const KeyPress& key); + + /** A set of colour IDs to use to change the colour of various aspects of the editor. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + To change the colours of the menu that pops up + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + backgroundColourId = 0x100ad00, /**< The background colour to fill the editor background. */ + textColourId = 0x100ad01, /**< The colour for the text. */ + }; + + /** @internal */ + void parentHierarchyChanged(); + /** @internal */ + void resized(); + /** @internal */ + void changeListenerCallback (void*); + /** @internal */ + bool mightContainSubItems(); + /** @internal */ + const String getUniqueName() const; + /** @internal */ + void buttonClicked (Button* button); + + juce_UseDebuggingNewOperator + +private: + + KeyPressMappingSet* mappings; + TreeView* tree; + friend class KeyMappingTreeViewItem; + friend class KeyCategoryTreeViewItem; + friend class KeyMappingItemComponent; + friend class KeyMappingChangeButton; + TextButton* resetButton; + + void assignNewKey (const CommandID commandID, int index); + + KeyMappingEditorComponent (const KeyMappingEditorComponent&); + const KeyMappingEditorComponent& operator= (const KeyMappingEditorComponent&); +}; + +#endif // __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_KeyMappingEditorComponent.h *********/ + +#endif +#ifndef __JUCE_KEYPRESS_JUCEHEADER__ + +#endif +#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ + +#endif +#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ #endif #ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ @@ -49384,708 +48709,247 @@ private: #ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__ #define __JUCE_DOCUMENTWINDOW_JUCEHEADER__ -/********* Start of inlined file: juce_ResizableWindow.h *********/ -#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ -#define __JUCE_RESIZABLEWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_MenuBarComponent.h *********/ +#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ +#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_TopLevelWindow.h *********/ -#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ -#define __JUCE_TOPLEVELWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_MenuBarModel.h *********/ +#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ +#define __JUCE_MENUBARMODEL_JUCEHEADER__ -/********* Start of inlined file: juce_DropShadower.h *********/ -#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__ -#define __JUCE_DROPSHADOWER_JUCEHEADER__ +class MenuBarModel; /** - Adds a drop-shadow to a component. + A class to receive callbacks when a MenuBarModel changes. - This object creates and manages a set of components which sit around a - component, creating a gaussian shadow around it. The components will track - the position of the component and if it's brought to the front they'll also - follow this. - - For desktop windows you don't need to use this class directly - just - set the Component::windowHasDropShadow flag when calling - Component::addToDesktop(), and the system will create one of these if it's - needed (which it obviously isn't on the Mac, for example). + @see MenuBarModel::addListener, MenuBarModel::removeListener, MenuBarModel::menuItemsChanged */ -class JUCE_API DropShadower : public ComponentListener +class JUCE_API MenuBarModelListener { public: - - /** Creates a DropShadower. - - @param alpha the opacity of the shadows, from 0 to 1.0 - @param xOffset the horizontal displacement of the shadow, in pixels - @param yOffset the vertical displacement of the shadow, in pixels - @param blurRadius the radius of the blur to use for creating the shadow - */ - DropShadower (const float alpha = 0.5f, - const int xOffset = 1, - const int yOffset = 5, - const float blurRadius = 10.0f); - /** Destructor. */ - virtual ~DropShadower(); + virtual ~MenuBarModelListener() {} - /** Attaches the DropShadower to the component you want to shadow. */ - void setOwner (Component* componentToFollow); + /** This callback is made when items are changed in the menu bar model. + */ + virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0; - /** @internal */ - void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); - /** @internal */ - void componentBroughtToFront (Component& component); - /** @internal */ - void componentChildrenChanged (Component& component); - /** @internal */ - void componentParentHierarchyChanged (Component& component); - /** @internal */ - void componentVisibilityChanged (Component& component); - - juce_UseDebuggingNewOperator - -private: - - Component* owner; - int numShadows; - Component* shadowWindows[4]; - Image* shadowImageSections[12]; - const int shadowEdge, xOffset, yOffset; - const float alpha, blurRadius; - bool inDestructor, reentrant; - - void updateShadows(); - void setShadowImage (Image* const src, - const int num, - const int w, const int h, - const int sx, const int sy) throw(); - - void bringShadowWindowsToFront(); - void deleteShadowWindows(); - - DropShadower (const DropShadower&); - const DropShadower& operator= (const DropShadower&); + /** This callback is made when an application command is invoked that + is represented by one of the items in the menu bar model. + */ + virtual void menuCommandInvoked (MenuBarModel* menuBarModel, + const ApplicationCommandTarget::InvocationInfo& info) = 0; }; -#endif // __JUCE_DROPSHADOWER_JUCEHEADER__ -/********* End of inlined file: juce_DropShadower.h *********/ - /** - A base class for top-level windows. + A class for controlling MenuBar components. - This class is used for components that are considered a major part of your - application - e.g. ResizableWindow, DocumentWindow, DialogWindow, AlertWindow, - etc. Things like menus that pop up briefly aren't derived from it. + This class is used to tell a MenuBar what menus to show, and to respond + to a menu being selected. - A TopLevelWindow is probably on the desktop, but this isn't mandatory - it - could itself be the child of another component. - - The class manages a list of all instances of top-level windows that are in use, - and each one is also given the concept of being "active". The active window is - one that is actively being used by the user. This isn't quite the same as the - component with the keyboard focus, because there may be a popup menu or other - temporary window which gets keyboard focus while the active top level window is - unchanged. - - A top-level window also has an optional drop-shadow. - - @see ResizableWindow, DocumentWindow, DialogWindow + @see MenuBarModelListener, MenuBarComponent, PopupMenu */ -class JUCE_API TopLevelWindow : public Component +class JUCE_API MenuBarModel : private AsyncUpdater, + private ApplicationCommandManagerListener { public: - /** Creates a TopLevelWindow. - - @param name the name to give the component - @param addToDesktop if true, the window will be automatically added to the - desktop; if false, you can use it as a child component - */ - TopLevelWindow (const String& name, - const bool addToDesktop); + MenuBarModel() throw(); /** Destructor. */ - ~TopLevelWindow(); + virtual ~MenuBarModel(); - /** True if this is currently the TopLevelWindow that is actively being used. + /** Call this when some of your menu items have changed. - This isn't quite the same as having keyboard focus, because the focus may be - on a child component or a temporary pop-up menu, etc, while this window is - still considered to be active. + This method will cause a callback to any MenuBarListener objects that + are registered with this model. - @see activeWindowStatusChanged + If this model is displaying items from an ApplicationCommandManager, you + can use the setApplicationCommandManagerToWatch() method to cause + change messages to be sent automatically when the ApplicationCommandManager + is changed. + + @see addListener, removeListener, MenuBarListener */ - bool isActiveWindow() const throw() { return windowIsActive_; } + void menuItemsChanged(); - /** This will set the bounds of the window so that it's centred in front of another - window. + /** Tells the menu bar to listen to the specified command manager, and to update + itself when the commands change. - If your app has a few windows open and want to pop up a dialog box for one of - them, you can use this to show it in front of the relevent parent window, which - is a bit neater than just having it appear in the middle of the screen. - - If componentToCentreAround is 0, then the currently active TopLevelWindow will - be used instead. If no window is focused, it'll just default to the middle of the - screen. + This will also allow it to flash a menu name when a command from that menu + is invoked using a keystroke. */ - void centreAroundComponent (Component* componentToCentreAround, - const int width, const int height); + void setApplicationCommandManagerToWatch (ApplicationCommandManager* const manager) throw(); - /** Turns the drop-shadow on and off. */ - void setDropShadowEnabled (const bool useShadow); + /** Registers a listener for callbacks when the menu items in this model change. - /** Sets whether an OS-native title bar will be used, or a Juce one. + The listener object will get callbacks when this object's menuItemsChanged() + method is called. - @see isUsingNativeTitleBar + @see removeListener */ - void setUsingNativeTitleBar (const bool useNativeTitleBar); + void addListener (MenuBarModelListener* const listenerToAdd) throw(); - /** Returns true if the window is currently using an OS-native title bar. + /** Removes a listener. - @see setUsingNativeTitleBar + @see addListener */ - bool isUsingNativeTitleBar() const throw() { return useNativeTitleBar && isOnDesktop(); } + void removeListener (MenuBarModelListener* const listenerToRemove) throw(); - /** Returns the number of TopLevelWindow objects currently in use. + /** This method must return a list of the names of the menus. */ + virtual const StringArray getMenuBarNames() = 0; - @see getTopLevelWindow + /** This should return the popup menu to display for a given top-level menu. + + @param topLevelMenuIndex the index of the top-level menu to show + @param menuName the name of the top-level menu item to show */ - static int getNumTopLevelWindows() throw(); + virtual const PopupMenu getMenuForIndex (int topLevelMenuIndex, + const String& menuName) = 0; - /** Returns one of the TopLevelWindow objects currently in use. + /** This is called when a menu item has been clicked on. - The index is 0 to (getNumTopLevelWindows() - 1). + @param menuItemID the item ID of the PopupMenu item that was selected + @param topLevelMenuIndex the index of the top-level menu from which the item was + chosen (just in case you've used duplicate ID numbers + on more than one of the popup menus) */ - static TopLevelWindow* getTopLevelWindow (const int index) throw(); + virtual void menuItemSelected (int menuItemID, + int topLevelMenuIndex) = 0; - /** Returns the currently-active top level window. +#if JUCE_MAC || DOXYGEN + /** MAC ONLY - Sets the model that is currently being shown as the main + menu bar at the top of the screen on the Mac. - There might not be one, of course, so this can return 0. + You can pass 0 to stop the current model being displayed. Be careful + not to delete a model while it is being used. + + An optional extra menu can be specified, containing items to add to the top of + the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of + an apple, it's the one next to it, with your application's name at the top + and the services menu etc on it). When one of these items is selected, the + menu bar model will be used to invoke it, and in the menuItemSelected() callback + the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems + object then newMenuBarModel must be non-null. */ - static TopLevelWindow* getActiveTopLevelWindow() throw(); + static void setMacMainMenu (MenuBarModel* newMenuBarModel, + const PopupMenu* extraAppleMenuItems = 0) throw(); - juce_UseDebuggingNewOperator - - /** @internal */ - virtual void addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo = 0); - -protected: - - /** This callback happens when this window becomes active or inactive. - - @see isActiveWindow + /** MAC ONLY - Returns the menu model that is currently being shown as + the main menu bar. */ - virtual void activeWindowStatusChanged(); - - /** @internal */ - void focusOfChildComponentChanged (FocusChangeType cause); - /** @internal */ - void parentHierarchyChanged(); - /** @internal */ - void visibilityChanged(); - /** @internal */ - virtual int getDesktopWindowStyleFlags() const; - /** @internal */ - void recreateDesktopWindow(); - -private: - friend class TopLevelWindowManager; - bool useDropShadow, useNativeTitleBar, windowIsActive_; - DropShadower* shadower; - - void setWindowActive (const bool isNowActive) throw(); - - TopLevelWindow (const TopLevelWindow&); - const TopLevelWindow& operator= (const TopLevelWindow&); -}; - -#endif // __JUCE_TOPLEVELWINDOW_JUCEHEADER__ -/********* End of inlined file: juce_TopLevelWindow.h *********/ - -/********* Start of inlined file: juce_ResizableBorderComponent.h *********/ -#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ -#define __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ - -/** - A component that resizes its parent window when dragged. - - This component forms a frame around the edge of a component, allowing it to - be dragged by the edges or corners to resize it - like the way windows are - resized in MSWindows or Linux. - - To use it, just add it to your component, making it fill the entire parent component - (there's a mouse hit-test that only traps mouse-events which land around the - edge of the component, so it's even ok to put it on top of any other components - you're using). Make sure you rescale the resizer component to fill the parent - each time the parent's size changes. - - @see ResizableCornerComponent -*/ -class JUCE_API ResizableBorderComponent : public Component -{ -public: - - /** Creates a resizer. - - Pass in the target component which you want to be resized when this one is - dragged. - - The target component will usually be a parent of the resizer component, but this - isn't mandatory. - - Remember that when the target component is resized, it'll need to move and - resize this component to keep it in place, as this won't happen automatically. - - If the constrainer parameter is non-zero, then this object will be used to enforce - limits on the size and position that the component can be stretched to. Make sure - that the constrainer isn't deleted while still in use by this object. - - @see ComponentBoundsConstrainer - */ - ResizableBorderComponent (Component* const componentToResize, - ComponentBoundsConstrainer* const constrainer); - - /** Destructor. */ - ~ResizableBorderComponent(); - - /** Specifies how many pixels wide the draggable edges of this component are. - - @see getBorderThickness - */ - void setBorderThickness (const BorderSize& newBorderSize) throw(); - - /** Returns the number of pixels wide that the draggable edges of this component are. - - @see setBorderThickness - */ - const BorderSize getBorderThickness() const throw(); - - juce_UseDebuggingNewOperator - -protected: - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void mouseEnter (const MouseEvent& e); - /** @internal */ - void mouseMove (const MouseEvent& e); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - bool hitTest (int x, int y); - -private: - Component* const component; - ComponentBoundsConstrainer* constrainer; - BorderSize borderSize; - int originalX, originalY, originalW, originalH; - int mouseZone; - - void updateMouseZone (const MouseEvent& e) throw(); - - ResizableBorderComponent (const ResizableBorderComponent&); - const ResizableBorderComponent& operator= (const ResizableBorderComponent&); -}; - -#endif // __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ResizableBorderComponent.h *********/ - -/********* Start of inlined file: juce_ResizableCornerComponent.h *********/ -#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ -#define __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ - -/** A component that resizes a parent window when dragged. - - This is the small triangular stripey resizer component you get in the bottom-right - of windows (more commonly on the Mac than Windows). Put one in the corner of - a larger component and it will automatically resize its parent when it gets dragged - around. - - @see ResizableFrameComponent -*/ -class JUCE_API ResizableCornerComponent : public Component -{ -public: - - /** Creates a resizer. - - Pass in the target component which you want to be resized when this one is - dragged. - - The target component will usually be a parent of the resizer component, but this - isn't mandatory. - - Remember that when the target component is resized, it'll need to move and - resize this component to keep it in place, as this won't happen automatically. - - If the constrainer parameter is non-zero, then this object will be used to enforce - limits on the size and position that the component can be stretched to. Make sure - that the constrainer isn't deleted while still in use by this object. If you - pass a zero in here, no limits will be put on the sizes it can be stretched to. - - @see ComponentBoundsConstrainer - */ - ResizableCornerComponent (Component* const componentToResize, - ComponentBoundsConstrainer* const constrainer); - - /** Destructor. */ - ~ResizableCornerComponent(); - - juce_UseDebuggingNewOperator - -protected: - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void mouseUp (const MouseEvent& e); - /** @internal */ - bool hitTest (int x, int y); - -private: - - Component* const component; - ComponentBoundsConstrainer* constrainer; - int originalX, originalY, originalW, originalH; - - ResizableCornerComponent (const ResizableCornerComponent&); - const ResizableCornerComponent& operator= (const ResizableCornerComponent&); -}; - -#endif // __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ResizableCornerComponent.h *********/ - -/** - A base class for top-level windows that can be dragged around and resized. - - To add content to the window, use its setContentComponent() method to - give it a component that will remain positioned inside it (leaving a gap around - the edges for a border). - - It's not advisable to add child components directly to a ResizableWindow: put them - inside your content component instead. And overriding methods like resized(), moved(), etc - is also not recommended - instead override these methods for your content component. - (If for some obscure reason you do need to override these methods, always remember to - call the super-class's resized() method too, otherwise it'll fail to lay out the window - decorations correctly). - - By default resizing isn't enabled - use the setResizable() method to enable it and - to choose the style of resizing to use. - - @see TopLevelWindow -*/ -class JUCE_API ResizableWindow : public TopLevelWindow -{ -public: - - /** Creates a ResizableWindow. - - This constructor doesn't specify a background colour, so the LookAndFeel's default - background colour will be used. - - @param name the name to give the component - @param addToDesktop if true, the window will be automatically added to the - desktop; if false, you can use it as a child component - */ - ResizableWindow (const String& name, - const bool addToDesktop); - - /** Creates a ResizableWindow. - - @param name the name to give the component - @param backgroundColour the colour to use for filling the window's background. - @param addToDesktop if true, the window will be automatically added to the - desktop; if false, you can use it as a child component - */ - ResizableWindow (const String& name, - const Colour& backgroundColour, - const bool addToDesktop); - - /** Destructor. - - If a content component has been set with setContentComponent(), it - will be deleted. - */ - ~ResizableWindow(); - - /** Returns the colour currently being used for the window's background. - - As a convenience the window will fill itself with this colour, but you - can override the paint() method if you need more customised behaviour. - - This method is the same as retrieving the colour for ResizableWindow::backgroundColourId. - - @see setBackgroundColour - */ - const Colour getBackgroundColour() const throw(); - - /** Changes the colour currently being used for the window's background. - - As a convenience the window will fill itself with this colour, but you - can override the paint() method if you need more customised behaviour. - - Note that the opaque state of this window is altered by this call to reflect - the opacity of the colour passed-in. On window systems which can't support - semi-transparent windows this might cause problems, (though it's unlikely you'll - be using this class as a base for a semi-transparent component anyway). - - You can also use the ResizableWindow::backgroundColourId colour id to set - this colour. - - @see getBackgroundColour - */ - void setBackgroundColour (const Colour& newColour); - - /** Make the window resizable or fixed. - - @param shouldBeResizable whether it's resizable at all - @param useBottomRightCornerResizer if true, it'll add a ResizableCornerComponent at the - bottom-right; if false, it'll use a ResizableBorderComponent - around the edge - @see setResizeLimits, isResizable - */ - void setResizable (const bool shouldBeResizable, - const bool useBottomRightCornerResizer); - - /** True if resizing is enabled. - - @see setResizable - */ - bool isResizable() const throw(); - - /** This sets the maximum and minimum sizes for the window. - - If the window's current size is outside these limits, it will be resized to - make sure it's within them. - - Calling setBounds() on the component will bypass any size checking - it's only when - the window is being resized by the user that these values are enforced. - - @see setResizable, setFixedAspectRatio - */ - void setResizeLimits (const int newMinimumWidth, - const int newMinimumHeight, - const int newMaximumWidth, - const int newMaximumHeight) throw(); - - /** Returns the bounds constrainer object that this window is using. - - You can access this to change its properties. - */ - ComponentBoundsConstrainer* getConstrainer() throw() { return constrainer; } - - /** Sets the bounds-constrainer object to use for resizing and dragging this window. - - A pointer to the object you pass in will be kept, but it won't be deleted - by this object, so it's the caller's responsiblity to manage it. - - If you pass 0, then no contraints will be placed on the positioning of the window. - */ - void setConstrainer (ComponentBoundsConstrainer* newConstrainer); - - /** Calls the window's setBounds method, after first checking these bounds - with the current constrainer. - - @see setConstrainer - */ - void setBoundsConstrained (int x, int y, int width, int height); - - /** Returns true if the window is currently in full-screen mode. - - @see setFullScreen - */ - bool isFullScreen() const; - - /** Puts the window into full-screen mode, or restores it to its normal size. - - If true, the window will become full-screen; if false, it will return to the - last size it was before being made full-screen. - - @see isFullScreen - */ - void setFullScreen (const bool shouldBeFullScreen); - - /** Returns true if the window is currently minimised. - - @see setMinimised - */ - bool isMinimised() const; - - /** Minimises the window, or restores it to its previous position and size. - - When being un-minimised, it'll return to the last position and size it - was in before being minimised. - - @see isMinimised - */ - void setMinimised (const bool shouldMinimise); - - /** Returns a string which encodes the window's current size and position. - - This string will encapsulate the window's size, position, and whether it's - in full-screen mode. It's intended for letting your application save and - restore a window's position. - - Use the restoreWindowStateFromString() to restore from a saved state. - - @see restoreWindowStateFromString - */ - const String getWindowStateAsString(); - - /** Restores the window to a previously-saved size and position. - - This restores the window's size, positon and full-screen status from an - string that was previously created with the getWindowStateAsString() - method. - - @returns false if the string wasn't a valid window state - @see getWindowStateAsString - */ - bool restoreWindowStateFromString (const String& previousState); - - /** Returns the current content component. - - This will be the component set by setContentComponent(), or 0 if none - has yet been specified. - - @see setContentComponent - */ - Component* getContentComponent() const throw() { return contentComponent; } - - /** Changes the current content component. - - This sets a component that will be placed in the centre of the ResizableWindow, - (leaving a space around the edge for the border). - - You should never add components directly to a ResizableWindow (or any of its subclasses) - with addChildComponent(). Instead, add them to the content component. - - @param newContentComponent the new component to use (or null to not use one) - this - component will be deleted either when replaced by another call - to this method, or when the ResizableWindow is deleted. - To remove a content component without deleting it, use - setContentComponent (0, false). - @param deleteOldOne if true, the previous content component will be deleted; if - false, the previous component will just be removed without - deleting it. - @param resizeToFit if true, the ResizableWindow will maintain its size such that - it always fits around the size of the content component. If false, the - new content will be resized to fit the current space available. - */ - void setContentComponent (Component* const newContentComponent, - const bool deleteOldOne = true, - const bool resizeToFit = false); - - /** Changes the window so that the content component ends up with the specified size. - - This is basically a setSize call on the window, but which adds on the borders, - so you can specify the content component's target size. - */ - void setContentComponentSize (int width, int height); - - /** A set of colour IDs to use to change the colour of various aspects of the window. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */ - }; - - juce_UseDebuggingNewOperator - -protected: - /** @internal */ - void paint (Graphics& g); - /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */ - void moved(); - /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */ - void resized(); - /** @internal */ - void mouseDown (const MouseEvent& e); - /** @internal */ - void mouseDrag (const MouseEvent& e); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - void childBoundsChanged (Component* child); - /** @internal */ - void parentSizeChanged(); - /** @internal */ - void visibilityChanged(); - /** @internal */ - void activeWindowStatusChanged(); - /** @internal */ - int getDesktopWindowStyleFlags() const; - - /** Returns the width of the border to use around the window. - - @see getContentComponentBorder - */ - virtual const BorderSize getBorderThickness(); - - /** Returns the insets to use when positioning the content component. - - @see getBorderThickness - */ - virtual const BorderSize getContentComponentBorder(); - -#ifdef JUCE_DEBUG - /** Overridden to warn people about adding components directly to this component - instead of using setContentComponent(). - - If you know what you're doing and are sure you really want to add a component, specify - a base-class method call to Component::addAndMakeVisible(), to side-step this warning. - */ - void addChildComponent (Component* const child, int zOrder = -1); - /** Overridden to warn people about adding components directly to this component - instead of using setContentComponent(). - - If you know what you're doing and are sure you really want to add a component, specify - a base-class method call to Component::addAndMakeVisible(), to side-step this warning. - */ - void addAndMakeVisible (Component* const child, int zOrder = -1); + static MenuBarModel* getMacMainMenu() throw(); #endif - ResizableCornerComponent* resizableCorner; - ResizableBorderComponent* resizableBorder; + /** @internal */ + void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info); + /** @internal */ + void applicationCommandListChanged(); + /** @internal */ + void handleAsyncUpdate(); + + juce_UseDebuggingNewOperator private: - Component* contentComponent; - bool resizeToFitContent, fullscreen; - ComponentDragger dragger; - Rectangle lastNonFullScreenPos; - ComponentBoundsConstrainer defaultConstrainer; - ComponentBoundsConstrainer* constrainer; - #ifdef JUCE_DEBUG - bool hasBeenResized; - #endif + ApplicationCommandManager* manager; + SortedSet listeners; - void updateLastPos(); - - ResizableWindow (const ResizableWindow&); - const ResizableWindow& operator= (const ResizableWindow&); - - // (xxx remove these eventually) - // temporarily here to stop old code compiling, as the parameters for these methods have changed.. - void getBorderThickness (int& left, int& top, int& right, int& bottom); - // temporarily here to stop old code compiling, as the parameters for these methods have changed.. - void getContentComponentBorder (int& left, int& top, int& right, int& bottom); + MenuBarModel (const MenuBarModel&); + const MenuBarModel& operator= (const MenuBarModel&); }; -#endif // __JUCE_RESIZABLEWINDOW_JUCEHEADER__ -/********* End of inlined file: juce_ResizableWindow.h *********/ +#endif // __JUCE_MENUBARMODEL_JUCEHEADER__ +/********* End of inlined file: juce_MenuBarModel.h *********/ + +/** + A menu bar component. + + @see MenuBarModel +*/ +class JUCE_API MenuBarComponent : public Component, + private MenuBarModelListener, + private Timer +{ +public: + + /** Creates a menu bar. + + @param model the model object to use to control this bar. You can + pass 0 into this if you like, and set the model later + using the setModel() method + */ + MenuBarComponent (MenuBarModel* const model); + + /** Destructor. */ + ~MenuBarComponent(); + + /** Changes the model object to use to control the bar. + + This can be 0, in which case the bar will be empty. Don't delete the object + that is passed-in while it's still being used by this MenuBar. + */ + void setModel (MenuBarModel* const newModel); + + /** Pops up one of the menu items. + + This lets you manually open one of the menus - it could be triggered by a + key shortcut, for example. + */ + void showMenu (const int menuIndex); + + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void resized(); + /** @internal */ + void mouseEnter (const MouseEvent& e); + /** @internal */ + void mouseExit (const MouseEvent& e); + /** @internal */ + void mouseDown (const MouseEvent& e); + /** @internal */ + void mouseDrag (const MouseEvent& e); + /** @internal */ + void mouseUp (const MouseEvent& e); + /** @internal */ + void mouseMove (const MouseEvent& e); + /** @internal */ + void inputAttemptWhenModal(); + /** @internal */ + void handleCommandMessage (int commandId); + /** @internal */ + bool keyPressed (const KeyPress& key); + /** @internal */ + void menuBarItemsChanged (MenuBarModel* menuBarModel); + /** @internal */ + void menuCommandInvoked (MenuBarModel* menuBarModel, + const ApplicationCommandTarget::InvocationInfo& info); + + juce_UseDebuggingNewOperator + +private: + MenuBarModel* model; + + StringArray menuNames; + Array xPositions; + int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain; + int lastMouseX, lastMouseY; + bool inModalState; + Component* currentPopup; + + int getItemAt (int x, int y); + void updateItemUnderMouse (const int x, const int y); + void hideCurrentMenu(); + void timerCallback(); + void repaintMenuItem (int index); + + MenuBarComponent (const MenuBarComponent&); + const MenuBarComponent& operator= (const MenuBarComponent&); +}; + +#endif // __JUCE_MENUBARCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_MenuBarComponent.h *********/ /** A resizable window with a title bar and maximise, minimise and close buttons. @@ -50999,1435 +49863,132 @@ private: #ifndef __JUCE_VIEWPORT_JUCEHEADER__ #endif -#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ +#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ -/********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ -#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ -#define __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_DirectoryContentsList.h *********/ -#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ -#define __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ - -/********* Start of inlined file: juce_FileFilter.h *********/ -#ifndef __JUCE_FILEFILTER_JUCEHEADER__ -#define __JUCE_FILEFILTER_JUCEHEADER__ - -/** - Interface for deciding which files are suitable for something. - - For example, this is used by DirectoryContentsList to select which files - go into the list. - - @see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent -*/ -class JUCE_API FileFilter -{ -public: - - /** Creates a filter with the given description. - - The description can be returned later with the getDescription() method. - */ - FileFilter (const String& filterDescription); - - /** Destructor. */ - virtual ~FileFilter(); - - /** Returns the description that the filter was created with. */ - const String& getDescription() const throw(); - - /** Should return true if this file is suitable for inclusion in whatever context - the object is being used. - */ - virtual bool isFileSuitable (const File& file) const = 0; - - /** Should return true if this directory is suitable for inclusion in whatever context - the object is being used. - */ - virtual bool isDirectorySuitable (const File& file) const = 0; - -protected: - - String description; -}; - -#endif // __JUCE_FILEFILTER_JUCEHEADER__ -/********* End of inlined file: juce_FileFilter.h *********/ - -/** - A class to asynchronously scan for details about the files in a directory. - - This keeps a list of files and some information about them, using a background - thread to scan for more files. As files are found, it broadcasts change messages - to tell any listeners. - - @see FileListComponent, FileBrowserComponent -*/ -class JUCE_API DirectoryContentsList : public ChangeBroadcaster, - public TimeSliceClient -{ -public: - - /** Creates a directory list. - - To set the directory it should point to, use setDirectory(), which will - also start it scanning for files on the background thread. - - When the background thread finds and adds new files to this list, the - ChangeBroadcaster class will send a change message, so you can register - listeners and update them when the list changes. - - @param fileFilter an optional filter to select which files are - included in the list. If this is 0, then all files - and directories are included. Make sure that the - filter doesn't get deleted during the lifetime of this - object - @param threadToUse a thread object that this list can use - to scan for files as a background task. Make sure - that the thread you give it has been started, or you - won't get any files! - */ - DirectoryContentsList (const FileFilter* const fileFilter, - TimeSliceThread& threadToUse); - - /** Destructor. */ - ~DirectoryContentsList(); - - /** Sets the directory to look in for files. - - If the directory that's passed in is different to the current one, this will - also start the background thread scanning it for files. - */ - void setDirectory (const File& directory, - const bool includeDirectories, - const bool includeFiles); - - /** Returns the directory that's currently being used. */ - const File& getDirectory() const throw(); - - /** Clears the list, and stops the thread scanning for files. */ - void clear(); - - /** Clears the list and restarts scanning the directory for files. */ - void refresh(); - - /** True if the background thread hasn't yet finished scanning for files. */ - bool isStillLoading() const; - - /** Tells the list whether or not to ignore hidden files. - - By default these are ignored. - */ - void setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles); - - /** Returns true if hidden files are ignored. - @see setIgnoresHiddenFiles - */ - bool ignoresHiddenFiles() const throw() { return ignoreHiddenFiles; } - - /** Contains cached information about one of the files in a DirectoryContentsList. - */ - struct FileInfo - { - - /** The filename. - - This isn't a full pathname, it's just the last part of the path, same as you'd - get from File::getFileName(). - - To get the full pathname, use DirectoryContentsList::getDirectory().getChildFile (filename). - */ - String filename; - - /** File size in bytes. */ - int64 fileSize; - - /** File modification time. - - As supplied by File::getLastModificationTime(). - */ - Time modificationTime; - - /** File creation time. - - As supplied by File::getCreationTime(). - */ - Time creationTime; - - /** True if the file is a directory. */ - bool isDirectory; - - /** True if the file is read-only. */ - bool isReadOnly; - }; - - /** Returns the number of files currently available in the list. - - The info about one of these files can be retrieved with getFileInfo() or - getFile(). - - Obviously as the background thread runs and scans the directory for files, this - number will change. - - @see getFileInfo, getFile - */ - int getNumFiles() const; - - /** Returns the cached information about one of the files in the list. - - If the index is in-range, this will return true and will copy the file's details - to the structure that is passed-in. - - If it returns false, then the index wasn't in range, and the structure won't - be affected. - - @see getNumFiles, getFile - */ - bool getFileInfo (const int index, - FileInfo& resultInfo) const; - - /** Returns one of the files in the list. - - @param index should be less than getNumFiles(). If this is out-of-range, the - return value will be File::nonexistent - @see getNumFiles, getFileInfo - */ - const File getFile (const int index) const; - - /** Returns the file filter being used. - - The filter is specified in the constructor. - */ - const FileFilter* getFilter() const throw() { return fileFilter; } - - /** @internal */ - bool useTimeSlice(); - /** @internal */ - TimeSliceThread& getTimeSliceThread() throw() { return thread; } - /** @internal */ - static int compareElements (const DirectoryContentsList::FileInfo* const first, - const DirectoryContentsList::FileInfo* const second) throw(); - - juce_UseDebuggingNewOperator - -private: - File root; - const FileFilter* fileFilter; - TimeSliceThread& thread; - bool includeDirectories, includeFiles, ignoreHiddenFiles; - - CriticalSection fileListLock; - OwnedArray files; - - void* volatile fileFindHandle; - bool volatile shouldStop; - - void changed(); - bool checkNextFile (bool& hasChanged); - bool addFile (const String& filename, const bool isDir, const bool isHidden, - const int64 fileSize, const Time& modTime, - const Time& creationTime, const bool isReadOnly); - - DirectoryContentsList (const DirectoryContentsList&); - const DirectoryContentsList& operator= (const DirectoryContentsList&); -}; - -#endif // __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ -/********* End of inlined file: juce_DirectoryContentsList.h *********/ - -/********* Start of inlined file: juce_FileBrowserListener.h *********/ -#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ -#define __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ - -/** - A listener for user selection events in a file browser. - - This is used by a FileBrowserComponent or FileListComponent. -*/ -class JUCE_API FileBrowserListener -{ -public: - - /** Destructor. */ - virtual ~FileBrowserListener(); - - /** Callback when the user selects a different file in the browser. */ - virtual void selectionChanged() = 0; - - /** Callback when the user clicks on a file in the browser. */ - virtual void fileClicked (const File& file, const MouseEvent& e) = 0; - - /** Callback when the user double-clicks on a file in the browser. */ - virtual void fileDoubleClicked (const File& file) = 0; -}; - -#endif // __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ -/********* End of inlined file: juce_FileBrowserListener.h *********/ - -/** - A base class for components that display a list of the files in a directory. - - @see DirectoryContentsList -*/ -class JUCE_API DirectoryContentsDisplayComponent -{ -public: - - /** - */ - DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - virtual ~DirectoryContentsDisplayComponent(); - - /** Returns the number of files the user has got selected. - @see getSelectedFile - */ - virtual int getNumSelectedFiles() const = 0; - - /** Returns one of the files that the user has currently selected. - The index should be in the range 0 to (getNumSelectedFiles() - 1). - @see getNumSelectedFiles - */ - virtual const File getSelectedFile (int index) const = 0; - - /** Scrolls this view to the top. */ - virtual void scrollToTop() = 0; - - /** Adds a listener to be told when files are selected or clicked. - - @see removeListener - */ - void addListener (FileBrowserListener* const listener) throw(); - - /** Removes a listener. - - @see addListener - */ - void removeListener (FileBrowserListener* const listener) throw(); - - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - Note that you can also use the constants from TextEditor::ColourIds to change the - colour of the text editor that is opened when a label is editable. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - highlightColourId = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */ - textColourId = 0x1000541, /**< The colour for the text. */ - }; - - /** @internal */ - void sendSelectionChangeMessage(); - /** @internal */ - void sendDoubleClickMessage (const File& file); - /** @internal */ - void sendMouseClickMessage (const File& file, const MouseEvent& e); - - juce_UseDebuggingNewOperator - -protected: - DirectoryContentsList& fileList; - SortedSet listeners; - - DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&); - const DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&); -}; - -#endif // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/ - -#endif -#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FileListComponent.h *********/ -#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ -#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__ - -/** - A component that displays the files in a directory as a listbox. - - This implements the DirectoryContentsDisplayComponent base class so that - it can be used in a FileBrowserComponent. - - To attach a listener to it, use its DirectoryContentsDisplayComponent base - class and the FileBrowserListener class. - - @see DirectoryContentsList, FileTreeComponent -*/ -class JUCE_API FileListComponent : public ListBox, - public DirectoryContentsDisplayComponent, - private ListBoxModel, - private ChangeListener -{ -public: - - /** Creates a listbox to show the contents of a specified directory. - */ - FileListComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileListComponent(); - - /** Returns the number of files the user has got selected. - @see getSelectedFile - */ - int getNumSelectedFiles() const; - - /** Returns one of the files that the user has currently selected. - The index should be in the range 0 to (getNumSelectedFiles() - 1). - @see getNumSelectedFiles - */ - const File getSelectedFile (int index = 0) const; - - /** Scrolls to the top of the list. */ - void scrollToTop(); - - /** @internal */ - void changeListenerCallback (void*); - /** @internal */ - int getNumRows(); - /** @internal */ - void paintListBoxItem (int, Graphics&, int, int, bool); - /** @internal */ - Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate); - /** @internal */ - void selectedRowsChanged (int lastRowSelected); - /** @internal */ - void deleteKeyPressed (int currentSelectedRow); - /** @internal */ - void returnKeyPressed (int currentSelectedRow); - - juce_UseDebuggingNewOperator - -private: - FileListComponent (const FileListComponent&); - const FileListComponent& operator= (const FileListComponent&); - - File lastDirectory; -}; - -#endif // __JUCE_FILELISTCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileListComponent.h *********/ - -#endif -#ifndef __JUCE_FILEFILTER_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FileTreeComponent.h *********/ -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ -#define __JUCE_FILETREECOMPONENT_JUCEHEADER__ - -/** - A component that displays the files in a directory as a treeview. - - This implements the DirectoryContentsDisplayComponent base class so that - it can be used in a FileBrowserComponent. - - To attach a listener to it, use its DirectoryContentsDisplayComponent base - class and the FileBrowserListener class. - - @see DirectoryContentsList, FileListComponent -*/ -class JUCE_API FileTreeComponent : public TreeView, - public DirectoryContentsDisplayComponent -{ -public: - - /** Creates a listbox to show the contents of a specified directory. - */ - FileTreeComponent (DirectoryContentsList& listToShow); - - /** Destructor. */ - ~FileTreeComponent(); - - /** Returns the number of files the user has got selected. - @see getSelectedFile - */ - int getNumSelectedFiles() const { return TreeView::getNumSelectedItems(); } - - /** Returns one of the files that the user has currently selected. - The index should be in the range 0 to (getNumSelectedFiles() - 1). - @see getNumSelectedFiles - */ - const File getSelectedFile (int index = 0) const; - - /** Scrolls the list to the top. */ - void scrollToTop(); - - /** Setting a name for this allows tree items to be dragged. - - The string that you pass in here will be returned by the getDragSourceDescription() - of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription(). - */ - void setDragAndDropDescription (const String& description) throw(); - - /** Returns the last value that was set by setDragAndDropDescription(). - */ - const String& getDragAndDropDescription() const throw() { return dragAndDropDescription; } - - juce_UseDebuggingNewOperator - -private: - String dragAndDropDescription; - - FileTreeComponent (const FileTreeComponent&); - const FileTreeComponent& operator= (const FileTreeComponent&); -}; - -#endif // __JUCE_FILETREECOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileTreeComponent.h *********/ - -#endif -#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ - -/********* Start of inlined file: juce_FileChooserDialogBox.h *********/ -#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ -#define __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ - -/********* Start of inlined file: juce_FileBrowserComponent.h *********/ -#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FilePreviewComponent.h *********/ -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - -/** - Base class for components that live inside a file chooser dialog box and - show previews of the files that get selected. - - One of these allows special extra information to be displayed for files - in a dialog box as the user selects them. Each time the current file or - directory is changed, the selectedFileChanged() method will be called - to allow it to update itself appropriately. - - @see FileChooser, ImagePreviewComponent -*/ -class JUCE_API FilePreviewComponent : public Component -{ -public: - - /** Creates a FilePreviewComponent. */ - FilePreviewComponent(); - - /** Destructor. */ - ~FilePreviewComponent(); - - /** Called to indicate that the user's currently selected file has changed. - - @param newSelectedFile the newly selected file or directory, which may be - File::nonexistent if none is selected. - */ - virtual void selectedFileChanged (const File& newSelectedFile) = 0; - - juce_UseDebuggingNewOperator - -private: - FilePreviewComponent (const FilePreviewComponent&); - const FilePreviewComponent& operator= (const FilePreviewComponent&); -}; - -#endif // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FilePreviewComponent.h *********/ - -/** - A component for browsing and selecting a file or directory to open or save. - - This contains a FileListComponent and adds various boxes and controls for - navigating and selecting a file. It can work in different modes so that it can - be used for loading or saving a file, or for choosing a directory. - - @see FileChooserDialogBox, FileChooser, FileListComponent -*/ -class JUCE_API FileBrowserComponent : public Component, - public ChangeBroadcaster, - private FileBrowserListener, - private TextEditorListener, - private ButtonListener, - private ComboBoxListener, - private FileFilter -{ -public: - - /** Various options for the browser. - - A combination of these is passed into the FileBrowserComponent constructor. - */ - enum FileChooserFlags - { - openMode = 1, /**< specifies that the component should allow the user to - choose an existing file with the intention of opening it. */ - saveMode = 2, /**< specifies that the component should allow the user to specify - the name of a file that will be used to save something. */ - canSelectFiles = 4, /**< specifies that the user can select files (can be used in - conjunction with canSelectDirectories). */ - canSelectDirectories = 8, /**< specifies that the user can select directories (can be used in - conjuction with canSelectFiles). */ - canSelectMultipleItems = 16, /**< specifies that the user can select multiple items. */ - useTreeView = 32, /**< specifies that a tree-view should be shown instead of a file list. */ - filenameBoxIsReadOnly = 64 /**< specifies that the user can't type directly into the filename box. */ - }; - - /** Creates a FileBrowserComponent. - - @param flags A combination of flags from the FileChooserFlags enumeration, - used to specify the component's behaviour. The flags must contain - either openMode or saveMode, and canSelectFiles and/or - canSelectDirectories. - @param initialFileOrDirectory The file or directory that should be selected when - the component begins. If this is File::nonexistent, - a default directory will be chosen. - @param fileFilter an optional filter to use to determine which files - are shown. If this is 0 then all files are displayed. Note - that a pointer is kept internally to this object, so - make sure that it is not deleted before the browser object - is deleted. - @param previewComp an optional preview component that will be used to - show previews of files that the user selects - */ - FileBrowserComponent (int flags, - const File& initialFileOrDirectory, - const FileFilter* fileFilter, - FilePreviewComponent* previewComp); - - /** Destructor. */ - ~FileBrowserComponent(); - - /** Returns the number of files that the user has got selected. - If multiple select isn't active, this will only be 0 or 1. To get the complete - list of files they've chosen, pass an index to getCurrentFile(). - */ - int getNumSelectedFiles() const throw(); - - /** Returns one of the files that the user has chosen. - If the box has multi-select enabled, the index lets you specify which of the files - to get - see getNumSelectedFiles() to find out how many files were chosen. - @see getHighlightedFile - */ - const File getSelectedFile (int index) const throw(); - - /** Returns true if the currently selected file(s) are usable. - - This can be used to decide whether the user can press "ok" for the - current file. What it does depends on the mode, so for example in an "open" - mode, this only returns true if a file has been selected and if it exists. - In a "save" mode, a non-existent file would also be valid. - */ - bool currentFileIsValid() const; - - /** This returns the last item in the view that the user has highlighted. - This may be different from getCurrentFile(), which returns the value - that is shown in the filename box, and if there are multiple selections, - this will only return one of them. - @see getCurrentFile - */ - const File getHighlightedFile() const throw(); - - /** Returns the directory whose contents are currently being shown in the listbox. */ - const File getRoot() const; - - /** Changes the directory that's being shown in the listbox. */ - void setRoot (const File& newRootDirectory); - - /** Equivalent to pressing the "up" button to browse the parent directory. */ - void goUp(); - - /** Refreshes the directory that's currently being listed. */ - void refresh(); - - /** Returns a verb to describe what should happen when the file is accepted. - - E.g. if browsing in "load file" mode, this will be "Open", if in "save file" - mode, it'll be "Save", etc. - */ - virtual const String getActionVerb() const; - - /** Returns true if the saveMode flag was set when this component was created. - */ - bool isSaveMode() const throw(); - - /** Adds a listener to be told when the user selects and clicks on files. - - @see removeListener - */ - void addListener (FileBrowserListener* const listener) throw(); - - /** Removes a listener. - - @see addListener - */ - void removeListener (FileBrowserListener* const listener) throw(); - - /** @internal */ - void resized(); - /** @internal */ - void buttonClicked (Button* b); - /** @internal */ - void comboBoxChanged (ComboBox*); - /** @internal */ - void textEditorTextChanged (TextEditor& editor); - /** @internal */ - void textEditorReturnKeyPressed (TextEditor& editor); - /** @internal */ - void textEditorEscapeKeyPressed (TextEditor& editor); - /** @internal */ - void textEditorFocusLost (TextEditor& editor); - /** @internal */ - bool keyPressed (const KeyPress& key); - /** @internal */ - void selectionChanged(); - /** @internal */ - void fileClicked (const File& f, const MouseEvent& e); - /** @internal */ - void fileDoubleClicked (const File& f); - /** @internal */ - bool isFileSuitable (const File& file) const; - /** @internal */ - bool isDirectorySuitable (const File&) const; - - /** @internal */ - FilePreviewComponent* getPreviewComponent() const throw(); - - juce_UseDebuggingNewOperator - -protected: - virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths); - -private: - - DirectoryContentsList* fileList; - const FileFilter* fileFilter; - - int flags; - File currentRoot; - OwnedArray chosenFiles; - SortedSet listeners; - - DirectoryContentsDisplayComponent* fileListComponent; - FilePreviewComponent* previewComp; - ComboBox* currentPathBox; - TextEditor* filenameBox; - Button* goUpButton; - - TimeSliceThread thread; - - void sendListenerChangeMessage(); - bool isFileOrDirSuitable (const File& f) const; - - FileBrowserComponent (const FileBrowserComponent&); - const FileBrowserComponent& operator= (const FileBrowserComponent&); -}; - -#endif // __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileBrowserComponent.h *********/ - -/** - A file open/save dialog box. - - This is a Juce-based file dialog box; to use a native file chooser, see the - FileChooser class. - - To use one of these, create it and call its show() method. e.g. - - @code - { - WildcardFileFilter wildcardFilter (T("*.foo"), T("Foo files")); - - FileBrowserComponent browser (FileBrowserComponent::loadFileMode, - File::nonexistent, - &wildcardFilter, - 0); - - FileChooserDialogBox dialogBox (T("Open some kind of file"), - T("Please choose some kind of file that you want to open..."), - browser, - getLookAndFeel().alertWindowBackground); - - if (dialogBox.show()) - { - File selectedFile = browser.getCurrentFile(); - ... - } - } - @endcode - - @see FileChooser -*/ -class JUCE_API FileChooserDialogBox : public ResizableWindow, - public ButtonListener, - public FileBrowserListener -{ -public: - - /** Creates a file chooser box. - - @param title the main title to show at the top of the box - @param instructions an optional longer piece of text to show below the title in - a smaller font, describing in more detail what's required. - @param browserComponent a FileBrowserComponent that will be shown inside this dialog - box. Make sure you delete this after (but not before!) the - dialog box has been deleted. - @param warnAboutOverwritingExistingFiles if true, then the user will be asked to confirm - if they try to select a file that already exists. (This - flag is only used when saving files) - @param backgroundColour the background colour for the top level window - - @see FileBrowserComponent, FilePreviewComponent - */ - FileChooserDialogBox (const String& title, - const String& instructions, - FileBrowserComponent& browserComponent, - const bool warnAboutOverwritingExistingFiles, - const Colour& backgroundColour); - - /** Destructor. */ - ~FileChooserDialogBox(); - - /** Displays and runs the dialog box modally. - - This will show the box with the specified size, returning true if the user - pressed 'ok', or false if they cancelled. - - Leave the width or height as 0 to use the default size - */ - bool show (int width = 0,int height = 0); - - /** @internal */ - void buttonClicked (Button* button); - /** @internal */ - void closeButtonPressed(); - /** @internal */ - void selectionChanged(); - /** @internal */ - void fileClicked (const File& file, const MouseEvent& e); - /** @internal */ - void fileDoubleClicked (const File& file); - - juce_UseDebuggingNewOperator - -private: - class ContentComponent : public Component - { - public: - ContentComponent(); - ~ContentComponent(); - - void paint (Graphics& g); - void resized(); - - String instructions; - GlyphArrangement text; - - FileBrowserComponent* chooserComponent; - FilePreviewComponent* previewComponent; - TextButton* okButton; - TextButton* cancelButton; - }; - - ContentComponent* content; - const bool warnAboutOverwritingExistingFiles; - - FileChooserDialogBox (const FileChooserDialogBox&); - const FileChooserDialogBox& operator= (const FileChooserDialogBox&); -}; - -#endif // __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ -/********* End of inlined file: juce_FileChooserDialogBox.h *********/ - -#endif -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FilenameComponent.h *********/ -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ -#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - -class FilenameComponent; - -/** - Listens for events happening to a FilenameComponent. - - Use FilenameComponent::addListener() and FilenameComponent::removeListener() to - register one of these objects for event callbacks when the filename is changed. - - @see FilenameComponent -*/ -class JUCE_API FilenameComponentListener -{ -public: - /** Destructor. */ - virtual ~FilenameComponentListener() {} - - /** This method is called after the FilenameComponent's file has been changed. */ - virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0; -}; - -/** - Shows a filename as an editable text box, with a 'browse' button and a - drop-down list for recently selected files. - - A handy component for dialogue boxes where you want the user to be able to - select a file or directory. - - Attach an FilenameComponentListener using the addListener() method, and it will - get called each time the user changes the filename, either by browsing for a file - and clicking 'ok', or by typing a new filename into the box and pressing return. - - @see FileChooser, ComboBox -*/ -class JUCE_API FilenameComponent : public Component, - public SettableTooltipClient, - public FileDragAndDropTarget, - private AsyncUpdater, - private ButtonListener, - private ComboBoxListener -{ -public: - - /** Creates a FilenameComponent. - - @param name the name for this component. - @param currentFile the file to initially show in the box - @param canEditFilename if true, the user can manually edit the filename; if false, - they can only change it by browsing for a new file - @param isDirectory if true, the file will be treated as a directory, and - an appropriate directory browser used - @param isForSaving if true, the file browser will allow non-existent files to - be picked, as the file is assumed to be used for saving rather - than loading - @param fileBrowserWildcard a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo". - If an empty string is passed in, then the pattern is assumed to be "*" - @param enforcedSuffix if this is non-empty, it is treated as a suffix that will be added - to any filenames that are entered or chosen - @param textWhenNothingSelected the message to display in the box before any filename is entered. (This - will only appear if the initial file isn't valid) - */ - FilenameComponent (const String& name, - const File& currentFile, - const bool canEditFilename, - const bool isDirectory, - const bool isForSaving, - const String& fileBrowserWildcard, - const String& enforcedSuffix, - const String& textWhenNothingSelected); - - /** Destructor. */ - ~FilenameComponent(); - - /** Returns the currently displayed filename. */ - const File getCurrentFile() const; - - /** Changes the current filename. - - If addToRecentlyUsedList is true, the filename will also be added to the - drop-down list of recent files. - - If sendChangeNotification is false, then the listeners won't be told of the - change. - */ - void setCurrentFile (File newFile, - const bool addToRecentlyUsedList, - const bool sendChangeNotification = true); - - /** Changes whether the use can type into the filename box. - */ - void setFilenameIsEditable (const bool shouldBeEditable); - - /** Sets a file or directory to be the default starting point for the browser to show. - - This is only used if the current file hasn't been set. - */ - void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - - /** Returns all the entries on the recent files list. - - This can be used in conjunction with setRecentlyUsedFilenames() for saving the - state of this list. - - @see setRecentlyUsedFilenames - */ - const StringArray getRecentlyUsedFilenames() const; - - /** Sets all the entries on the recent files list. - - This can be used in conjunction with getRecentlyUsedFilenames() for saving the - state of this list. - - @see getRecentlyUsedFilenames, addRecentlyUsedFile - */ - void setRecentlyUsedFilenames (const StringArray& filenames); - - /** Adds an entry to the recently-used files dropdown list. - - If the file is already in the list, it will be moved to the top. A limit - is also placed on the number of items that are kept in the list. - - @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles - */ - void addRecentlyUsedFile (const File& file); - - /** Changes the limit for the number of files that will be stored in the recent-file list. - */ - void setMaxNumberOfRecentFiles (const int newMaximum); - - /** Changes the text shown on the 'browse' button. - - By default this button just says "..." but you can change it. The button itself - can be changed using the look-and-feel classes, so it might not actually have any - text on it. - */ - void setBrowseButtonText (const String& browseButtonText); - - /** Adds a listener that will be called when the selected file is changed. */ - void addListener (FilenameComponentListener* const listener) throw(); - - /** Removes a previously-registered listener. */ - void removeListener (FilenameComponentListener* const listener) throw(); - - /** Gives the component a tooltip. */ - void setTooltip (const String& newTooltip); - - /** @internal */ - void paintOverChildren (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void lookAndFeelChanged(); - /** @internal */ - bool isInterestedInFileDrag (const StringArray& files); - /** @internal */ - void filesDropped (const StringArray& files, int, int); - /** @internal */ - void fileDragEnter (const StringArray& files, int, int); - /** @internal */ - void fileDragExit (const StringArray& files); - - juce_UseDebuggingNewOperator - -private: - - ComboBox* filenameBox; - String lastFilename; - Button* browseButton; - int maxRecentFiles; - bool isDir, isSaving, isFileDragOver; - String wildcard, enforcedSuffix, browseButtonText; - SortedSet listeners; - File defaultBrowseFile; - - void comboBoxChanged (ComboBox*); - void buttonClicked (Button* button); - void handleAsyncUpdate(); - - FilenameComponent (const FilenameComponent&); - const FilenameComponent& operator= (const FilenameComponent&); -}; - -#endif // __JUCE_FILENAMECOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FilenameComponent.h *********/ - -#endif -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/ -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ -#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - -/** - Shows a set of file paths in a list, allowing them to be added, removed or - re-ordered. - - @see FileSearchPath -*/ -class JUCE_API FileSearchPathListComponent : public Component, - public SettableTooltipClient, - public FileDragAndDropTarget, - private ButtonListener, - private ListBoxModel -{ -public: - - /** Creates an empty FileSearchPathListComponent. - - */ - FileSearchPathListComponent(); - - /** Destructor. */ - ~FileSearchPathListComponent(); - - /** Returns the path as it is currently shown. */ - const FileSearchPath& getPath() const throw() { return path; } - - /** Changes the current path. */ - void setPath (const FileSearchPath& newPath); - - /** Sets a file or directory to be the default starting point for the browser to show. - - This is only used if the current file hasn't been set. - */ - void setDefaultBrowseTarget (const File& newDefaultDirectory) throw(); - - /** A set of colour IDs to use to change the colour of various aspects of the label. - - These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() - methods. - - @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour - */ - enum ColourIds - { - backgroundColourId = 0x1004100, /**< The background colour to fill the component with. - Make this transparent if you don't want the background to be filled. */ - }; - - /** @internal */ - int getNumRows(); - /** @internal */ - void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected); - /** @internal */ - void deleteKeyPressed (int lastRowSelected); - /** @internal */ - void returnKeyPressed (int lastRowSelected); - /** @internal */ - void listBoxItemDoubleClicked (int row, const MouseEvent&); - /** @internal */ - void selectedRowsChanged (int lastRowSelected); - /** @internal */ - void resized(); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - bool isInterestedInFileDrag (const StringArray& files); - /** @internal */ - void filesDropped (const StringArray& files, int, int); - /** @internal */ - void buttonClicked (Button* button); - - juce_UseDebuggingNewOperator - -private: - - FileSearchPath path; - File defaultBrowseTarget; - - ListBox* listBox; - Button* addButton; - Button* removeButton; - Button* changeButton; - Button* upButton; - Button* downButton; - - void changed() throw(); - void updateButtons() throw(); - - FileSearchPathListComponent (const FileSearchPathListComponent&); - const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&); -}; - -#endif // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_FileSearchPathListComponent.h *********/ - -#endif -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - -/********* Start of inlined file: juce_WildcardFileFilter.h *********/ -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ -#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - -/** - A type of FileFilter that works by wildcard pattern matching. - - This filter only allows files that match one of the specified patterns, but - allows all directories through. - - @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent -*/ -class JUCE_API WildcardFileFilter : public FileFilter -{ -public: - - /** - Creates a wildcard filter for one or more patterns. - - The wildcardPatterns parameter is a comma or semicolon-delimited set of - patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav - or .aiff. - - The description is a name to show the user in a list of possible patterns, so - for the wav/aiff example, your description might be "audio files". - */ - WildcardFileFilter (const String& fileWildcardPatterns, - const String& directoryWildcardPatterns, - const String& description); - - /** Destructor. */ - ~WildcardFileFilter(); - - /** Returns true if the filename matches one of the patterns specified. */ - bool isFileSuitable (const File& file) const; - - /** This always returns true. */ - bool isDirectorySuitable (const File& file) const; - - juce_UseDebuggingNewOperator - -private: - StringArray fileWildcards, directoryWildcards; - - static void parse (const String& pattern, StringArray& result) throw(); - static bool match (const File& file, const StringArray& wildcards) throw(); -}; - -#endif // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ -/********* End of inlined file: juce_WildcardFileFilter.h *********/ - -#endif -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_ImagePreviewComponent.h *********/ -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ -#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - -/** - A simple preview component that shows thumbnails of image files. - - @see FileChooserDialogBox, FilePreviewComponent -*/ -class JUCE_API ImagePreviewComponent : public FilePreviewComponent, - private Timer -{ -public: - - /** Creates an ImagePreviewComponent. */ - ImagePreviewComponent(); - - /** Destructor. */ - ~ImagePreviewComponent(); - - /** @internal */ - void selectedFileChanged (const File& newSelectedFile); - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void timerCallback(); - - juce_UseDebuggingNewOperator - -private: - File fileToLoad; - Image* currentThumbnail; - String currentDetails; - - void getThumbSize (int& w, int& h) const; - - ImagePreviewComponent (const ImagePreviewComponent&); - const ImagePreviewComponent& operator= (const ImagePreviewComponent&); -}; - -#endif // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_ImagePreviewComponent.h *********/ - -#endif -#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ - -#endif -#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ - -/********* Start of inlined file: juce_FileChooser.h *********/ -#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ -#define __JUCE_FILECHOOSER_JUCEHEADER__ - -/** - Creates a dialog box to choose a file or directory to load or save. - - To use a FileChooser: - - create one (as a local stack variable is the neatest way) - - call one of its browseFor.. methods - - if this returns true, the user has selected a file, so you can retrieve it - with the getResult() method. - - e.g. @code - void loadMooseFile() - { - FileChooser myChooser ("Please select the moose you want to load...", - File::getSpecialLocation (File::userHomeDirectory), - "*.moose"); - - if (myChooser.browseForFileToOpen()) - { - File mooseFile (myChooser.getResult()); - - loadMoose (mooseFile); - } - } - @endcode -*/ -class JUCE_API FileChooser -{ -public: - - /** Creates a FileChooser. - - After creating one of these, use one of the browseFor... methods to display it. - - @param dialogBoxTitle a text string to display in the dialog box to - tell the user what's going on - @param initialFileOrDirectory the file or directory that should be selected when - the dialog box opens. If this parameter is set to - File::nonexistent, a sensible default directory - will be used instead. - @param filePatternsAllowed a set of file patterns to specify which files can be - selected - each pattern should be separated by a - comma or semi-colon, e.g. "*" or "*.jpg;*.gif". An - empty string means that all files are allowed - @param useOSNativeDialogBox if true, then a native dialog box will be used if - possible; if false, then a Juce-based browser dialog - box will always be used - @see browseForFileToOpen, browseForFileToSave, browseForDirectory - */ - FileChooser (const String& dialogBoxTitle, - const File& initialFileOrDirectory = File::nonexistent, - const String& filePatternsAllowed = String::empty, - const bool useOSNativeDialogBox = true); - - /** Destructor. */ - ~FileChooser(); - - /** Shows a dialog box to choose a file to open. - - This will display the dialog box modally, using an "open file" mode, so that - it won't allow non-existent files or directories to be chosen. - - @param previewComponent an optional component to display inside the dialog - box to show special info about the files that the user - is browsing. The component will not be deleted by this - object, so the caller must take care of it. - @returns true if the user selected a file, in which case, use the getResult() - method to find out what it was. Returns false if they cancelled instead. - @see browseForFileToSave, browseForDirectory - */ - bool browseForFileToOpen (FilePreviewComponent* previewComponent = 0); - - /** Same as browseForFileToOpen, but allows the user to select multiple files. - - The files that are returned can be obtained by calling getResults(). See - browseForFileToOpen() for more info about the behaviour of this method. - */ - bool browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent = 0); - - /** Shows a dialog box to choose a file to save. - - This will display the dialog box modally, using an "save file" mode, so it - will allow non-existent files to be chosen, but not directories. - - @param warnAboutOverwritingExistingFiles if true, the dialog box will ask - the user if they're sure they want to overwrite a file that already - exists - @returns true if the user chose a file and pressed 'ok', in which case, use - the getResult() method to find out what the file was. Returns false - if they cancelled instead. - @see browseForFileToOpen, browseForDirectory - */ - bool browseForFileToSave (const bool warnAboutOverwritingExistingFiles); - - /** Shows a dialog box to choose a directory. - - This will display the dialog box modally, using an "open directory" mode, so it - will only allow directories to be returned, not files. - - @returns true if the user chose a directory and pressed 'ok', in which case, use - the getResult() method to find out what they chose. Returns false - if they cancelled instead. - @see browseForFileToOpen, browseForFileToSave - */ - bool browseForDirectory(); - - /** Same as browseForFileToOpen, but allows the user to select multiple files and directories. - - The files that are returned can be obtained by calling getResults(). See - browseForFileToOpen() for more info about the behaviour of this method. - */ - bool browseForMultipleFilesOrDirectories (FilePreviewComponent* previewComponent = 0); - - /** Returns the last file that was chosen by one of the browseFor methods. - - After calling the appropriate browseFor... method, this method lets you - find out what file or directory they chose. - - Note that the file returned is only valid if the browse method returned true (i.e. - if the user pressed 'ok' rather than cancelling). - - If you're using a multiple-file select, then use the getResults() method instead, - to obtain the list of all files chosen. - - @see getResults - */ - const File getResult() const; - - /** Returns a list of all the files that were chosen during the last call to a - browse method. - - This array may be empty if no files were chosen, or can contain multiple entries - if multiple files were chosen. - - @see getResult - */ - const OwnedArray & getResults() const; - - juce_UseDebuggingNewOperator - -private: - String title, filters; - File startingFile; - OwnedArray results; - bool useNativeDialogBox; - - bool showDialog (const bool selectsDirectories, - const bool selectsFiles, - const bool isSave, - const bool warnAboutOverwritingExistingFiles, - const bool selectMultipleFiles, - FilePreviewComponent* const previewComponent); - - static void showPlatformDialog (OwnedArray& results, - const String& title, - const File& file, - const String& filters, - bool selectsDirectories, - bool selectsFiles, - bool isSave, - bool warnAboutOverwritingExistingFiles, - bool selectMultipleFiles, - FilePreviewComponent* previewComponent); -}; - -#endif // __JUCE_FILECHOOSER_JUCEHEADER__ -/********* End of inlined file: juce_FileChooser.h *********/ - -#endif -#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_LookAndFeel.h *********/ +#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ +#define __JUCE_LOOKANDFEEL_JUCEHEADER__ /********* Start of inlined file: juce_AlertWindow.h *********/ #ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ #define __JUCE_ALERTWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_TextLayout.h *********/ +#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ +#define __JUCE_TEXTLAYOUT_JUCEHEADER__ + +class Graphics; + +/** + A laid-out arrangement of text. + + You can add text in different fonts to a TextLayout object, then call its + layout() method to word-wrap it into lines. The layout can then be drawn + using a graphics context. + + It's handy if you've got a message to display, because you can format it, + measure the extent of the layout, and then create a suitably-sized window + to show it in. + + @see Font, Graphics::drawFittedText, GlyphArrangement +*/ +class JUCE_API TextLayout +{ +public: + + /** Creates an empty text layout. + + Text can then be appended using the appendText() method. + */ + TextLayout() throw(); + + /** Creates a copy of another layout object. */ + TextLayout (const TextLayout& other) throw(); + + /** Creates a text layout from an initial string and font. */ + TextLayout (const String& text, const Font& font) throw(); + + /** Destructor. */ + ~TextLayout() throw(); + + /** Copies another layout onto this one. */ + const TextLayout& operator= (const TextLayout& layoutToCopy) throw(); + + /** Clears the layout, removing all its text. */ + void clear() throw(); + + /** Adds a string to the end of the arrangement. + + The string will be broken onto new lines wherever it contains + carriage-returns or linefeeds. After adding it, you can call layout() + to wrap long lines into a paragraph and justify it. + */ + void appendText (const String& textToAppend, + const Font& fontToUse) throw(); + + /** Replaces all the text with a new string. + + This is equivalent to calling clear() followed by appendText(). + */ + void setText (const String& newText, + const Font& fontToUse) throw(); + + /** Breaks the text up to form a paragraph with the given width. + + @param maximumWidth any text wider than this will be split + across multiple lines + @param justification how the lines are to be laid-out horizontally + @param attemptToBalanceLineLengths if true, it will try to split the lines at a + width that keeps all the lines of text at a + similar length - this is good when you're displaying + a short message and don't want it to get split + onto two lines with only a couple of words on + the second line, which looks untidy. + */ + void layout (int maximumWidth, + const Justification& justification, + const bool attemptToBalanceLineLengths) throw(); + + /** Returns the overall width of the entire text layout. */ + int getWidth() const throw(); + + /** Returns the overall height of the entire text layout. */ + int getHeight() const throw(); + + /** Returns the total number of lines of text. */ + int getNumLines() const throw() { return totalLines; } + + /** Returns the width of a particular line of text. + + @param lineNumber the line, from 0 to (getNumLines() - 1) + */ + int getLineWidth (const int lineNumber) const throw(); + + /** Renders the text at a specified position using a graphics context. + */ + void draw (Graphics& g, + const int topLeftX, + const int topLeftY) const throw(); + + /** Renders the text within a specified rectangle using a graphics context. + + The justification flags dictate how the block of text should be positioned + within the rectangle. + */ + void drawWithin (Graphics& g, + int x, int y, int w, int h, + const Justification& layoutFlags) const throw(); + + juce_UseDebuggingNewOperator + +private: + VoidArray tokens; + int totalLines; +}; + +#endif // __JUCE_TEXTLAYOUT_JUCEHEADER__ +/********* End of inlined file: juce_TextLayout.h *********/ + /** A window that displays a message and has buttons for the user to react to it. For simple dialog boxes with just a couple of buttons on them, there are @@ -52755,392 +50316,1685 @@ private: #endif // __JUCE_ALERTWINDOW_JUCEHEADER__ /********* End of inlined file: juce_AlertWindow.h *********/ -#endif -#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ - -/********* Start of inlined file: juce_DialogWindow.h *********/ -#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ -#define __JUCE_DIALOGWINDOW_JUCEHEADER__ +class ToggleButton; +class TextButton; +class AlertWindow; +class TextLayout; +class ScrollBar; +class BubbleComponent; +class ComboBox; +class Button; +class FilenameComponent; +class DocumentWindow; +class ResizableWindow; +class GroupComponent; +class MenuBarComponent; +class DropShadower; +class GlyphArrangement; +class PropertyComponent; +class TableHeaderComponent; +class Toolbar; +class ToolbarItemComponent; +class PopupMenu; +class ProgressBar; +class FileBrowserComponent; +class DirectoryContentsDisplayComponent; +class FilePreviewComponent; +class ImageButton; /** - A dialog-box style window. + LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses + can be used to apply different 'skins' to the application. - This class is a convenient way of creating a DocumentWindow with a close button - that can be triggered by pressing the escape key. - - Any of the methods available to a DocumentWindow or ResizableWindow are also - available to this, so it can be made resizable, have a menu bar, etc. - - To add items to the box, see the ResizableWindow::setContentComponent() method. - Don't add components directly to this class - always put them in a content component! - - You'll need to override the DocumentWindow::closeButtonPressed() method to handle - the user clicking the close button - for more info, see the DocumentWindow - help. - - @see DocumentWindow, ResizableWindow */ -class JUCE_API DialogWindow : public DocumentWindow +class JUCE_API LookAndFeel { public: - /** Creates a DialogWindow. + /** Creates the default JUCE look and feel. */ + LookAndFeel(); - @param name the name to give the component - this is also - the title shown at the top of the window. To change - this later, use setName() - @param backgroundColour the colour to use for filling the window's background. - @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the - close button to be triggered - @param addToDesktop if true, the window will be automatically added to the - desktop; if false, you can use it as a child component + /** Destructor. */ + virtual ~LookAndFeel(); + + /** Returns the current default look-and-feel for a component to use when it + hasn't got one explicitly set. + + @see setDefaultLookAndFeel */ - DialogWindow (const String& name, - const Colour& backgroundColour, - const bool escapeKeyTriggersCloseButton, - const bool addToDesktop = true); + static LookAndFeel& getDefaultLookAndFeel() throw(); - /** Destructor. + /** Changes the default look-and-feel. - If a content component has been set with setContentComponent(), it - will be deleted. + @param newDefaultLookAndFeel the new look-and-feel object to use - if this is + set to 0, it will revert to using the default one. The + object passed-in must be deleted by the caller when + it's no longer needed. + @see getDefaultLookAndFeel */ - ~DialogWindow(); + static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) throw(); - /** Easy way of quickly showing a dialog box containing a given component. + /** Looks for a colour that has been registered with the given colour ID number. - This will open and display a DialogWindow containing a given component, returning - when the user clicks its close button. + If a colour has been set for this ID number using setColour(), then it is + returned. If none has been set, it will just return Colours::black. - It returns the value that was returned by the dialog box's runModalLoop() call. + The colour IDs for various purposes are stored as enums in the components that + they are relevent to - for an example, see Slider::ColourIds, + Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc. - To close the dialog programatically, you should call exitModalState (returnValue) on - the DialogWindow that is created. To find a pointer to this window from your - contentComponent, you can do something like this: - @code - Dialogwindow* dw = contentComponent->findParentComponentOfClass ((DialogWindow*) 0); + If you're looking up a colour for use in drawing a component, it's usually + best not to call this directly, but to use the Component::findColour() method + instead. That will first check whether a suitable colour has been registered + directly with the component, and will fall-back on calling the component's + LookAndFeel's findColour() method if none is found. - if (dw != 0) - dw->exitModalState (1234); - @endcode - - @param dialogTitle the dialog box's title - @param contentComponent the content component for the dialog box. Make sure - that this has been set to the size you want it to - be before calling this method. The component won't - be deleted by this call, so you can re-use it or delete - it afterwards - @param componentToCentreAround if this is non-zero, it indicates a component that - you'd like to show this dialog box in front of. See the - DocumentWindow::centreAroundComponent() method for more - info on this parameter - @param backgroundColour a colour to use for the dialog box's background colour - @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the - close button to be triggered - @param shouldBeResizable if true, the dialog window has either a resizable border, or - a corner resizer - @param useBottomRightCornerResizer if shouldBeResizable is true, this indicates whether - to use a border or corner resizer component. See ResizableWindow::setResizable() + @see setColour, Component::findColour, Component::setColour */ - static int showModalDialog (const String& dialogTitle, - Component* contentComponent, - Component* componentToCentreAround, - const Colour& backgroundColour, - const bool escapeKeyTriggersCloseButton, - const bool shouldBeResizable = false, - const bool useBottomRightCornerResizer = false); + const Colour findColour (const int colourId) const throw(); + + /** Registers a colour to be used for a particular purpose. + + For more details, see the comments for findColour(). + + @see findColour, Component::findColour, Component::setColour + */ + void setColour (const int colourId, const Colour& colour) throw(); + + /** Returns true if the specified colour ID has been explicitly set using the + setColour() method. + */ + bool isColourSpecified (const int colourId) const throw(); + + virtual const Typeface::Ptr getTypefaceForFont (const Font& font); + + /** Allows you to change the default sans-serif font. + + If you need to supply your own Typeface object for any of the default fonts, rather + than just supplying the name (e.g. if you want to use an embedded font), then + you should instead override getTypefaceForFont() to create and return the typeface. + */ + void setDefaultSansSerifTypefaceName (const String& newName); + + /** Override this to get the chance to swap a component's mouse cursor for a + customised one. + */ + virtual const MouseCursor getMouseCursorFor (Component& component); + + /** Draws the lozenge-shaped background for a standard button. */ + virtual void drawButtonBackground (Graphics& g, + Button& button, + const Colour& backgroundColour, + bool isMouseOverButton, + bool isButtonDown); + + virtual const Font getFontForTextButton (TextButton& button); + + /** Draws the text for a TextButton. */ + virtual void drawButtonText (Graphics& g, + TextButton& button, + bool isMouseOverButton, + bool isButtonDown); + + /** Draws the contents of a standard ToggleButton. */ + virtual void drawToggleButton (Graphics& g, + ToggleButton& button, + bool isMouseOverButton, + bool isButtonDown); + + virtual void changeToggleButtonWidthToFitText (ToggleButton& button); + + virtual void drawTickBox (Graphics& g, + Component& component, + int x, int y, int w, int h, + const bool ticked, + const bool isEnabled, + const bool isMouseOverButton, + const bool isButtonDown); + + /* AlertWindow handling.. + */ + virtual AlertWindow* createAlertWindow (const String& title, + const String& message, + const String& button1, + const String& button2, + const String& button3, + AlertWindow::AlertIconType iconType, + int numButtons, + Component* associatedComponent); + + virtual void drawAlertBox (Graphics& g, + AlertWindow& alert, + const Rectangle& textArea, + TextLayout& textLayout); + + virtual int getAlertBoxWindowFlags(); + + virtual int getAlertWindowButtonHeight(); + + virtual const Font getAlertWindowFont(); + + /** Draws a progress bar. + + If the progress value is less than 0 or greater than 1.0, this should draw a spinning + bar that fills the whole space (i.e. to say that the app is still busy but the progress + isn't known). It can use the current time as a basis for playing an animation. + + (Used by progress bars in AlertWindow). + */ + virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar, + int width, int height, + double progress, const String& textToShow); + + // Draws a small image that spins to indicate that something's happening.. + // This method should use the current time to animate itself, so just keep + // repainting it every so often. + virtual void drawSpinningWaitAnimation (Graphics& g, const Colour& colour, + int x, int y, int w, int h); + + /** Draws one of the buttons on a scrollbar. + + @param g the context to draw into + @param scrollbar the bar itself + @param width the width of the button + @param height the height of the button + @param buttonDirection the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left + @param isScrollbarVertical true if it's a vertical bar, false if horizontal + @param isMouseOverButton whether the mouse is currently over the button (also true if it's held down) + @param isButtonDown whether the mouse button's held down + */ + virtual void drawScrollbarButton (Graphics& g, + ScrollBar& scrollbar, + int width, int height, + int buttonDirection, + bool isScrollbarVertical, + bool isMouseOverButton, + bool isButtonDown); + + /** Draws the thumb area of a scrollbar. + + @param g the context to draw into + @param scrollbar the bar itself + @param x the x position of the left edge of the thumb area to draw in + @param y the y position of the top edge of the thumb area to draw in + @param width the width of the thumb area to draw in + @param height the height of the thumb area to draw in + @param isScrollbarVertical true if it's a vertical bar, false if horizontal + @param thumbStartPosition for vertical bars, the y co-ordinate of the top of the + thumb, or its x position for horizontal bars + @param thumbSize for vertical bars, the height of the thumb, or its width for + horizontal bars. This may be 0 if the thumb shouldn't be drawn. + @param isMouseOver whether the mouse is over the thumb area, also true if the mouse is + currently dragging the thumb + @param isMouseDown whether the mouse is currently dragging the scrollbar + */ + virtual void drawScrollbar (Graphics& g, + ScrollBar& scrollbar, + int x, int y, + int width, int height, + bool isScrollbarVertical, + int thumbStartPosition, + int thumbSize, + bool isMouseOver, + bool isMouseDown); + + /** Returns the component effect to use for a scrollbar */ + virtual ImageEffectFilter* getScrollbarEffect(); + + /** Returns the minimum length in pixels to use for a scrollbar thumb. */ + virtual int getMinimumScrollbarThumbSize (ScrollBar& scrollbar); + + /** Returns the default thickness to use for a scrollbar. */ + virtual int getDefaultScrollbarWidth(); + + /** Returns the length in pixels to use for a scrollbar button. */ + virtual int getScrollbarButtonSize (ScrollBar& scrollbar); + + /** Returns a tick shape for use in yes/no boxes, etc. */ + virtual const Path getTickShape (const float height); + /** Returns a cross shape for use in yes/no boxes, etc. */ + virtual const Path getCrossShape (const float height); + + /** Draws the + or - box in a treeview. */ + virtual void drawTreeviewPlusMinusBox (Graphics& g, int x, int y, int w, int h, bool isPlus, bool isMouseOver); + + virtual void fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor); + virtual void drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor); + + // these return an image from the ImageCache, so use ImageCache::release() to free it + virtual Image* getDefaultFolderImage(); + virtual Image* getDefaultDocumentFileImage(); + + virtual void createFileChooserHeaderText (const String& title, + const String& instructions, + GlyphArrangement& destArrangement, + int width); + + virtual void drawFileBrowserRow (Graphics& g, int width, int height, + const String& filename, Image* icon, + const String& fileSizeDescription, + const String& fileTimeDescription, + const bool isDirectory, + const bool isItemSelected, + const int itemIndex); + + virtual Button* createFileBrowserGoUpButton(); + + virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp, + DirectoryContentsDisplayComponent* fileListComponent, + FilePreviewComponent* previewComp, + ComboBox* currentPathBox, + TextEditor* filenameBox, + Button* goUpButton); + + virtual void drawBubble (Graphics& g, + float tipX, float tipY, + float boxX, float boxY, float boxW, float boxH); + + /** Fills the background of a popup menu component. */ + virtual void drawPopupMenuBackground (Graphics& g, int width, int height); + + /** Draws one of the items in a popup menu. */ + virtual void drawPopupMenuItem (Graphics& g, + int width, int height, + const bool isSeparator, + const bool isActive, + const bool isHighlighted, + const bool isTicked, + const bool hasSubMenu, + const String& text, + const String& shortcutKeyText, + Image* image, + const Colour* const textColour); + + /** Returns the size and style of font to use in popup menus. */ + virtual const Font getPopupMenuFont(); + + virtual void drawPopupMenuUpDownArrow (Graphics& g, + int width, int height, + bool isScrollUpArrow); + + /** Finds the best size for an item in a popup menu. */ + virtual void getIdealPopupMenuItemSize (const String& text, + const bool isSeparator, + int standardMenuItemHeight, + int& idealWidth, + int& idealHeight); + + virtual int getMenuWindowFlags(); + + virtual void drawMenuBarBackground (Graphics& g, int width, int height, + bool isMouseOverBar, + MenuBarComponent& menuBar); + + virtual int getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText); + + virtual const Font getMenuBarFont (MenuBarComponent& menuBar, int itemIndex, const String& itemText); + + virtual void drawMenuBarItem (Graphics& g, + int width, int height, + int itemIndex, + const String& itemText, + bool isMouseOverItem, + bool isMenuOpen, + bool isMouseOverBar, + MenuBarComponent& menuBar); + + virtual void drawComboBox (Graphics& g, int width, int height, + const bool isButtonDown, + int buttonX, int buttonY, + int buttonW, int buttonH, + ComboBox& box); + + virtual const Font getComboBoxFont (ComboBox& box); + + virtual Label* createComboBoxTextBox (ComboBox& box); + + virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition); + + virtual void drawLabel (Graphics& g, Label& label); + + virtual void drawLinearSlider (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, + float minSliderPos, + float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider); + + virtual void drawLinearSliderBackground (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, + float minSliderPos, + float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider); + + virtual void drawLinearSliderThumb (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, + float minSliderPos, + float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider); + + virtual int getSliderThumbRadius (Slider& slider); + + virtual void drawRotarySlider (Graphics& g, + int x, int y, + int width, int height, + float sliderPosProportional, + const float rotaryStartAngle, + const float rotaryEndAngle, + Slider& slider); + + virtual Button* createSliderButton (const bool isIncrement); + virtual Label* createSliderTextBox (Slider& slider); + + virtual ImageEffectFilter* getSliderEffect(); + + virtual void getTooltipSize (const String& tipText, int& width, int& height); + + virtual void drawTooltip (Graphics& g, const String& text, int width, int height); + + virtual Button* createFilenameComponentBrowseButton (const String& text); + + virtual void layoutFilenameComponent (FilenameComponent& filenameComp, + ComboBox* filenameBox, Button* browseButton); + + virtual void drawCornerResizer (Graphics& g, + int w, int h, + bool isMouseOver, + bool isMouseDragging); + + virtual void drawResizableFrame (Graphics& g, + int w, int h, + const BorderSize& borders); + + virtual void fillResizableWindowBackground (Graphics& g, int w, int h, + const BorderSize& border, + ResizableWindow& window); + + virtual void drawResizableWindowBorder (Graphics& g, + int w, int h, + const BorderSize& border, + ResizableWindow& window); + + virtual void drawDocumentWindowTitleBar (DocumentWindow& window, + Graphics& g, int w, int h, + int titleSpaceX, int titleSpaceW, + const Image* icon, + bool drawTitleTextOnLeft); + + virtual Button* createDocumentWindowButton (int buttonType); + + virtual void positionDocumentWindowButtons (DocumentWindow& window, + int titleBarX, int titleBarY, + int titleBarW, int titleBarH, + Button* minimiseButton, + Button* maximiseButton, + Button* closeButton, + bool positionTitleBarButtonsOnLeft); + + virtual int getDefaultMenuBarHeight(); + + virtual DropShadower* createDropShadowerForComponent (Component* component); + + virtual void drawStretchableLayoutResizerBar (Graphics& g, + int w, int h, + bool isVerticalBar, + bool isMouseOver, + bool isMouseDragging); + + virtual void drawGroupComponentOutline (Graphics& g, int w, int h, + const String& text, + const Justification& position, + GroupComponent& group); + + virtual void createTabButtonShape (Path& p, + int width, int height, + int tabIndex, + const String& text, + Button& button, + TabbedButtonBar::Orientation orientation, + const bool isMouseOver, + const bool isMouseDown, + const bool isFrontTab); + + virtual void fillTabButtonShape (Graphics& g, + const Path& path, + const Colour& preferredBackgroundColour, + int tabIndex, + const String& text, + Button& button, + TabbedButtonBar::Orientation orientation, + const bool isMouseOver, + const bool isMouseDown, + const bool isFrontTab); + + virtual void drawTabButtonText (Graphics& g, + int x, int y, int w, int h, + const Colour& preferredBackgroundColour, + int tabIndex, + const String& text, + Button& button, + TabbedButtonBar::Orientation orientation, + const bool isMouseOver, + const bool isMouseDown, + const bool isFrontTab); + + virtual int getTabButtonOverlap (int tabDepth); + virtual int getTabButtonSpaceAroundImage(); + + virtual int getTabButtonBestWidth (int tabIndex, + const String& text, + int tabDepth, + Button& button); + + virtual void drawTabButton (Graphics& g, + int w, int h, + const Colour& preferredColour, + int tabIndex, + const String& text, + Button& button, + TabbedButtonBar::Orientation orientation, + const bool isMouseOver, + const bool isMouseDown, + const bool isFrontTab); + + virtual void drawTabAreaBehindFrontButton (Graphics& g, + int w, int h, + TabbedButtonBar& tabBar, + TabbedButtonBar::Orientation orientation); + + virtual Button* createTabBarExtrasButton(); + + virtual void drawImageButton (Graphics& g, Image* image, + int imageX, int imageY, int imageW, int imageH, + const Colour& overlayColour, + float imageOpacity, + ImageButton& button); + + virtual void drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header); + + virtual void drawTableHeaderColumn (Graphics& g, const String& columnName, int columnId, + int width, int height, + bool isMouseOver, bool isMouseDown, + int columnFlags); + + virtual void paintToolbarBackground (Graphics& g, int width, int height, Toolbar& toolbar); + + virtual Button* createToolbarMissingItemsButton (Toolbar& toolbar); + + virtual void paintToolbarButtonBackground (Graphics& g, int width, int height, + bool isMouseOver, bool isMouseDown, + ToolbarItemComponent& component); + + virtual void paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height, + const String& text, ToolbarItemComponent& component); + + virtual void drawPropertyPanelSectionHeader (Graphics& g, const String& name, + bool isOpen, int width, int height); + + virtual void drawPropertyComponentBackground (Graphics& g, int width, int height, + PropertyComponent& component); + + virtual void drawPropertyComponentLabel (Graphics& g, int width, int height, + PropertyComponent& component); + + virtual const Rectangle getPropertyComponentContentPosition (PropertyComponent& component); + + virtual void drawLevelMeter (Graphics& g, int width, int height, float level); + + virtual void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription); + + /** + */ + virtual void playAlertSound(); + + /** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */ + static void drawGlassSphere (Graphics& g, + const float x, const float y, + const float diameter, + const Colour& colour, + const float outlineThickness) throw(); + + static void drawGlassPointer (Graphics& g, + const float x, const float y, + const float diameter, + const Colour& colour, const float outlineThickness, + const int direction) throw(); + + /** Utility function to draw a shiny, glassy oblong (for text buttons). */ + static void drawGlassLozenge (Graphics& g, + const float x, const float y, + const float width, const float height, + const Colour& colour, + const float outlineThickness, + const float cornerSize, + const bool flatOnLeft, const bool flatOnRight, + const bool flatOnTop, const bool flatOnBottom) throw(); juce_UseDebuggingNewOperator protected: - /** @internal */ - void resized(); + // xxx the following methods are only here to cause a compiler error, because they've been + // deprecated or their parameters have changed. Hopefully these definitions should cause an + // error if you try to build a subclass with the old versions. + virtual int drawTickBox (Graphics&, int, int, int, int, bool, const bool, const bool, const bool) { return 0; } + virtual int drawProgressBar (Graphics&, int, int, int, int, float) { return 0; } + virtual int drawProgressBar (Graphics&, ProgressBar&, int, int, int, int, float) { return 0; } + virtual void getTabButtonBestWidth (int, const String&, int) {} + virtual int drawTreeviewPlusMinusBox (Graphics&, int, int, int, int, bool) { return 0; } private: - bool escapeKeyTriggersCloseButton; + friend void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); + static void clearDefaultLookAndFeel() throw(); // called at shutdown - DialogWindow (const DialogWindow&); - const DialogWindow& operator= (const DialogWindow&); + Array colourIds; + Array colours; + + // default typeface names + String defaultSans, defaultSerif, defaultFixed; + + void drawShinyButtonShape (Graphics& g, + float x, float y, float w, float h, float maxCornerSize, + const Colour& baseColour, + const float strokeWidth, + const bool flatOnLeft, + const bool flatOnRight, + const bool flatOnTop, + const bool flatOnBottom) throw(); + + LookAndFeel (const LookAndFeel&); + const LookAndFeel& operator= (const LookAndFeel&); }; -#endif // __JUCE_DIALOGWINDOW_JUCEHEADER__ -/********* End of inlined file: juce_DialogWindow.h *********/ +#endif // __JUCE_LOOKANDFEEL_JUCEHEADER__ +/********* End of inlined file: juce_LookAndFeel.h *********/ #endif -#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__ +#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ -#endif -#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_OldSchoolLookAndFeel.h *********/ +#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ +#define __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ -#endif -#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ +/** + The original Juce look-and-feel. -/********* Start of inlined file: juce_SplashScreen.h *********/ -#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ -#define __JUCE_SPLASHSCREEN_JUCEHEADER__ - -/** A component for showing a splash screen while your app starts up. - - This will automatically position itself, and delete itself when the app has - finished initialising (it uses the JUCEApplication::isInitialising() to detect - this). - - To use it, just create one of these in your JUCEApplication::initialise() method, - call its show() method and let the object delete itself later. - - E.g. @code - - void MyApp::initialise (const String& commandLine) - { - SplashScreen* splash = new SplashScreen(); - - splash->show (T("welcome to my app"), - ImageCache::getFromFile (File ("/foobar/splash.jpg")), - 4000, false); - - .. no need to delete the splash screen - it'll do that itself. - } - - @endcode */ -class JUCE_API SplashScreen : public Component, - public Timer, - private DeletedAtShutdown +class JUCE_API OldSchoolLookAndFeel : public LookAndFeel { public: - /** Creates a SplashScreen object. - - After creating one of these (or your subclass of it), call one of the show() - methods to display it. - */ - SplashScreen(); + /** Creates the default JUCE look and feel. */ + OldSchoolLookAndFeel(); /** Destructor. */ - ~SplashScreen(); + virtual ~OldSchoolLookAndFeel(); - /** Creates a SplashScreen object that will display an image. + /** Draws the lozenge-shaped background for a standard button. */ + virtual void drawButtonBackground (Graphics& g, + Button& button, + const Colour& backgroundColour, + bool isMouseOverButton, + bool isButtonDown); - As soon as this is called, the SplashScreen will be displayed in the centre of the - screen. This method will also dispatch any pending messages to make sure that when - it returns, the splash screen has been completely drawn, and your initialisation - code can carry on. + /** Draws the contents of a standard ToggleButton. */ + virtual void drawToggleButton (Graphics& g, + ToggleButton& button, + bool isMouseOverButton, + bool isButtonDown); - @param title the name to give the component - @param backgroundImage an image to draw on the component. The component's size - will be set to the size of this image, and if the image is - semi-transparent, the component will be made semi-transparent - too. This image will be deleted (or released from the ImageCache - if that's how it was created) by the splash screen object when - it is itself deleted. - @param minimumTimeToDisplayFor how long (in milliseconds) the splash screen - should stay visible for. If the initialisation takes longer than - this time, the splash screen will wait for it to finish before - disappearing, but if initialisation is very quick, this lets - you make sure that people get a good look at your splash. - @param useDropShadow if true, the window will have a drop shadow - @param removeOnMouseClick if true, the window will go away as soon as the user clicks - the mouse (anywhere) + virtual void drawTickBox (Graphics& g, + Component& component, + int x, int y, int w, int h, + const bool ticked, + const bool isEnabled, + const bool isMouseOverButton, + const bool isButtonDown); + + virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar, + int width, int height, + double progress, const String& textToShow); + + virtual void drawScrollbarButton (Graphics& g, + ScrollBar& scrollbar, + int width, int height, + int buttonDirection, + bool isScrollbarVertical, + bool isMouseOverButton, + bool isButtonDown); + + virtual void drawScrollbar (Graphics& g, + ScrollBar& scrollbar, + int x, int y, + int width, int height, + bool isScrollbarVertical, + int thumbStartPosition, + int thumbSize, + bool isMouseOver, + bool isMouseDown); + + virtual ImageEffectFilter* getScrollbarEffect(); + + virtual void drawTextEditorOutline (Graphics& g, + int width, int height, + TextEditor& textEditor); + + /** Fills the background of a popup menu component. */ + virtual void drawPopupMenuBackground (Graphics& g, int width, int height); + + virtual void drawMenuBarBackground (Graphics& g, int width, int height, + bool isMouseOverBar, + MenuBarComponent& menuBar); + + virtual void drawComboBox (Graphics& g, int width, int height, + const bool isButtonDown, + int buttonX, int buttonY, + int buttonW, int buttonH, + ComboBox& box); + + virtual const Font getComboBoxFont (ComboBox& box); + + virtual void drawLinearSlider (Graphics& g, + int x, int y, + int width, int height, + float sliderPos, + float minSliderPos, + float maxSliderPos, + const Slider::SliderStyle style, + Slider& slider); + + virtual int getSliderThumbRadius (Slider& slider); + + virtual Button* createSliderButton (const bool isIncrement); + + virtual ImageEffectFilter* getSliderEffect(); + + virtual void drawCornerResizer (Graphics& g, + int w, int h, + bool isMouseOver, + bool isMouseDragging); + + virtual Button* createDocumentWindowButton (int buttonType); + + virtual void positionDocumentWindowButtons (DocumentWindow& window, + int titleBarX, int titleBarY, + int titleBarW, int titleBarH, + Button* minimiseButton, + Button* maximiseButton, + Button* closeButton, + bool positionTitleBarButtonsOnLeft); + + juce_UseDebuggingNewOperator + +private: + DropShadowEffect scrollbarShadow; + + OldSchoolLookAndFeel (const OldSchoolLookAndFeel&); + const OldSchoolLookAndFeel& operator= (const OldSchoolLookAndFeel&); +}; + +#endif // __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ +/********* End of inlined file: juce_OldSchoolLookAndFeel.h *********/ + +#endif +#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ + +#endif +#ifndef __JUCE_POPUPMENU_JUCEHEADER__ + +#endif +#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ + +#endif +#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ + +#endif +#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ + +#endif +#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_LassoComponent.h *********/ +#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ +#define __JUCE_LASSOCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_SelectedItemSet.h *********/ +#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__ +#define __JUCE_SELECTEDITEMSET_JUCEHEADER__ + +/** Manages a list of selectable items. + + Use one of these to keep a track of things that the user has highlighted, like + icons or things in a list. + + The class is templated so that you can use it to hold either a set of pointers + to objects, or a set of ID numbers or handles, for cases where each item may + not always have a corresponding object. + + To be informed when items are selected/deselected, register a ChangeListener with + this object. + + @see SelectableObject +*/ +template +class JUCE_API SelectedItemSet : public ChangeBroadcaster +{ +public: + + /** Creates an empty set. */ + SelectedItemSet() + { + } + + /** Creates a set based on an array of items. */ + SelectedItemSet (const Array & items) + : selectedItems (items) + { + } + + /** Creates a copy of another set. */ + SelectedItemSet (const SelectedItemSet& other) + : selectedItems (other.selectedItems) + { + } + + /** Creates a copy of another set. */ + const SelectedItemSet& operator= (const SelectedItemSet& other) + { + if (selectedItems != other.selectedItems) + { + selectedItems = other.selectedItems; + changed(); + } + + return *this; + } + + /** Destructor. */ + ~SelectedItemSet() + { + } + + /** Clears any other currently selected items, and selects this item. + + If this item is already the only thing selected, no change notification + will be sent out. + + @see addToSelection, addToSelectionBasedOnModifiers */ - void show (const String& title, - Image* const backgroundImage, - const int minimumTimeToDisplayFor, - const bool useDropShadow, - const bool removeOnMouseClick = true); + void selectOnly (SelectableItemType item) + { + if (isSelected (item)) + { + for (int i = selectedItems.size(); --i >= 0;) + { + if (selectedItems.getUnchecked(i) != item) + { + deselect (selectedItems.getUnchecked(i)); + i = jmin (i, selectedItems.size()); + } + } + } + else + { + deselectAll(); + changed(); - /** Creates a SplashScreen object with a specified size. + selectedItems.add (item); + itemSelected (item); + } + } - For a custom splash screen, you can use this method to display it at a certain size - and then override the paint() method yourself to do whatever's necessary. + /** Selects an item. - As soon as this is called, the SplashScreen will be displayed in the centre of the - screen. This method will also dispatch any pending messages to make sure that when - it returns, the splash screen has been completely drawn, and your initialisation - code can carry on. + If the item is already selected, no change notification will be sent out. - @param title the name to give the component - @param width the width to use - @param height the height to use - @param minimumTimeToDisplayFor how long (in milliseconds) the splash screen - should stay visible for. If the initialisation takes longer than - this time, the splash screen will wait for it to finish before - disappearing, but if initialisation is very quick, this lets - you make sure that people get a good look at your splash. - @param useDropShadow if true, the window will have a drop shadow - @param removeOnMouseClick if true, the window will go away as soon as the user clicks - the mouse (anywhere) + @see selectOnly, addToSelectionBasedOnModifiers */ - void show (const String& title, - const int width, - const int height, - const int minimumTimeToDisplayFor, - const bool useDropShadow, - const bool removeOnMouseClick = true); + void addToSelection (SelectableItemType item) + { + if (! isSelected (item)) + { + changed(); + + selectedItems.add (item); + itemSelected (item); + } + } + + /** Selects or deselects an item. + + This will use the modifier keys to decide whether to deselect other items + first. + + So if the shift key is held down, the item will be added without deselecting + anything (same as calling addToSelection() ) + + If no modifiers are down, the current selection will be cleared first (same + as calling selectOnly() ) + + If the ctrl (or command on the Mac) key is held down, the item will be toggled - + so it'll be added to the set unless it's already there, in which case it'll be + deselected. + + If the items that you're selecting can also be dragged, you may need to use the + addToSelectionOnMouseDown() and addToSelectionOnMouseUp() calls to handle the + subtleties of this kind of usage. + + @see selectOnly, addToSelection, addToSelectionOnMouseDown, addToSelectionOnMouseUp + */ + void addToSelectionBasedOnModifiers (SelectableItemType item, + const ModifierKeys& modifiers) + { + if (modifiers.isShiftDown()) + { + addToSelection (item); + } + else if (modifiers.isCommandDown()) + { + if (isSelected (item)) + deselect (item); + else + addToSelection (item); + } + else + { + selectOnly (item); + } + } + + /** Selects or deselects items that can also be dragged, based on a mouse-down event. + + If you call addToSelectionOnMouseDown() at the start of your mouseDown event, + and then call addToSelectionOnMouseUp() at the end of your mouseUp event, this + makes it easy to handle multiple-selection of sets of objects that can also + be dragged. + + For example, if you have several items already selected, and you click on + one of them (without dragging), then you'd expect this to deselect the other, and + just select the item you clicked on. But if you had clicked on this item and + dragged it, you'd have expected them all to stay selected. + + When you call this method, you'll need to store the boolean result, because the + addToSelectionOnMouseUp() method will need to be know this value. + + @see addToSelectionOnMouseUp, addToSelectionBasedOnModifiers + */ + bool addToSelectionOnMouseDown (SelectableItemType item, + const ModifierKeys& modifiers) + { + if (isSelected (item)) + { + return ! modifiers.isPopupMenu(); + } + else + { + addToSelectionBasedOnModifiers (item, modifiers); + return false; + } + } + + /** Selects or deselects items that can also be dragged, based on a mouse-up event. + + Call this during a mouseUp callback, when you have previously called the + addToSelectionOnMouseDown() method during your mouseDown event. + + See addToSelectionOnMouseDown() for more info + + @param item the item to select (or deselect) + @param modifiers the modifiers from the mouse-up event + @param wasItemDragged true if your item was dragged during the mouse click + @param resultOfMouseDownSelectMethod this is the boolean return value that came + back from the addToSelectionOnMouseDown() call that you + should have made during the matching mouseDown event + */ + void addToSelectionOnMouseUp (SelectableItemType item, + const ModifierKeys& modifiers, + const bool wasItemDragged, + const bool resultOfMouseDownSelectMethod) + { + if (resultOfMouseDownSelectMethod && ! wasItemDragged) + addToSelectionBasedOnModifiers (item, modifiers); + } + + /** Deselects an item. */ + void deselect (SelectableItemType item) + { + const int i = selectedItems.indexOf (item); + + if (i >= 0) + { + changed(); + itemDeselected (selectedItems.remove (i)); + } + } + + /** Deselects all items. */ + void deselectAll() + { + if (selectedItems.size() > 0) + { + changed(); + + for (int i = selectedItems.size(); --i >= 0;) + { + itemDeselected (selectedItems.remove (i)); + i = jmin (i, selectedItems.size()); + } + } + } + + /** Returns the number of currently selected items. + + @see getSelectedItem + */ + int getNumSelected() const throw() + { + return selectedItems.size(); + } + + /** Returns one of the currently selected items. + + Returns 0 if the index is out-of-range. + + @see getNumSelected + */ + SelectableItemType getSelectedItem (const int index) const throw() + { + return selectedItems [index]; + } + + /** True if this item is currently selected. */ + bool isSelected (const SelectableItemType item) const throw() + { + return selectedItems.contains (item); + } + + const Array & getItemArray() const throw() { return selectedItems; } + + /** Can be overridden to do special handling when an item is selected. + + For example, if the item is an object, you might want to call it and tell + it that it's being selected. + */ + virtual void itemSelected (SelectableItemType item) {} + + /** Can be overridden to do special handling when an item is deselected. + + For example, if the item is an object, you might want to call it and tell + it that it's being deselected. + */ + virtual void itemDeselected (SelectableItemType item) {} + + /** Used internally, but can be called to force a change message to be sent to the ChangeListeners. + */ + void changed (const bool synchronous = false) + { + if (synchronous) + sendSynchronousChangeMessage (this); + else + sendChangeMessage (this); + } + + juce_UseDebuggingNewOperator + +private: + Array selectedItems; +}; + +#endif // __JUCE_SELECTEDITEMSET_JUCEHEADER__ +/********* End of inlined file: juce_SelectedItemSet.h *********/ + +/** + A class used by the LassoComponent to manage the things that it selects. + + This allows the LassoComponent to find out which items are within the lasso, + and to change the list of selected items. + + @see LassoComponent, SelectedItemSet +*/ +template +class LassoSource +{ +public: + /** Destructor. */ + virtual ~LassoSource() {} + + /** Returns the set of items that lie within a given lassoable region. + + Your implementation of this method must find all the relevent items that lie + within the given rectangle. and add them to the itemsFound array. + + The co-ordinates are relative to the top-left of the lasso component's parent + component. (i.e. they are the same as the size and position of the lasso + component itself). + */ + virtual void findLassoItemsInArea (Array & itemsFound, + int x, int y, int width, int height) = 0; + + /** Returns the SelectedItemSet that the lasso should update. + + This set will be continuously updated by the LassoComponent as it gets + dragged around, so make sure that you've got a ChangeListener attached to + the set so that your UI objects will know when the selection changes and + be able to update themselves appropriately. + */ + virtual SelectedItemSet & getLassoSelection() = 0; +}; + +/** + A component that acts as a rectangular selection region, which you drag with + the mouse to select groups of objects (in conjunction with a SelectedItemSet). + + To use one of these: + + - In your mouseDown or mouseDrag event, add the LassoComponent to your parent + component, and call its beginLasso() method, giving it a + suitable LassoSource object that it can use to find out which items are in + the active area. + + - Each time your parent component gets a mouseDrag event, call dragLasso() + to update the lasso's position - it will use its LassoSource to calculate and + update the current selection. + + - After the drag has finished and you get a mouseUp callback, you should call + endLasso() to clean up. This will make the lasso component invisible, and you + can remove it from the parent component, or delete it. + + The class takes into account the modifier keys that are being held down while + the lasso is being dragged, so if shift is pressed, then any lassoed items will + be added to the original selection; if ctrl or command is pressed, they will be + xor'ed with any previously selected items. + + @see LassoSource, SelectedItemSet +*/ +template +class LassoComponent : public Component +{ +public: + + /** Creates a Lasso component. + + The fill colour is used to fill the lasso'ed rectangle, and the outline + colour is used to draw a line around its edge. + */ + LassoComponent (const int outlineThickness_ = 1) + : source (0), + outlineThickness (outlineThickness_) + { + } + + /** Destructor. */ + ~LassoComponent() + { + } + + /** Call this in your mouseDown event, to initialise a drag. + + Pass in a suitable LassoSource object which the lasso will use to find + the items and change the selection. + + After using this method to initialise the lasso, repeatedly call dragLasso() + in your component's mouseDrag callback. + + @see dragLasso, endLasso, LassoSource + */ + void beginLasso (const MouseEvent& e, + LassoSource * const lassoSource) + { + jassert (source == 0); // this suggests that you didn't call endLasso() after the last drag... + jassert (lassoSource != 0); // the source can't be null! + jassert (getParentComponent() != 0); // you need to add this to a parent component for it to work! + + source = lassoSource; + + if (lassoSource != 0) + originalSelection = lassoSource->getLassoSelection().getItemArray(); + + setSize (0, 0); + } + + /** Call this in your mouseDrag event, to update the lasso's position. + + This must be repeatedly calling when the mouse is dragged, after you've + first initialised the lasso with beginLasso(). + + This method takes into account the modifier keys that are being held down, so + if shift is pressed, then the lassoed items will be added to any that were + previously selected; if ctrl or command is pressed, then they will be xor'ed + with previously selected items. + + @see beginLasso, endLasso + */ + void dragLasso (const MouseEvent& e) + { + if (source != 0) + { + const int x1 = e.getMouseDownX(); + const int y1 = e.getMouseDownY(); + + setBounds (jmin (x1, e.x), jmin (y1, e.y), abs (e.x - x1), abs (e.y - y1)); + setVisible (true); + + Array itemsInLasso; + source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight()); + + if (e.mods.isShiftDown()) + { + itemsInLasso.removeValuesIn (originalSelection); // to avoid duplicates + itemsInLasso.addArray (originalSelection); + } + else if (e.mods.isCommandDown() || e.mods.isAltDown()) + { + Array originalMinusNew (originalSelection); + originalMinusNew.removeValuesIn (itemsInLasso); + + itemsInLasso.removeValuesIn (originalSelection); + itemsInLasso.addArray (originalMinusNew); + } + + source->getLassoSelection() = SelectedItemSet (itemsInLasso); + } + } + + /** Call this in your mouseUp event, after the lasso has been dragged. + + @see beginLasso, dragLasso + */ + void endLasso() + { + source = 0; + originalSelection.clear(); + setVisible (false); + } + + /** A set of colour IDs to use to change the colour of various aspects of the label. + + These constants can be used either via the Component::setColour(), or LookAndFeel::setColour() + methods. + + Note that you can also use the constants from TextEditor::ColourIds to change the + colour of the text editor that is opened when a label is editable. + + @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour + */ + enum ColourIds + { + lassoFillColourId = 0x1000440, /**< The colour to fill the lasso rectangle with. */ + lassoOutlineColourId = 0x1000441, /**< The colour to draw the outline with. */ + }; + + /** @internal */ + void paint (Graphics& g) + { + g.fillAll (findColour (lassoFillColourId)); + + g.setColour (findColour (lassoOutlineColourId)); + g.drawRect (0, 0, getWidth(), getHeight(), outlineThickness); + + // this suggests that you've left a lasso comp lying around after the + // mouse drag has finished.. Be careful to call endLasso() when you get a + // mouse-up event. + jassert (isMouseButtonDownAnywhere()); + } + + /** @internal */ + bool hitTest (int x, int y) { return false; } + + juce_UseDebuggingNewOperator + +private: + Array originalSelection; + LassoSource * source; + int outlineThickness; +}; + +#endif // __JUCE_LASSOCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_LassoComponent.h *********/ + +#endif +#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__ + +#endif +#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ + +/********* Start of inlined file: juce_MouseHoverDetector.h *********/ +#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ +#define __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ + +/** + Monitors a component for mouse activity, and triggers a callback + when the mouse hovers in one place for a specified length of time. + + To use a hover-detector, just create one and call its setHoverComponent() + method to start it watching a component. You can call setHoverComponent (0) + to make it inactive. + + (Be careful not to delete a component that's being monitored without first + stopping or deleting the hover detector). +*/ +class JUCE_API MouseHoverDetector +{ +public: + + /** Creates a hover detector. + + Initially the object is inactive, and you need to tell it which component + to monitor, using the setHoverComponent() method. + + @param hoverTimeMillisecs the number of milliseconds for which the mouse + needs to stay still before the mouseHovered() method + is invoked. You can change this setting later with + the setHoverTimeMillisecs() method + */ + MouseHoverDetector (const int hoverTimeMillisecs = 400); + + /** Destructor. */ + virtual ~MouseHoverDetector(); + + /** Changes the time for which the mouse has to stay still before it's considered + to be hovering. + */ + void setHoverTimeMillisecs (const int newTimeInMillisecs); + + /** Changes the component that's being monitored for hovering. + + Be careful not to delete a component that's being monitored without first + stopping or deleting the hover detector. + */ + void setHoverComponent (Component* const newSourceComponent); + +protected: + + /** Called back when the mouse hovers. + + After the mouse has stayed still over the component for the length of time + specified by setHoverTimeMillisecs(), this method will be invoked. + + When the mouse is first moved after this callback has occurred, the + mouseMovedAfterHover() method will be called. + + @param mouseX the mouse's X position relative to the component being monitored + @param mouseY the mouse's Y position relative to the component being monitored + */ + virtual void mouseHovered (int mouseX, + int mouseY) = 0; + + /** Called when the mouse is moved away after just having hovered. */ + virtual void mouseMovedAfterHover() = 0; + +private: + + class JUCE_API HoverDetectorInternal : public MouseListener, + public Timer + { + public: + MouseHoverDetector* owner; + int lastX, lastY; + + void timerCallback(); + void mouseEnter (const MouseEvent&); + void mouseExit (const MouseEvent&); + void mouseDown (const MouseEvent&); + void mouseUp (const MouseEvent&); + void mouseMove (const MouseEvent&); + void mouseWheelMove (const MouseEvent&, float, float); + + } internalTimer; + + friend class HoverDetectorInternal; + + Component* source; + int hoverTimeMillisecs; + bool hasJustHovered; + + void hoverTimerCallback(); + void checkJustHoveredCallback(); +}; + +#endif // __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ +/********* End of inlined file: juce_MouseHoverDetector.h *********/ + +#endif +#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ + +#endif +#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_BooleanPropertyComponent.h *********/ +#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ + +/** + A PropertyComponent that contains an on/off toggle button. + + This type of property component can be used if you have a boolean value to + toggle on/off. + + @see PropertyComponent +*/ +class JUCE_API BooleanPropertyComponent : public PropertyComponent, + private ButtonListener +{ +public: + + /** Creates a button component. + + @param propertyName the property name to be passed to the PropertyComponent + @param buttonTextWhenTrue the text shown in the button when the value is true + @param buttonTextWhenFalse the text shown in the button when the value is false + */ + BooleanPropertyComponent (const String& propertyName, + const String& buttonTextWhenTrue, + const String& buttonTextWhenFalse); + + /** Destructor. */ + ~BooleanPropertyComponent(); + + /** Called to change the state of the boolean value. */ + virtual void setState (const bool newState) = 0; + + /** Must return the current value of the property. */ + virtual bool getState() const = 0; /** @internal */ void paint (Graphics& g); /** @internal */ - void timerCallback(); + void refresh(); + /** @internal */ + void buttonClicked (Button*); juce_UseDebuggingNewOperator private: - Image* backgroundImage; - Time earliestTimeToDelete; - int originalClickCounter; - bool isImageInCache; - - SplashScreen (const SplashScreen&); - const SplashScreen& operator= (const SplashScreen&); + ToggleButton* button; + String onText, offText; }; -#endif // __JUCE_SPLASHSCREEN_JUCEHEADER__ -/********* End of inlined file: juce_SplashScreen.h *********/ +#endif // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_BooleanPropertyComponent.h *********/ #endif -#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ +#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ -#endif -#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ - -#endif -#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ - -/********* Start of inlined file: juce_ThreadWithProgressWindow.h *********/ -#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ -#define __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ +/********* Start of inlined file: juce_ButtonPropertyComponent.h *********/ +#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ /** - A thread that automatically pops up a modal dialog box with a progress bar - and cancel button while it's busy running. + A PropertyComponent that contains a button. - These are handy for performing some sort of task while giving the user feedback - about how long there is to go, etc. + This type of property component can be used if you need a button to trigger some + kind of action. - E.g. @code - class MyTask : public ThreadWithProgressWindow - { - public: - MyTask() : ThreadWithProgressWindow (T("busy..."), true, true) - { - } - - ~MyTask() - { - } - - void run() - { - for (int i = 0; i < thingsToDo; ++i) - { - // must check this as often as possible, because this is - // how we know if the user's pressed 'cancel' - if (threadShouldExit()) - break; - - // this will update the progress bar on the dialog box - setProgress (i / (double) thingsToDo); - - // ... do the business here... - } - } - }; - - void doTheTask() - { - MyTask m; - - if (m.runThread()) - { - // thread finished normally.. - } - else - { - // user pressed the cancel button.. - } - } - - @endcode - - @see Thread, AlertWindow + @see PropertyComponent */ -class JUCE_API ThreadWithProgressWindow : public Thread, - private Timer +class JUCE_API ButtonPropertyComponent : public PropertyComponent, + private ButtonListener { public: - /** Creates the thread. + /** Creates a button component. - Initially, the dialog box won't be visible, it'll only appear when the - runThread() method is called. - - @param windowTitle the title to go at the top of the dialog box - @param hasProgressBar whether the dialog box should have a progress bar (see - setProgress() ) - @param hasCancelButton whether the dialog box should have a cancel button - @param timeOutMsWhenCancelling when 'cancel' is pressed, this is how long to wait for - the thread to stop before killing it forcibly (see - Thread::stopThread() ) - @param cancelButtonText the text that should be shown in the cancel button - (if it has one) + @param propertyName the property name to be passed to the PropertyComponent + @param triggerOnMouseDown this is passed to the Button::setTriggeredOnMouseDown() method */ - ThreadWithProgressWindow (const String& windowTitle, - const bool hasProgressBar, - const bool hasCancelButton, - const int timeOutMsWhenCancelling = 10000, - const String& cancelButtonText = JUCE_T("Cancel")); + ButtonPropertyComponent (const String& propertyName, + const bool triggerOnMouseDown); /** Destructor. */ - ~ThreadWithProgressWindow(); + ~ButtonPropertyComponent(); - /** Starts the thread and waits for it to finish. - - This will start the thread, make the dialog box appear, and wait until either - the thread finishes normally, or until the cancel button is pressed. - - Before returning, the dialog box will be hidden. - - @param threadPriority the priority to use when starting the thread - see - Thread::startThread() for values - @returns true if the thread finished normally; false if the user pressed cancel + /** Called when the user clicks the button. */ - bool runThread (const int threadPriority = 5); + virtual void buttonClicked() = 0; - /** The thread should call this periodically to update the position of the progress bar. + /** Returns the string that should be displayed in the button. - @param newProgress the progress, from 0.0 to 1.0 - @see setStatusMessage + If you need to change this string, call refresh() to update the component. */ - void setProgress (const double newProgress); + virtual const String getButtonText() const = 0; - /** The thread can call this to change the message that's displayed in the dialog box. - */ - void setStatusMessage (const String& newStatusMessage); - - /** Returns the AlertWindow that is being used. - */ - AlertWindow* getAlertWindow() const throw() { return alertWindow; } + /** @internal */ + void refresh(); + /** @internal */ + void buttonClicked (Button*); juce_UseDebuggingNewOperator private: - void timerCallback(); - - double progress; - AlertWindow* alertWindow; - String message; - CriticalSection messageLock; - const int timeOutMsWhenCancelling; - - ThreadWithProgressWindow (const ThreadWithProgressWindow&); - const ThreadWithProgressWindow& operator= (const ThreadWithProgressWindow&); + TextButton* button; }; -#endif // __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ -/********* End of inlined file: juce_ThreadWithProgressWindow.h *********/ +#endif // __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ButtonPropertyComponent.h *********/ #endif -#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ +#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_ChoicePropertyComponent.h *********/ +#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ + +/** + A PropertyComponent that shows its value as a combo box. + + This type of property component contains a list of options and has a + combo box to choose one. + + Your subclass's constructor must add some strings to the choices StringArray + and these are shown in the list. + + The getIndex() method will be called to find out which option is the currently + selected one. If you call refresh() it will call getIndex() to check whether + the value has changed, and will update the combo box if needed. + + If the user selects a different item from the list, setIndex() will be + called to let your class process this. + + @see PropertyComponent, PropertyPanel +*/ +class JUCE_API ChoicePropertyComponent : public PropertyComponent, + private ComboBoxListener +{ +public: + /** Creates the component. + + Your subclass's constructor must add a list of options to the choices + member variable. + */ + ChoicePropertyComponent (const String& propertyName); + + /** Destructor. */ + ~ChoicePropertyComponent(); + + /** Called when the user selects an item from the combo box. + + Your subclass must use this callback to update the value that this component + represents. The index is the index of the chosen item in the choices + StringArray. + */ + virtual void setIndex (const int newIndex) = 0; + + /** Returns the index of the item that should currently be shown. + + This is the index of the item in the choices StringArray that will be + shown. + */ + virtual int getIndex() const = 0; + + /** Returns the list of options. */ + const StringArray& getChoices() const throw(); + + /** @internal */ + void refresh(); + /** @internal */ + void comboBoxChanged (ComboBox*); + + juce_UseDebuggingNewOperator + +protected: + /** The list of options that will be shown in the combo box. + + Your subclass must populate this array in its constructor. If any empty + strings are added, these will be replaced with horizontal separators (see + ComboBox::addSeparator() for more info). + */ + StringArray choices; + +private: + ComboBox* comboBox; +}; + +#endif // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_ChoicePropertyComponent.h *********/ + +#endif +#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ + +#endif +#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_SliderPropertyComponent.h *********/ +#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ + +/** + A PropertyComponent that shows its value as a slider. + + @see PropertyComponent, Slider +*/ +class JUCE_API SliderPropertyComponent : public PropertyComponent, + private SliderListener +{ +public: + + /** Creates the property component. + + The ranges, interval and skew factor are passed to the Slider component. + + If you need to customise the slider in other ways, your constructor can + access the slider member variable and change it directly. + */ + SliderPropertyComponent (const String& propertyName, + const double rangeMin, + const double rangeMax, + const double interval, + const double skewFactor = 1.0); + + /** Destructor. */ + ~SliderPropertyComponent(); + + /** Called when the user moves the slider to change its value. + + Your subclass must use this method to update whatever item this property + represents. + */ + virtual void setValue (const double newValue) = 0; + + /** Returns the value that the slider should show. */ + virtual const double getValue() const = 0; + + /** @internal */ + void refresh(); + /** @internal */ + void changeListenerCallback (void*); + /** @internal */ + void sliderValueChanged (Slider*); + + juce_UseDebuggingNewOperator + +protected: + + /** The slider component being used in this component. + + Your subclass has access to this in case it needs to customise it in some way. + */ + Slider* slider; +}; + +#endif // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_SliderPropertyComponent.h *********/ + +#endif +#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_TextPropertyComponent.h *********/ +#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ +#define __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ + +/** + A PropertyComponent that shows its value as editable text. + + @see PropertyComponent +*/ +class JUCE_API TextPropertyComponent : public PropertyComponent +{ +public: + + /** Creates a text property component. + + The maxNumChars is used to set the length of string allowable, and isMultiLine + sets whether the text editor allows carriage returns. + + @see TextEditor + */ + TextPropertyComponent (const String& propertyName, + const int maxNumChars, + const bool isMultiLine); + + /** Destructor. */ + ~TextPropertyComponent(); + + /** Called when the user edits the text. + + Your subclass must use this callback to change the value of whatever item + this property component represents. + */ + virtual void setText (const String& newText) = 0; + + /** Returns the text that should be shown in the text editor. + */ + virtual const String getText() const = 0; + + /** @internal */ + void refresh(); + /** @internal */ + void textWasEdited(); + + juce_UseDebuggingNewOperator + +private: + Label* textEditor; +}; + +#endif // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_TextPropertyComponent.h *********/ #endif #ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ @@ -54699,170 +53553,6 @@ private: #endif // __JUCE_PREFERENCESPANEL_JUCEHEADER__ /********* End of inlined file: juce_PreferencesPanel.h *********/ -#endif -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_WebBrowserComponent.h *********/ -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ -#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - -#if JUCE_WEB_BROWSER || DOXYGEN - -#if ! DOXYGEN - class WebBrowserComponentInternal; -#endif - -/** - A component that displays an embedded web browser. - - The browser itself will be platform-dependent. On the Mac, probably Safari, on - Windows, probably IE. - -*/ -class JUCE_API WebBrowserComponent : public Component -{ -public: - - /** Creates a WebBrowserComponent. - - Once it's created and visible, send the browser to a URL using goToURL(). - - @param unloadPageWhenBrowserIsHidden if this is true, then when the browser - component is taken offscreen, it'll clear the current page - and replace it with a blank page - this can be handy to stop - the browser using resources in the background when it's not - actually being used. - */ - WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden = true); - - /** Destructor. */ - ~WebBrowserComponent(); - - /** Sends the browser to a particular URL. - - @param url the URL to go to. - @param headers an optional set of parameters to put in the HTTP header. If - you supply this, it should be a set of string in the form - "HeaderKey: HeaderValue" - @param postData an optional block of data that will be attached to the HTTP - POST request - */ - void goToURL (const String& url, - const StringArray* headers = 0, - const MemoryBlock* postData = 0); - - /** Stops the current page loading. - */ - void stop(); - - /** Sends the browser back one page. - */ - void goBack(); - - /** Sends the browser forward one page. - */ - void goForward(); - - /** Refreshes the browser. - */ - void refresh(); - - /** This callback is called when the browser is about to navigate - to a new location. - - You can override this method to perform some action when the user - tries to go to a particular URL. To allow the operation to carry on, - return true, or return false to stop the navigation happening. - */ - virtual bool pageAboutToLoad (const String& newURL); - - /** @internal */ - void paint (Graphics& g); - /** @internal */ - void resized(); - /** @internal */ - void parentHierarchyChanged(); - /** @internal */ - void visibilityChanged(); - - juce_UseDebuggingNewOperator - -private: - WebBrowserComponentInternal* browser; - bool blankPageShown, unloadPageWhenBrowserIsHidden; - String lastURL; - StringArray lastHeaders; - MemoryBlock lastPostData; - - void reloadLastURL(); - void checkWindowAssociation(); - - WebBrowserComponent (const WebBrowserComponent&); - const WebBrowserComponent& operator= (const WebBrowserComponent&); -}; - -#endif -#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_WebBrowserComponent.h *********/ - -#endif -#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ - -/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/ -#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ - -#if JUCE_WINDOWS || JUCE_LINUX || DOXYGEN - -/** - On Windows only, this component sits in the taskbar tray as a small icon. - - To use it, just create one of these components, but don't attempt to make it - visible, add it to a parent, or put it on the desktop. - - You can then call setIconImage() to create an icon for it in the taskbar. - - To change the icon's tooltip, you can use setIconTooltip(). - - To respond to mouse-events, you can override the normal mouseDown(), - mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y - position will not be valid, you can use this to respond to clicks. Traditionally - you'd use a left-click to show your application's window, and a right-click - to show a pop-up menu. -*/ -class JUCE_API SystemTrayIconComponent : public Component -{ -public: - - SystemTrayIconComponent(); - - /** Destructor. */ - ~SystemTrayIconComponent(); - - /** Changes the image shown in the taskbar. - */ - void setIconImage (const Image& newImage); - - /** Changes the tooltip that Windows shows above the icon. */ - void setIconTooltip (const String& tooltip); - -#if JUCE_LINUX - /** @internal */ - void paint (Graphics& g); -#endif - - juce_UseDebuggingNewOperator - -private: - - SystemTrayIconComponent (const SystemTrayIconComponent&); - const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&); -}; - -#endif -#endif // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -/********* End of inlined file: juce_SystemTrayIconComponent.h *********/ - #endif #ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__ @@ -55068,738 +53758,2320 @@ private: /********* End of inlined file: juce_QuickTimeMovieComponent.h *********/ #endif -#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ +#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -/********* Start of inlined file: juce_LookAndFeel.h *********/ -#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ -#define __JUCE_LOOKANDFEEL_JUCEHEADER__ +/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/ +#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ +#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ -class ToggleButton; -class TextButton; -class AlertWindow; -class TextLayout; -class ScrollBar; -class BubbleComponent; -class ComboBox; -class Button; -class FilenameComponent; -class DocumentWindow; -class ResizableWindow; -class GroupComponent; -class MenuBarComponent; -class DropShadower; -class GlyphArrangement; -class PropertyComponent; -class TableHeaderComponent; -class Toolbar; -class ToolbarItemComponent; -class PopupMenu; -class ProgressBar; -class FileBrowserComponent; -class DirectoryContentsDisplayComponent; -class FilePreviewComponent; -class ImageButton; +#if JUCE_WINDOWS || JUCE_LINUX || DOXYGEN /** - LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses - can be used to apply different 'skins' to the application. + On Windows only, this component sits in the taskbar tray as a small icon. + To use it, just create one of these components, but don't attempt to make it + visible, add it to a parent, or put it on the desktop. + + You can then call setIconImage() to create an icon for it in the taskbar. + + To change the icon's tooltip, you can use setIconTooltip(). + + To respond to mouse-events, you can override the normal mouseDown(), + mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y + position will not be valid, you can use this to respond to clicks. Traditionally + you'd use a left-click to show your application's window, and a right-click + to show a pop-up menu. */ -class JUCE_API LookAndFeel +class JUCE_API SystemTrayIconComponent : public Component { public: - /** Creates the default JUCE look and feel. */ - LookAndFeel(); + SystemTrayIconComponent(); /** Destructor. */ - virtual ~LookAndFeel(); + ~SystemTrayIconComponent(); - /** Returns the current default look-and-feel for a component to use when it - hasn't got one explicitly set. - - @see setDefaultLookAndFeel + /** Changes the image shown in the taskbar. */ - static LookAndFeel& getDefaultLookAndFeel() throw(); + void setIconImage (const Image& newImage); - /** Changes the default look-and-feel. + /** Changes the tooltip that Windows shows above the icon. */ + void setIconTooltip (const String& tooltip); - @param newDefaultLookAndFeel the new look-and-feel object to use - if this is - set to 0, it will revert to using the default one. The - object passed-in must be deleted by the caller when - it's no longer needed. - @see getDefaultLookAndFeel +#if JUCE_LINUX + /** @internal */ + void paint (Graphics& g); +#endif + + juce_UseDebuggingNewOperator + +private: + + SystemTrayIconComponent (const SystemTrayIconComponent&); + const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&); +}; + +#endif +#endif // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_SystemTrayIconComponent.h *********/ + +#endif +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + +/********* Start of inlined file: juce_WebBrowserComponent.h *********/ +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ +#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + +#if JUCE_WEB_BROWSER || DOXYGEN + +#if ! DOXYGEN + class WebBrowserComponentInternal; +#endif + +/** + A component that displays an embedded web browser. + + The browser itself will be platform-dependent. On the Mac, probably Safari, on + Windows, probably IE. + +*/ +class JUCE_API WebBrowserComponent : public Component +{ +public: + + /** Creates a WebBrowserComponent. + + Once it's created and visible, send the browser to a URL using goToURL(). + + @param unloadPageWhenBrowserIsHidden if this is true, then when the browser + component is taken offscreen, it'll clear the current page + and replace it with a blank page - this can be handy to stop + the browser using resources in the background when it's not + actually being used. */ - static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) throw(); + WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden = true); - /** Looks for a colour that has been registered with the given colour ID number. + /** Destructor. */ + ~WebBrowserComponent(); - If a colour has been set for this ID number using setColour(), then it is - returned. If none has been set, it will just return Colours::black. + /** Sends the browser to a particular URL. - The colour IDs for various purposes are stored as enums in the components that - they are relevent to - for an example, see Slider::ColourIds, - Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc. - - If you're looking up a colour for use in drawing a component, it's usually - best not to call this directly, but to use the Component::findColour() method - instead. That will first check whether a suitable colour has been registered - directly with the component, and will fall-back on calling the component's - LookAndFeel's findColour() method if none is found. - - @see setColour, Component::findColour, Component::setColour + @param url the URL to go to. + @param headers an optional set of parameters to put in the HTTP header. If + you supply this, it should be a set of string in the form + "HeaderKey: HeaderValue" + @param postData an optional block of data that will be attached to the HTTP + POST request */ - const Colour findColour (const int colourId) const throw(); + void goToURL (const String& url, + const StringArray* headers = 0, + const MemoryBlock* postData = 0); - /** Registers a colour to be used for a particular purpose. - - For more details, see the comments for findColour(). - - @see findColour, Component::findColour, Component::setColour + /** Stops the current page loading. */ - void setColour (const int colourId, const Colour& colour) throw(); + void stop(); - /** Returns true if the specified colour ID has been explicitly set using the - setColour() method. + /** Sends the browser back one page. */ - bool isColourSpecified (const int colourId) const throw(); + void goBack(); - virtual const Typeface::Ptr getTypefaceForFont (const Font& font); - - /** Allows you to change the default sans-serif font. - - If you need to supply your own Typeface object for any of the default fonts, rather - than just supplying the name (e.g. if you want to use an embedded font), then - you should instead override getTypefaceForFont() to create and return the typeface. + /** Sends the browser forward one page. */ - void setDefaultSansSerifTypefaceName (const String& newName); + void goForward(); - /** Override this to get the chance to swap a component's mouse cursor for a - customised one. + /** Refreshes the browser. */ - virtual const MouseCursor getMouseCursorFor (Component& component); + void refresh(); - /** Draws the lozenge-shaped background for a standard button. */ - virtual void drawButtonBackground (Graphics& g, - Button& button, - const Colour& backgroundColour, - bool isMouseOverButton, - bool isButtonDown); + /** This callback is called when the browser is about to navigate + to a new location. - virtual const Font getFontForTextButton (TextButton& button); - - /** Draws the text for a TextButton. */ - virtual void drawButtonText (Graphics& g, - TextButton& button, - bool isMouseOverButton, - bool isButtonDown); - - /** Draws the contents of a standard ToggleButton. */ - virtual void drawToggleButton (Graphics& g, - ToggleButton& button, - bool isMouseOverButton, - bool isButtonDown); - - virtual void changeToggleButtonWidthToFitText (ToggleButton& button); - - virtual void drawTickBox (Graphics& g, - Component& component, - int x, int y, int w, int h, - const bool ticked, - const bool isEnabled, - const bool isMouseOverButton, - const bool isButtonDown); - - /* AlertWindow handling.. + You can override this method to perform some action when the user + tries to go to a particular URL. To allow the operation to carry on, + return true, or return false to stop the navigation happening. */ - virtual AlertWindow* createAlertWindow (const String& title, - const String& message, - const String& button1, - const String& button2, - const String& button3, - AlertWindow::AlertIconType iconType, - int numButtons, - Component* associatedComponent); + virtual bool pageAboutToLoad (const String& newURL); - virtual void drawAlertBox (Graphics& g, - AlertWindow& alert, - const Rectangle& textArea, - TextLayout& textLayout); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void resized(); + /** @internal */ + void parentHierarchyChanged(); + /** @internal */ + void visibilityChanged(); - virtual int getAlertBoxWindowFlags(); + juce_UseDebuggingNewOperator - virtual int getAlertWindowButtonHeight(); +private: + WebBrowserComponentInternal* browser; + bool blankPageShown, unloadPageWhenBrowserIsHidden; + String lastURL; + StringArray lastHeaders; + MemoryBlock lastPostData; - virtual const Font getAlertWindowFont(); + void reloadLastURL(); + void checkWindowAssociation(); - /** Draws a progress bar. + WebBrowserComponent (const WebBrowserComponent&); + const WebBrowserComponent& operator= (const WebBrowserComponent&); +}; - If the progress value is less than 0 or greater than 1.0, this should draw a spinning - bar that fills the whole space (i.e. to say that the app is still busy but the progress - isn't known). It can use the current time as a basis for playing an animation. +#endif +#endif // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ +/********* End of inlined file: juce_WebBrowserComponent.h *********/ - (Used by progress bars in AlertWindow). +#endif +#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ + +#endif +#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ + +#endif +#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ + +/********* Start of inlined file: juce_DialogWindow.h *********/ +#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ +#define __JUCE_DIALOGWINDOW_JUCEHEADER__ + +/** + A dialog-box style window. + + This class is a convenient way of creating a DocumentWindow with a close button + that can be triggered by pressing the escape key. + + Any of the methods available to a DocumentWindow or ResizableWindow are also + available to this, so it can be made resizable, have a menu bar, etc. + + To add items to the box, see the ResizableWindow::setContentComponent() method. + Don't add components directly to this class - always put them in a content component! + + You'll need to override the DocumentWindow::closeButtonPressed() method to handle + the user clicking the close button - for more info, see the DocumentWindow + help. + + @see DocumentWindow, ResizableWindow +*/ +class JUCE_API DialogWindow : public DocumentWindow +{ +public: + + /** Creates a DialogWindow. + + @param name the name to give the component - this is also + the title shown at the top of the window. To change + this later, use setName() + @param backgroundColour the colour to use for filling the window's background. + @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the + close button to be triggered + @param addToDesktop if true, the window will be automatically added to the + desktop; if false, you can use it as a child component */ - virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar, - int width, int height, - double progress, const String& textToShow); + DialogWindow (const String& name, + const Colour& backgroundColour, + const bool escapeKeyTriggersCloseButton, + const bool addToDesktop = true); - // Draws a small image that spins to indicate that something's happening.. - // This method should use the current time to animate itself, so just keep - // repainting it every so often. - virtual void drawSpinningWaitAnimation (Graphics& g, const Colour& colour, - int x, int y, int w, int h); + /** Destructor. - /** Draws one of the buttons on a scrollbar. - - @param g the context to draw into - @param scrollbar the bar itself - @param width the width of the button - @param height the height of the button - @param buttonDirection the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left - @param isScrollbarVertical true if it's a vertical bar, false if horizontal - @param isMouseOverButton whether the mouse is currently over the button (also true if it's held down) - @param isButtonDown whether the mouse button's held down + If a content component has been set with setContentComponent(), it + will be deleted. */ - virtual void drawScrollbarButton (Graphics& g, - ScrollBar& scrollbar, - int width, int height, - int buttonDirection, - bool isScrollbarVertical, - bool isMouseOverButton, - bool isButtonDown); + ~DialogWindow(); - /** Draws the thumb area of a scrollbar. + /** Easy way of quickly showing a dialog box containing a given component. - @param g the context to draw into - @param scrollbar the bar itself - @param x the x position of the left edge of the thumb area to draw in - @param y the y position of the top edge of the thumb area to draw in - @param width the width of the thumb area to draw in - @param height the height of the thumb area to draw in - @param isScrollbarVertical true if it's a vertical bar, false if horizontal - @param thumbStartPosition for vertical bars, the y co-ordinate of the top of the - thumb, or its x position for horizontal bars - @param thumbSize for vertical bars, the height of the thumb, or its width for - horizontal bars. This may be 0 if the thumb shouldn't be drawn. - @param isMouseOver whether the mouse is over the thumb area, also true if the mouse is - currently dragging the thumb - @param isMouseDown whether the mouse is currently dragging the scrollbar + This will open and display a DialogWindow containing a given component, returning + when the user clicks its close button. + + It returns the value that was returned by the dialog box's runModalLoop() call. + + To close the dialog programatically, you should call exitModalState (returnValue) on + the DialogWindow that is created. To find a pointer to this window from your + contentComponent, you can do something like this: + @code + Dialogwindow* dw = contentComponent->findParentComponentOfClass ((DialogWindow*) 0); + + if (dw != 0) + dw->exitModalState (1234); + @endcode + + @param dialogTitle the dialog box's title + @param contentComponent the content component for the dialog box. Make sure + that this has been set to the size you want it to + be before calling this method. The component won't + be deleted by this call, so you can re-use it or delete + it afterwards + @param componentToCentreAround if this is non-zero, it indicates a component that + you'd like to show this dialog box in front of. See the + DocumentWindow::centreAroundComponent() method for more + info on this parameter + @param backgroundColour a colour to use for the dialog box's background colour + @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the + close button to be triggered + @param shouldBeResizable if true, the dialog window has either a resizable border, or + a corner resizer + @param useBottomRightCornerResizer if shouldBeResizable is true, this indicates whether + to use a border or corner resizer component. See ResizableWindow::setResizable() */ - virtual void drawScrollbar (Graphics& g, - ScrollBar& scrollbar, - int x, int y, - int width, int height, - bool isScrollbarVertical, - int thumbStartPosition, - int thumbSize, - bool isMouseOver, - bool isMouseDown); - - /** Returns the component effect to use for a scrollbar */ - virtual ImageEffectFilter* getScrollbarEffect(); - - /** Returns the minimum length in pixels to use for a scrollbar thumb. */ - virtual int getMinimumScrollbarThumbSize (ScrollBar& scrollbar); - - /** Returns the default thickness to use for a scrollbar. */ - virtual int getDefaultScrollbarWidth(); - - /** Returns the length in pixels to use for a scrollbar button. */ - virtual int getScrollbarButtonSize (ScrollBar& scrollbar); - - /** Returns a tick shape for use in yes/no boxes, etc. */ - virtual const Path getTickShape (const float height); - /** Returns a cross shape for use in yes/no boxes, etc. */ - virtual const Path getCrossShape (const float height); - - /** Draws the + or - box in a treeview. */ - virtual void drawTreeviewPlusMinusBox (Graphics& g, int x, int y, int w, int h, bool isPlus, bool isMouseOver); - - virtual void fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor); - virtual void drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor); - - // these return an image from the ImageCache, so use ImageCache::release() to free it - virtual Image* getDefaultFolderImage(); - virtual Image* getDefaultDocumentFileImage(); - - virtual void createFileChooserHeaderText (const String& title, - const String& instructions, - GlyphArrangement& destArrangement, - int width); - - virtual void drawFileBrowserRow (Graphics& g, int width, int height, - const String& filename, Image* icon, - const String& fileSizeDescription, - const String& fileTimeDescription, - const bool isDirectory, - const bool isItemSelected, - const int itemIndex); - - virtual Button* createFileBrowserGoUpButton(); - - virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp, - DirectoryContentsDisplayComponent* fileListComponent, - FilePreviewComponent* previewComp, - ComboBox* currentPathBox, - TextEditor* filenameBox, - Button* goUpButton); - - virtual void drawBubble (Graphics& g, - float tipX, float tipY, - float boxX, float boxY, float boxW, float boxH); - - /** Fills the background of a popup menu component. */ - virtual void drawPopupMenuBackground (Graphics& g, int width, int height); - - /** Draws one of the items in a popup menu. */ - virtual void drawPopupMenuItem (Graphics& g, - int width, int height, - const bool isSeparator, - const bool isActive, - const bool isHighlighted, - const bool isTicked, - const bool hasSubMenu, - const String& text, - const String& shortcutKeyText, - Image* image, - const Colour* const textColour); - - /** Returns the size and style of font to use in popup menus. */ - virtual const Font getPopupMenuFont(); - - virtual void drawPopupMenuUpDownArrow (Graphics& g, - int width, int height, - bool isScrollUpArrow); - - /** Finds the best size for an item in a popup menu. */ - virtual void getIdealPopupMenuItemSize (const String& text, - const bool isSeparator, - int standardMenuItemHeight, - int& idealWidth, - int& idealHeight); - - virtual int getMenuWindowFlags(); - - virtual void drawMenuBarBackground (Graphics& g, int width, int height, - bool isMouseOverBar, - MenuBarComponent& menuBar); - - virtual int getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText); - - virtual const Font getMenuBarFont (MenuBarComponent& menuBar, int itemIndex, const String& itemText); - - virtual void drawMenuBarItem (Graphics& g, - int width, int height, - int itemIndex, - const String& itemText, - bool isMouseOverItem, - bool isMenuOpen, - bool isMouseOverBar, - MenuBarComponent& menuBar); - - virtual void drawComboBox (Graphics& g, int width, int height, - const bool isButtonDown, - int buttonX, int buttonY, - int buttonW, int buttonH, - ComboBox& box); - - virtual const Font getComboBoxFont (ComboBox& box); - - virtual Label* createComboBoxTextBox (ComboBox& box); - - virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition); - - virtual void drawLabel (Graphics& g, Label& label); - - virtual void drawLinearSlider (Graphics& g, - int x, int y, - int width, int height, - float sliderPos, - float minSliderPos, - float maxSliderPos, - const Slider::SliderStyle style, - Slider& slider); - - virtual void drawLinearSliderBackground (Graphics& g, - int x, int y, - int width, int height, - float sliderPos, - float minSliderPos, - float maxSliderPos, - const Slider::SliderStyle style, - Slider& slider); - - virtual void drawLinearSliderThumb (Graphics& g, - int x, int y, - int width, int height, - float sliderPos, - float minSliderPos, - float maxSliderPos, - const Slider::SliderStyle style, - Slider& slider); - - virtual int getSliderThumbRadius (Slider& slider); - - virtual void drawRotarySlider (Graphics& g, - int x, int y, - int width, int height, - float sliderPosProportional, - const float rotaryStartAngle, - const float rotaryEndAngle, - Slider& slider); - - virtual Button* createSliderButton (const bool isIncrement); - virtual Label* createSliderTextBox (Slider& slider); - - virtual ImageEffectFilter* getSliderEffect(); - - virtual void getTooltipSize (const String& tipText, int& width, int& height); - - virtual void drawTooltip (Graphics& g, const String& text, int width, int height); - - virtual Button* createFilenameComponentBrowseButton (const String& text); - - virtual void layoutFilenameComponent (FilenameComponent& filenameComp, - ComboBox* filenameBox, Button* browseButton); - - virtual void drawCornerResizer (Graphics& g, - int w, int h, - bool isMouseOver, - bool isMouseDragging); - - virtual void drawResizableFrame (Graphics& g, - int w, int h, - const BorderSize& borders); - - virtual void fillResizableWindowBackground (Graphics& g, int w, int h, - const BorderSize& border, - ResizableWindow& window); - - virtual void drawResizableWindowBorder (Graphics& g, - int w, int h, - const BorderSize& border, - ResizableWindow& window); - - virtual void drawDocumentWindowTitleBar (DocumentWindow& window, - Graphics& g, int w, int h, - int titleSpaceX, int titleSpaceW, - const Image* icon, - bool drawTitleTextOnLeft); - - virtual Button* createDocumentWindowButton (int buttonType); - - virtual void positionDocumentWindowButtons (DocumentWindow& window, - int titleBarX, int titleBarY, - int titleBarW, int titleBarH, - Button* minimiseButton, - Button* maximiseButton, - Button* closeButton, - bool positionTitleBarButtonsOnLeft); - - virtual int getDefaultMenuBarHeight(); - - virtual DropShadower* createDropShadowerForComponent (Component* component); - - virtual void drawStretchableLayoutResizerBar (Graphics& g, - int w, int h, - bool isVerticalBar, - bool isMouseOver, - bool isMouseDragging); - - virtual void drawGroupComponentOutline (Graphics& g, int w, int h, - const String& text, - const Justification& position, - GroupComponent& group); - - virtual void createTabButtonShape (Path& p, - int width, int height, - int tabIndex, - const String& text, - Button& button, - TabbedButtonBar::Orientation orientation, - const bool isMouseOver, - const bool isMouseDown, - const bool isFrontTab); - - virtual void fillTabButtonShape (Graphics& g, - const Path& path, - const Colour& preferredBackgroundColour, - int tabIndex, - const String& text, - Button& button, - TabbedButtonBar::Orientation orientation, - const bool isMouseOver, - const bool isMouseDown, - const bool isFrontTab); - - virtual void drawTabButtonText (Graphics& g, - int x, int y, int w, int h, - const Colour& preferredBackgroundColour, - int tabIndex, - const String& text, - Button& button, - TabbedButtonBar::Orientation orientation, - const bool isMouseOver, - const bool isMouseDown, - const bool isFrontTab); - - virtual int getTabButtonOverlap (int tabDepth); - virtual int getTabButtonSpaceAroundImage(); - - virtual int getTabButtonBestWidth (int tabIndex, - const String& text, - int tabDepth, - Button& button); - - virtual void drawTabButton (Graphics& g, - int w, int h, - const Colour& preferredColour, - int tabIndex, - const String& text, - Button& button, - TabbedButtonBar::Orientation orientation, - const bool isMouseOver, - const bool isMouseDown, - const bool isFrontTab); - - virtual void drawTabAreaBehindFrontButton (Graphics& g, - int w, int h, - TabbedButtonBar& tabBar, - TabbedButtonBar::Orientation orientation); - - virtual Button* createTabBarExtrasButton(); - - virtual void drawImageButton (Graphics& g, Image* image, - int imageX, int imageY, int imageW, int imageH, - const Colour& overlayColour, - float imageOpacity, - ImageButton& button); - - virtual void drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header); - - virtual void drawTableHeaderColumn (Graphics& g, const String& columnName, int columnId, - int width, int height, - bool isMouseOver, bool isMouseDown, - int columnFlags); - - virtual void paintToolbarBackground (Graphics& g, int width, int height, Toolbar& toolbar); - - virtual Button* createToolbarMissingItemsButton (Toolbar& toolbar); - - virtual void paintToolbarButtonBackground (Graphics& g, int width, int height, - bool isMouseOver, bool isMouseDown, - ToolbarItemComponent& component); - - virtual void paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height, - const String& text, ToolbarItemComponent& component); - - virtual void drawPropertyPanelSectionHeader (Graphics& g, const String& name, - bool isOpen, int width, int height); - - virtual void drawPropertyComponentBackground (Graphics& g, int width, int height, - PropertyComponent& component); - - virtual void drawPropertyComponentLabel (Graphics& g, int width, int height, - PropertyComponent& component); - - virtual const Rectangle getPropertyComponentContentPosition (PropertyComponent& component); - - virtual void drawLevelMeter (Graphics& g, int width, int height, float level); - - virtual void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription); - - /** - */ - virtual void playAlertSound(); - - /** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */ - static void drawGlassSphere (Graphics& g, - const float x, const float y, - const float diameter, - const Colour& colour, - const float outlineThickness) throw(); - - static void drawGlassPointer (Graphics& g, - const float x, const float y, - const float diameter, - const Colour& colour, const float outlineThickness, - const int direction) throw(); - - /** Utility function to draw a shiny, glassy oblong (for text buttons). */ - static void drawGlassLozenge (Graphics& g, - const float x, const float y, - const float width, const float height, - const Colour& colour, - const float outlineThickness, - const float cornerSize, - const bool flatOnLeft, const bool flatOnRight, - const bool flatOnTop, const bool flatOnBottom) throw(); + static int showModalDialog (const String& dialogTitle, + Component* contentComponent, + Component* componentToCentreAround, + const Colour& backgroundColour, + const bool escapeKeyTriggersCloseButton, + const bool shouldBeResizable = false, + const bool useBottomRightCornerResizer = false); juce_UseDebuggingNewOperator protected: - // xxx the following methods are only here to cause a compiler error, because they've been - // deprecated or their parameters have changed. Hopefully these definitions should cause an - // error if you try to build a subclass with the old versions. - virtual int drawTickBox (Graphics&, int, int, int, int, bool, const bool, const bool, const bool) { return 0; } - virtual int drawProgressBar (Graphics&, int, int, int, int, float) { return 0; } - virtual int drawProgressBar (Graphics&, ProgressBar&, int, int, int, int, float) { return 0; } - virtual void getTabButtonBestWidth (int, const String&, int) {} - virtual int drawTreeviewPlusMinusBox (Graphics&, int, int, int, int, bool) { return 0; } + /** @internal */ + void resized(); private: - friend void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI(); - static void clearDefaultLookAndFeel() throw(); // called at shutdown + bool escapeKeyTriggersCloseButton; - Array colourIds; - Array colours; - - // default typeface names - String defaultSans, defaultSerif, defaultFixed; - - void drawShinyButtonShape (Graphics& g, - float x, float y, float w, float h, float maxCornerSize, - const Colour& baseColour, - const float strokeWidth, - const bool flatOnLeft, - const bool flatOnRight, - const bool flatOnTop, - const bool flatOnBottom) throw(); - - LookAndFeel (const LookAndFeel&); - const LookAndFeel& operator= (const LookAndFeel&); + DialogWindow (const DialogWindow&); + const DialogWindow& operator= (const DialogWindow&); }; -#endif // __JUCE_LOOKANDFEEL_JUCEHEADER__ -/********* End of inlined file: juce_LookAndFeel.h *********/ +#endif // __JUCE_DIALOGWINDOW_JUCEHEADER__ +/********* End of inlined file: juce_DialogWindow.h *********/ #endif -#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ +#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__ -/********* Start of inlined file: juce_OldSchoolLookAndFeel.h *********/ -#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ -#define __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ +#endif +#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ -/** - The original Juce look-and-feel. +#endif +#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ +/********* Start of inlined file: juce_SplashScreen.h *********/ +#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ +#define __JUCE_SPLASHSCREEN_JUCEHEADER__ + +/** A component for showing a splash screen while your app starts up. + + This will automatically position itself, and delete itself when the app has + finished initialising (it uses the JUCEApplication::isInitialising() to detect + this). + + To use it, just create one of these in your JUCEApplication::initialise() method, + call its show() method and let the object delete itself later. + + E.g. @code + + void MyApp::initialise (const String& commandLine) + { + SplashScreen* splash = new SplashScreen(); + + splash->show (T("welcome to my app"), + ImageCache::getFromFile (File ("/foobar/splash.jpg")), + 4000, false); + + .. no need to delete the splash screen - it'll do that itself. + } + + @endcode */ -class JUCE_API OldSchoolLookAndFeel : public LookAndFeel +class JUCE_API SplashScreen : public Component, + public Timer, + private DeletedAtShutdown { public: - /** Creates the default JUCE look and feel. */ - OldSchoolLookAndFeel(); + /** Creates a SplashScreen object. + + After creating one of these (or your subclass of it), call one of the show() + methods to display it. + */ + SplashScreen(); /** Destructor. */ - virtual ~OldSchoolLookAndFeel(); + ~SplashScreen(); - /** Draws the lozenge-shaped background for a standard button. */ - virtual void drawButtonBackground (Graphics& g, - Button& button, - const Colour& backgroundColour, - bool isMouseOverButton, - bool isButtonDown); + /** Creates a SplashScreen object that will display an image. - /** Draws the contents of a standard ToggleButton. */ - virtual void drawToggleButton (Graphics& g, - ToggleButton& button, - bool isMouseOverButton, - bool isButtonDown); + As soon as this is called, the SplashScreen will be displayed in the centre of the + screen. This method will also dispatch any pending messages to make sure that when + it returns, the splash screen has been completely drawn, and your initialisation + code can carry on. - virtual void drawTickBox (Graphics& g, - Component& component, - int x, int y, int w, int h, - const bool ticked, - const bool isEnabled, - const bool isMouseOverButton, - const bool isButtonDown); + @param title the name to give the component + @param backgroundImage an image to draw on the component. The component's size + will be set to the size of this image, and if the image is + semi-transparent, the component will be made semi-transparent + too. This image will be deleted (or released from the ImageCache + if that's how it was created) by the splash screen object when + it is itself deleted. + @param minimumTimeToDisplayFor how long (in milliseconds) the splash screen + should stay visible for. If the initialisation takes longer than + this time, the splash screen will wait for it to finish before + disappearing, but if initialisation is very quick, this lets + you make sure that people get a good look at your splash. + @param useDropShadow if true, the window will have a drop shadow + @param removeOnMouseClick if true, the window will go away as soon as the user clicks + the mouse (anywhere) + */ + void show (const String& title, + Image* const backgroundImage, + const int minimumTimeToDisplayFor, + const bool useDropShadow, + const bool removeOnMouseClick = true); - virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar, - int width, int height, - double progress, const String& textToShow); + /** Creates a SplashScreen object with a specified size. - virtual void drawScrollbarButton (Graphics& g, - ScrollBar& scrollbar, - int width, int height, - int buttonDirection, - bool isScrollbarVertical, - bool isMouseOverButton, - bool isButtonDown); + For a custom splash screen, you can use this method to display it at a certain size + and then override the paint() method yourself to do whatever's necessary. - virtual void drawScrollbar (Graphics& g, - ScrollBar& scrollbar, - int x, int y, - int width, int height, - bool isScrollbarVertical, - int thumbStartPosition, - int thumbSize, - bool isMouseOver, - bool isMouseDown); + As soon as this is called, the SplashScreen will be displayed in the centre of the + screen. This method will also dispatch any pending messages to make sure that when + it returns, the splash screen has been completely drawn, and your initialisation + code can carry on. - virtual ImageEffectFilter* getScrollbarEffect(); + @param title the name to give the component + @param width the width to use + @param height the height to use + @param minimumTimeToDisplayFor how long (in milliseconds) the splash screen + should stay visible for. If the initialisation takes longer than + this time, the splash screen will wait for it to finish before + disappearing, but if initialisation is very quick, this lets + you make sure that people get a good look at your splash. + @param useDropShadow if true, the window will have a drop shadow + @param removeOnMouseClick if true, the window will go away as soon as the user clicks + the mouse (anywhere) + */ + void show (const String& title, + const int width, + const int height, + const int minimumTimeToDisplayFor, + const bool useDropShadow, + const bool removeOnMouseClick = true); - virtual void drawTextEditorOutline (Graphics& g, - int width, int height, - TextEditor& textEditor); - - /** Fills the background of a popup menu component. */ - virtual void drawPopupMenuBackground (Graphics& g, int width, int height); - - virtual void drawMenuBarBackground (Graphics& g, int width, int height, - bool isMouseOverBar, - MenuBarComponent& menuBar); - - virtual void drawComboBox (Graphics& g, int width, int height, - const bool isButtonDown, - int buttonX, int buttonY, - int buttonW, int buttonH, - ComboBox& box); - - virtual const Font getComboBoxFont (ComboBox& box); - - virtual void drawLinearSlider (Graphics& g, - int x, int y, - int width, int height, - float sliderPos, - float minSliderPos, - float maxSliderPos, - const Slider::SliderStyle style, - Slider& slider); - - virtual int getSliderThumbRadius (Slider& slider); - - virtual Button* createSliderButton (const bool isIncrement); - - virtual ImageEffectFilter* getSliderEffect(); - - virtual void drawCornerResizer (Graphics& g, - int w, int h, - bool isMouseOver, - bool isMouseDragging); - - virtual Button* createDocumentWindowButton (int buttonType); - - virtual void positionDocumentWindowButtons (DocumentWindow& window, - int titleBarX, int titleBarY, - int titleBarW, int titleBarH, - Button* minimiseButton, - Button* maximiseButton, - Button* closeButton, - bool positionTitleBarButtonsOnLeft); + /** @internal */ + void paint (Graphics& g); + /** @internal */ + void timerCallback(); juce_UseDebuggingNewOperator private: - DropShadowEffect scrollbarShadow; + Image* backgroundImage; + Time earliestTimeToDelete; + int originalClickCounter; + bool isImageInCache; - OldSchoolLookAndFeel (const OldSchoolLookAndFeel&); - const OldSchoolLookAndFeel& operator= (const OldSchoolLookAndFeel&); + SplashScreen (const SplashScreen&); + const SplashScreen& operator= (const SplashScreen&); }; -#endif // __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ -/********* End of inlined file: juce_OldSchoolLookAndFeel.h *********/ +#endif // __JUCE_SPLASHSCREEN_JUCEHEADER__ +/********* End of inlined file: juce_SplashScreen.h *********/ + +#endif +#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ + +/********* Start of inlined file: juce_ThreadWithProgressWindow.h *********/ +#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ +#define __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ + +/** + A thread that automatically pops up a modal dialog box with a progress bar + and cancel button while it's busy running. + + These are handy for performing some sort of task while giving the user feedback + about how long there is to go, etc. + + E.g. @code + class MyTask : public ThreadWithProgressWindow + { + public: + MyTask() : ThreadWithProgressWindow (T("busy..."), true, true) + { + } + + ~MyTask() + { + } + + void run() + { + for (int i = 0; i < thingsToDo; ++i) + { + // must check this as often as possible, because this is + // how we know if the user's pressed 'cancel' + if (threadShouldExit()) + break; + + // this will update the progress bar on the dialog box + setProgress (i / (double) thingsToDo); + + // ... do the business here... + } + } + }; + + void doTheTask() + { + MyTask m; + + if (m.runThread()) + { + // thread finished normally.. + } + else + { + // user pressed the cancel button.. + } + } + + @endcode + + @see Thread, AlertWindow +*/ +class JUCE_API ThreadWithProgressWindow : public Thread, + private Timer +{ +public: + + /** Creates the thread. + + Initially, the dialog box won't be visible, it'll only appear when the + runThread() method is called. + + @param windowTitle the title to go at the top of the dialog box + @param hasProgressBar whether the dialog box should have a progress bar (see + setProgress() ) + @param hasCancelButton whether the dialog box should have a cancel button + @param timeOutMsWhenCancelling when 'cancel' is pressed, this is how long to wait for + the thread to stop before killing it forcibly (see + Thread::stopThread() ) + @param cancelButtonText the text that should be shown in the cancel button + (if it has one) + */ + ThreadWithProgressWindow (const String& windowTitle, + const bool hasProgressBar, + const bool hasCancelButton, + const int timeOutMsWhenCancelling = 10000, + const String& cancelButtonText = JUCE_T("Cancel")); + + /** Destructor. */ + ~ThreadWithProgressWindow(); + + /** Starts the thread and waits for it to finish. + + This will start the thread, make the dialog box appear, and wait until either + the thread finishes normally, or until the cancel button is pressed. + + Before returning, the dialog box will be hidden. + + @param threadPriority the priority to use when starting the thread - see + Thread::startThread() for values + @returns true if the thread finished normally; false if the user pressed cancel + */ + bool runThread (const int threadPriority = 5); + + /** The thread should call this periodically to update the position of the progress bar. + + @param newProgress the progress, from 0.0 to 1.0 + @see setStatusMessage + */ + void setProgress (const double newProgress); + + /** The thread can call this to change the message that's displayed in the dialog box. + */ + void setStatusMessage (const String& newStatusMessage); + + /** Returns the AlertWindow that is being used. + */ + AlertWindow* getAlertWindow() const throw() { return alertWindow; } + + juce_UseDebuggingNewOperator + +private: + void timerCallback(); + + double progress; + AlertWindow* alertWindow; + String message; + CriticalSection messageLock; + const int timeOutMsWhenCancelling; + + ThreadWithProgressWindow (const ThreadWithProgressWindow&); + const ThreadWithProgressWindow& operator= (const ThreadWithProgressWindow&); +}; + +#endif // __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ +/********* End of inlined file: juce_ThreadWithProgressWindow.h *********/ + +#endif +#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ + +#endif +#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ + +#endif +#ifndef __JUCE_COLOUR_JUCEHEADER__ + +#endif +#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_COLOURS_JUCEHEADER__ + +#endif +#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__ + +#endif +#ifndef __JUCE_EDGETABLE_JUCEHEADER__ + +#endif +#ifndef __JUCE_FILLTYPE_JUCEHEADER__ + +#endif +#ifndef __JUCE_GRAPHICS_JUCEHEADER__ + +#endif +#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ + +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ + +/********* Start of inlined file: juce_LowLevelGraphicsContext.h *********/ +#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ +#define __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ + +/** + Interface class for graphics context objects, used internally by the Graphics class. + + Users are not supposed to create instances of this class directly - do your drawing + via the Graphics object instead. + + It's a base class for different types of graphics context, that may perform software-based + or OS-accelerated rendering. + + E.g. the LowLevelGraphicsSoftwareRenderer renders onto an image in memory, but other + subclasses could render directly to a windows HDC, a Quartz context, or an OpenGL + context. +*/ +class JUCE_API LowLevelGraphicsContext +{ +protected: + + LowLevelGraphicsContext(); + +public: + virtual ~LowLevelGraphicsContext(); + + /** Returns true if this device is vector-based, e.g. a printer. */ + virtual bool isVectorDevice() const = 0; + + /** Moves the origin to a new position. + + The co-ords are relative to the current origin, and indicate the new position + of (0, 0). + */ + virtual void setOrigin (int x, int y) = 0; + + virtual bool clipToRectangle (const Rectangle& r) = 0; + virtual bool clipToRectangleList (const RectangleList& clipRegion) = 0; + virtual void excludeClipRectangle (const Rectangle& r) = 0; + virtual void clipToPath (const Path& path, const AffineTransform& transform) = 0; + virtual void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform) = 0; + + virtual bool clipRegionIntersects (const Rectangle& r) = 0; + virtual const Rectangle getClipBounds() const = 0; + virtual bool isClipEmpty() const = 0; + + virtual void saveState() = 0; + virtual void restoreState() = 0; + + virtual void setFill (const FillType& fillType) = 0; + virtual void setOpacity (float newOpacity) = 0; + virtual void setInterpolationQuality (Graphics::ResamplingQuality quality) = 0; + + virtual void fillRect (const Rectangle& r, const bool replaceExistingContents) = 0; + virtual void fillPath (const Path& path, const AffineTransform& transform) = 0; + + virtual void drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles) = 0; + + virtual void drawLine (double x1, double y1, double x2, double y2) = 0; + virtual void drawVerticalLine (const int x, double top, double bottom) = 0; + virtual void drawHorizontalLine (const int y, double left, double right) = 0; + + virtual void setFont (const Font& newFont) = 0; + virtual const Font getFont() = 0; + virtual void drawGlyph (int glyphNumber, const AffineTransform& transform) = 0; +}; + +#endif // __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ +/********* End of inlined file: juce_LowLevelGraphicsContext.h *********/ + +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ + +/********* Start of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/ +#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ +#define __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ + +/** + An implementation of LowLevelGraphicsContext that turns the drawing operations + into a PostScript document. + +*/ +class JUCE_API LowLevelGraphicsPostScriptRenderer : public LowLevelGraphicsContext +{ +public: + + LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript, + const String& documentTitle, + const int totalWidth, + const int totalHeight); + + ~LowLevelGraphicsPostScriptRenderer(); + + bool isVectorDevice() const; + void setOrigin (int x, int y); + + bool clipToRectangle (const Rectangle& r); + bool clipToRectangleList (const RectangleList& clipRegion); + void excludeClipRectangle (const Rectangle& r); + void clipToPath (const Path& path, const AffineTransform& transform); + void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); + + void saveState(); + void restoreState(); + + bool clipRegionIntersects (const Rectangle& r); + const Rectangle getClipBounds() const; + bool isClipEmpty() const; + + void setFill (const FillType& fillType); + void setOpacity (float opacity); + void setInterpolationQuality (Graphics::ResamplingQuality quality); + + void fillRect (const Rectangle& r, const bool replaceExistingContents); + void fillPath (const Path& path, const AffineTransform& transform); + + void drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles); + + void drawLine (double x1, double y1, double x2, double y2); + + void drawVerticalLine (const int x, double top, double bottom); + void drawHorizontalLine (const int x, double top, double bottom); + + const Font getFont(); + void setFont (const Font& newFont); + void drawGlyph (int glyphNumber, const AffineTransform& transform); + + juce_UseDebuggingNewOperator + +protected: + + OutputStream& out; + int totalWidth, totalHeight; + bool needToClip; + Colour lastColour; + + struct SavedState + { + SavedState(); + ~SavedState(); + + RectangleList clip; + int xOffset, yOffset; + FillType fillType; + Font font; + + private: + const SavedState& operator= (const SavedState&); + }; + + OwnedArray stateStack; + + void writeClip(); + void writeColour (const Colour& colour); + void writePath (const Path& path) const; + void writeXY (const float x, const float y) const; + void writeTransform (const AffineTransform& trans) const; + void writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const; + + LowLevelGraphicsPostScriptRenderer (const LowLevelGraphicsPostScriptRenderer& other); + const LowLevelGraphicsPostScriptRenderer& operator= (const LowLevelGraphicsPostScriptRenderer&); +}; + +#endif // __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ +/********* End of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/ + +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ + +/********* Start of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/ +#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ +#define __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ + +class LLGCSavedState; + +/** + A lowest-common-denominator implementation of LowLevelGraphicsContext that does all + its rendering in memory. + + User code is not supposed to create instances of this class directly - do all your + rendering via the Graphics class instead. +*/ +class JUCE_API LowLevelGraphicsSoftwareRenderer : public LowLevelGraphicsContext +{ +public: + + LowLevelGraphicsSoftwareRenderer (Image& imageToRenderOn); + ~LowLevelGraphicsSoftwareRenderer(); + + bool isVectorDevice() const; + + void setOrigin (int x, int y); + + bool clipToRectangle (const Rectangle& r); + bool clipToRectangleList (const RectangleList& clipRegion); + void excludeClipRectangle (const Rectangle& r); + void clipToPath (const Path& path, const AffineTransform& transform); + void clipToImageAlpha (const Image& sourceImage, const Rectangle& srcClip, const AffineTransform& transform); + + bool clipRegionIntersects (const Rectangle& r); + const Rectangle getClipBounds() const; + bool isClipEmpty() const; + + void saveState(); + void restoreState(); + + void setFill (const FillType& fillType); + void setOpacity (float opacity); + void setInterpolationQuality (Graphics::ResamplingQuality quality); + + void fillRect (const Rectangle& r, const bool replaceExistingContents); + void fillPath (const Path& path, const AffineTransform& transform); + + void drawImage (const Image& sourceImage, const Rectangle& srcClip, + const AffineTransform& transform, const bool fillEntireClipAsTiles); + + void drawLine (double x1, double y1, double x2, double y2); + + void drawVerticalLine (const int x, double top, double bottom); + void drawHorizontalLine (const int x, double top, double bottom); + + void setFont (const Font& newFont); + const Font getFont(); + void drawGlyph (int glyphNumber, float x, float y); + void drawGlyph (int glyphNumber, const AffineTransform& transform); + + juce_UseDebuggingNewOperator + +protected: + + Image& image; + + LLGCSavedState* currentState; + OwnedArray stateStack; + + LowLevelGraphicsSoftwareRenderer (const LowLevelGraphicsSoftwareRenderer& other); + const LowLevelGraphicsSoftwareRenderer& operator= (const LowLevelGraphicsSoftwareRenderer&); +}; + +#endif // __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ +/********* End of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/ + +#endif +#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_DRAWABLE_JUCEHEADER__ + +#endif +#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ + +/********* Start of inlined file: juce_DrawableComposite.h *********/ +#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ +#define __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ + +/** + A drawable object which acts as a container for a set of other Drawables. + + @see Drawable +*/ +class JUCE_API DrawableComposite : public Drawable +{ +public: + + /** Creates a composite Drawable. + */ + DrawableComposite(); + + /** Destructor. */ + virtual ~DrawableComposite(); + + /** Adds a new sub-drawable to this one. + + This passes in a Drawable pointer for this object to look after. To add a copy + of a drawable, use the form of this method that takes a Drawable reference instead. + + @param drawable the object to add - this will be deleted automatically + when no longer needed, so the caller mustn't keep any + pointers to it. + @param transform the transform to apply to this drawable when it's being + drawn + @param index where to insert it in the list of drawables. 0 is the back, + -1 is the front, or any value from 0 and getNumDrawables() + can be used + @see removeDrawable + */ + void insertDrawable (Drawable* drawable, + const AffineTransform& transform = AffineTransform::identity, + const int index = -1); + + /** Adds a new sub-drawable to this one. + + This takes a copy of a Drawable and adds it to this object. To pass in a Drawable + for this object to look after, use the form of this method that takes a Drawable + pointer instead. + + @param drawable the object to add - an internal copy will be made of this object + @param transform the transform to apply to this drawable when it's being + drawn + @param index where to insert it in the list of drawables. 0 is the back, + -1 is the front, or any value from 0 and getNumDrawables() + can be used + @see removeDrawable + */ + void insertDrawable (const Drawable& drawable, + const AffineTransform& transform = AffineTransform::identity, + const int index = -1); + + /** Deletes one of the Drawable objects. + + @param index the index of the drawable to delete, between 0 + and (getNumDrawables() - 1). + @param deleteDrawable if this is true, the drawable that is removed will also + be deleted. If false, it'll just be removed. + @see insertDrawable, getNumDrawables + */ + void removeDrawable (const int index, const bool deleteDrawable = true); + + /** Returns the number of drawables contained inside this one. + + @see getDrawable + */ + int getNumDrawables() const throw() { return drawables.size(); } + + /** Returns one of the drawables that are contained in this one. + + Each drawable also has a transform associated with it - you can use getDrawableTransform() + to find it. + + The pointer returned is managed by this object and will be deleted when no longer + needed, so be careful what you do with it. + + @see getNumDrawables + */ + Drawable* getDrawable (const int index) const throw() { return drawables [index]; } + + /** Returns the transform that applies to one of the drawables that are contained in this one. + + The pointer returned is managed by this object and will be deleted when no longer + needed, so be careful what you do with it. + + @see getNumDrawables + */ + const AffineTransform* getDrawableTransform (const int index) const throw() { return transforms [index]; } + + /** Brings one of the Drawables to the front. + + @param index the index of the drawable to move, between 0 + and (getNumDrawables() - 1). + @see insertDrawable, getNumDrawables + */ + void bringToFront (const int index); + + /** @internal */ + void render (const Drawable::RenderingContext& context) const; + /** @internal */ + void getBounds (float& x, float& y, float& width, float& height) const; + /** @internal */ + bool hitTest (float x, float y) const; + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + ValueTree createValueTree() const throw(); + /** @internal */ + static DrawableComposite* createFromValueTree (const ValueTree& tree) throw(); + + juce_UseDebuggingNewOperator + +private: + OwnedArray drawables; + OwnedArray transforms; + + DrawableComposite (const DrawableComposite&); + const DrawableComposite& operator= (const DrawableComposite&); +}; + +#endif // __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ +/********* End of inlined file: juce_DrawableComposite.h *********/ + +#endif +#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ + +/********* Start of inlined file: juce_DrawableImage.h *********/ +#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ +#define __JUCE_DRAWABLEIMAGE_JUCEHEADER__ + +/** + A drawable object which is a bitmap image. + + @see Drawable +*/ +class JUCE_API DrawableImage : public Drawable +{ +public: + + DrawableImage(); + + /** Destructor. */ + virtual ~DrawableImage(); + + /** Sets the image that this drawable will render. + + An internal copy is made of the image passed-in. If you want to provide an + image that this object can take charge of without needing to create a copy, + use the other setImage() method. + */ + void setImage (const Image& imageToCopy); + + /** Sets the image that this drawable will render. + + An internal copy of this will not be made, so the caller mustn't delete + the image while it's still being used by this object. + + A good way to use this is with the ImageCache - if you create an image + with ImageCache and pass it in here with releaseWhenNotNeeded = true, then + it'll be released neatly with its reference count being decreased. + + @param imageToUse the image to render + @param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, + then the image will be deleted when this object no longer + needs it - unless the image was created by the ImageCache, + in which case it will be released with ImageCache::release(). + */ + void setImage (Image* imageToUse, + const bool releaseWhenNotNeeded); + + /** Returns the current image. */ + Image* getImage() const throw() { return image; } + + /** Clears (and possibly deletes) the currently set image. */ + void clearImage(); + + /** Sets the opacity to use when drawing the image. */ + void setOpacity (const float newOpacity); + + /** Returns the image's opacity. */ + float getOpacity() const throw() { return opacity; } + + /** Sets a colour to draw over the image's alpha channel. + + By default this is transparent so isn't drawn, but if you set a non-transparent + colour here, then it will be overlaid on the image, using the image's alpha + channel as a mask. + + This is handy for doing things like darkening or lightening an image by overlaying + it with semi-transparent black or white. + */ + void setOverlayColour (const Colour& newOverlayColour); + + /** Returns the overlay colour. */ + const Colour& getOverlayColour() const throw() { return overlayColour; } + + /** @internal */ + void render (const Drawable::RenderingContext& context) const; + /** @internal */ + void getBounds (float& x, float& y, float& width, float& height) const; + /** @internal */ + bool hitTest (float x, float y) const; + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + ValueTree createValueTree() const throw(); + /** @internal */ + static DrawableImage* createFromValueTree (const ValueTree& tree) throw(); + + juce_UseDebuggingNewOperator + +private: + Image* image; + bool canDeleteImage; + float opacity; + Colour overlayColour; + + DrawableImage (const DrawableImage&); + const DrawableImage& operator= (const DrawableImage&); +}; + +#endif // __JUCE_DRAWABLEIMAGE_JUCEHEADER__ +/********* End of inlined file: juce_DrawableImage.h *********/ + +#endif +#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ + +/********* Start of inlined file: juce_DrawablePath.h *********/ +#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ +#define __JUCE_DRAWABLEPATH_JUCEHEADER__ + +/** + A drawable object which renders a filled or outlined shape. + + @see Drawable +*/ +class JUCE_API DrawablePath : public Drawable +{ +public: + + /** Creates a DrawablePath. + */ + DrawablePath(); + + /** Destructor. */ + virtual ~DrawablePath(); + + /** Changes the path that will be drawn. + + @see setFillColour, setStrokeType + */ + void setPath (const Path& newPath) throw(); + + /** Returns the current path. */ + const Path& getPath() const throw() { return path; } + + /** Sets a fill type for the path. + + This colour is used to fill the path - if you don't want the path to be + filled (e.g. if you're just drawing an outline), set this to a transparent + colour. + + @see setPath, setStrokeFill + */ + void setFill (const FillType& newFill) throw(); + + /** Returns the current fill type. + @see setFill + */ + const FillType& getFill() const throw() { return mainFill; } + + /** Sets the fill type with which the outline will be drawn. + @see setFill + */ + void setStrokeFill (const FillType& newStrokeFill) throw(); + + /** Returns the current stroke fill. + @see setStrokeFill + */ + const FillType& getStrokeFill() const throw() { return strokeFill; } + + /** Changes the properties of the outline that will be drawn around the path. + If the stroke has 0 thickness, no stroke will be drawn. + @see setStrokeThickness, setStrokeColour + */ + void setStrokeType (const PathStrokeType& newStrokeType) throw(); + + /** Changes the stroke thickness. + This is a shortcut for calling setStrokeType. + */ + void setStrokeThickness (const float newThickness) throw(); + + /** Returns the current outline style. */ + const PathStrokeType& getStrokeType() const throw() { return strokeType; } + + /** @internal */ + void render (const Drawable::RenderingContext& context) const; + /** @internal */ + void getBounds (float& x, float& y, float& width, float& height) const; + /** @internal */ + bool hitTest (float x, float y) const; + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + ValueTree createValueTree() const throw(); + /** @internal */ + static DrawablePath* createFromValueTree (const ValueTree& tree) throw(); + + juce_UseDebuggingNewOperator + +private: + Path path, stroke; + FillType mainFill, strokeFill; + PathStrokeType strokeType; + + void updateOutline(); + + DrawablePath (const DrawablePath&); + const DrawablePath& operator= (const DrawablePath&); +}; + +#endif // __JUCE_DRAWABLEPATH_JUCEHEADER__ +/********* End of inlined file: juce_DrawablePath.h *********/ + +#endif +#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ + +/********* Start of inlined file: juce_DrawableText.h *********/ +#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ +#define __JUCE_DRAWABLETEXT_JUCEHEADER__ + +/** + A drawable object which renders a line of text. + + @see Drawable +*/ +class JUCE_API DrawableText : public Drawable +{ +public: + + /** Creates a DrawableText object. */ + DrawableText(); + + /** Destructor. */ + virtual ~DrawableText(); + + /** Sets the block of text to render */ + void setText (const GlyphArrangement& newText); + + /** Sets a single line of text to render. + + This is a convenient method of adding a single line - for + more complex text, use the setText() that takes a + GlyphArrangement instead. + */ + void setText (const String& newText, const Font& fontToUse); + + /** Returns the text arrangement that was set with setText(). */ + const GlyphArrangement& getText() const throw() { return text; } + + /** Sets the colour of the text. */ + void setColour (const Colour& newColour); + + /** Returns the current text colour. */ + const Colour& getColour() const throw() { return colour; } + + /** @internal */ + void render (const Drawable::RenderingContext& context) const; + /** @internal */ + void getBounds (float& x, float& y, float& width, float& height) const; + /** @internal */ + bool hitTest (float x, float y) const; + /** @internal */ + Drawable* createCopy() const; + /** @internal */ + ValueTree createValueTree() const throw(); + /** @internal */ + static DrawableText* createFromValueTree (const ValueTree& tree) throw(); + + juce_UseDebuggingNewOperator + +private: + GlyphArrangement text; + Colour colour; + + DrawableText (const DrawableText&); + const DrawableText& operator= (const DrawableText&); +}; + +#endif // __JUCE_DRAWABLETEXT_JUCEHEADER__ +/********* End of inlined file: juce_DrawableText.h *********/ + +#endif +#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ + +#endif +#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ + +/********* Start of inlined file: juce_GlowEffect.h *********/ +#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ +#define __JUCE_GLOWEFFECT_JUCEHEADER__ + +/** + A component effect that adds a coloured blur around the component's contents. + + (This will only work on non-opaque components). + + @see Component::setComponentEffect, DropShadowEffect +*/ +class JUCE_API GlowEffect : public ImageEffectFilter +{ +public: + + /** Creates a default 'glow' effect. + + To customise its appearance, use the setGlowProperties() method. + */ + GlowEffect(); + + /** Destructor. */ + ~GlowEffect(); + + /** Sets the glow's radius and colour. + + The radius is how large the blur should be, and the colour is + used to render it (for a less intense glow, lower the colour's + opacity). + */ + void setGlowProperties (const float newRadius, + const Colour& newColour); + + /** @internal */ + void applyEffect (Image& sourceImage, Graphics& destContext); + + juce_UseDebuggingNewOperator + +private: + float radius; + Colour colour; +}; + +#endif // __JUCE_GLOWEFFECT_JUCEHEADER__ +/********* End of inlined file: juce_GlowEffect.h *********/ + +#endif +#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ + +#endif +#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ + +/********* Start of inlined file: juce_ReduceOpacityEffect.h *********/ +#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ +#define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ + +/** + An effect filter that reduces the image's opacity. + + This can be used to make a component (and its child components) more + transparent. + + @see Component::setComponentEffect +*/ +class JUCE_API ReduceOpacityEffect : public ImageEffectFilter +{ +public: + + /** Creates the effect object. + + The opacity of the component to which the effect is applied will be + scaled by the given factor (in the range 0 to 1.0f). + */ + ReduceOpacityEffect (const float opacity = 1.0f); + + /** Destructor. */ + ~ReduceOpacityEffect(); + + /** Sets how much to scale the component's opacity. + + @param newOpacity should be between 0 and 1.0f + */ + void setOpacity (const float newOpacity); + + /** @internal */ + void applyEffect (Image& sourceImage, Graphics& destContext); + + juce_UseDebuggingNewOperator + +private: + float opacity; +}; + +#endif // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ +/********* End of inlined file: juce_ReduceOpacityEffect.h *********/ + +#endif +#ifndef __JUCE_FONT_JUCEHEADER__ + +#endif +#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ + +#endif +#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ + +#endif +#ifndef __JUCE_TYPEFACE_JUCEHEADER__ + +#endif +#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ + +#endif +#ifndef __JUCE_BORDERSIZE_JUCEHEADER__ + +#endif +#ifndef __JUCE_LINE_JUCEHEADER__ + +#endif +#ifndef __JUCE_PATH_JUCEHEADER__ + +#endif +#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ + +/********* Start of inlined file: juce_PathIterator.h *********/ +#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ +#define __JUCE_PATHITERATOR_JUCEHEADER__ + +/** + Flattens a Path object into a series of straight-line sections. + + Use one of these to iterate through a Path object, and it will convert + all the curves into line sections so it's easy to render or perform + geometric operations on. + + @see Path +*/ +class JUCE_API PathFlatteningIterator +{ +public: + + /** Creates a PathFlatteningIterator. + + After creation, use the next() method to initialise the fields in the + object with the first line's position. + + @param path the path to iterate along + @param transform a transform to apply to each point in the path being iterated + @param tolerence the amount by which the curves are allowed to deviate from the + lines into which they are being broken down - a higher tolerence + is a bit faster, but less smooth. + */ + PathFlatteningIterator (const Path& path, + const AffineTransform& transform = AffineTransform::identity, + float tolerence = 6.0f) throw(); + + /** Destructor. */ + ~PathFlatteningIterator() throw(); + + /** Fetches the next line segment from the path. + + This will update the member variables x1, y1, x2, y2, subPathIndex and closesSubPath + so that they describe the new line segment. + + @returns false when there are no more lines to fetch. + */ + bool next() throw(); + + /** The x position of the start of the current line segment. */ + float x1; + /** The y position of the start of the current line segment. */ + float y1; + /** The x position of the end of the current line segment. */ + float x2; + /** The y position of the end of the current line segment. */ + float y2; + + /** Indicates whether the current line segment is closing a sub-path. + + If the current line is the one that connects the end of a sub-path + back to the start again, this will be true. + */ + bool closesSubPath; + + /** The index of the current line within the current sub-path. + + E.g. you can use this to see whether the line is the first one in the + subpath by seeing if it's 0. + */ + int subPathIndex; + + /** Returns true if the current segment is the last in the current sub-path. */ + bool isLastInSubpath() const throw() { return stackPos == stackBase + && (index >= path.numElements + || points [index] == Path::moveMarker); } + + juce_UseDebuggingNewOperator + +private: + const Path& path; + const AffineTransform transform; + float* points; + float tolerence, subPathCloseX, subPathCloseY; + bool isIdentityTransform; + + HeapBlock stackBase; + float* stackPos; + int index, stackSize; + + PathFlatteningIterator (const PathFlatteningIterator&); + const PathFlatteningIterator& operator= (const PathFlatteningIterator&); +}; + +#endif // __JUCE_PATHITERATOR_JUCEHEADER__ +/********* End of inlined file: juce_PathIterator.h *********/ + +#endif +#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ + +#endif +#ifndef __JUCE_POINT_JUCEHEADER__ + +#endif +#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ + +/********* Start of inlined file: juce_PositionedRectangle.h *********/ +#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ +#define __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ + +/** + A rectangle whose co-ordinates can be defined in terms of absolute or + proportional distances. + + Designed mainly for storing component positions, this gives you a lot of + control over how each co-ordinate is stored, either as an absolute position, + or as a proportion of the size of a parent rectangle. + + It also allows you to define the anchor points by which the rectangle is + positioned, so for example you could specify that the top right of the + rectangle should be an absolute distance from its parent's bottom-right corner. + + This object can be stored as a string, which takes the form "x y w h", including + symbols like '%' and letters to indicate the anchor point. See its toString() + method for more info. + + Example usage: + @code + class MyComponent + { + void resized() + { + // this will set the child component's x to be 20% of our width, its y + // to be 30, its width to be 150, and its height to be 50% of our + // height.. + const PositionedRectangle pos1 ("20% 30 150 50%"); + pos1.applyToComponent (*myChildComponent1); + + // this will inset the child component with a gap of 10 pixels + // around each of its edges.. + const PositionedRectangle pos2 ("10 10 20M 20M"); + pos2.applyToComponent (*myChildComponent2); + } + }; + @endcode +*/ +class JUCE_API PositionedRectangle +{ +public: + + /** Creates an empty rectangle with all co-ordinates set to zero. + + The default anchor point is top-left; the default + */ + PositionedRectangle() throw(); + + /** Initialises a PositionedRectangle from a saved string version. + + The string must be in the format generated by toString(). + */ + PositionedRectangle (const String& stringVersion) throw(); + + /** Creates a copy of another PositionedRectangle. */ + PositionedRectangle (const PositionedRectangle& other) throw(); + + /** Copies another PositionedRectangle. */ + const PositionedRectangle& operator= (const PositionedRectangle& other) throw(); + + /** Destructor. */ + ~PositionedRectangle() throw(); + + /** Returns a string version of this position, from which it can later be + re-generated. + + The format is four co-ordinates, "x y w h". + + - If a co-ordinate is absolute, it is stored as an integer, e.g. "100". + - If a co-ordinate is proportional to its parent's width or height, it is stored + as a percentage, e.g. "80%". + - If the X or Y co-ordinate is relative to the parent's right or bottom edge, the + number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from + the parent's right-hand edge. + - If the X or Y co-ordinate is relative to the parent's centre, the number has "C" + appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre. + - If the X or Y co-ordinate should be anchored at the component's right or bottom + edge, then it has "r" appended to it. So "-50Rr" would mean that this component's + right-hand edge should be 50 pixels left of the parent's right-hand edge. + - If the X or Y co-ordinate should be anchored at the component's centre, then it + has "c" appended to it. So "-50Rc" would mean that this component's + centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that + this component's centre should be placed 40% across the parent's width. + - If it's a width or height that should use the parentSizeMinusAbsolute mode, then + the number has "M" appended to it. + + To reload a stored string, use the constructor that takes a string parameter. + */ + const String toString() const throw(); + + /** Calculates the absolute position, given the size of the space that + it should go in. + + This will work out any proportional distances and sizes relative to the + target rectangle, and will return the absolute position. + + @see applyToComponent + */ + const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw(); + + /** Same as getRectangle(), but returning the values as doubles rather than ints. + */ + void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo, + double& x, + double& y, + double& width, + double& height) const throw(); + + /** This sets the bounds of the given component to this position. + + This is equivalent to writing: + @code + comp.setBounds (getRectangle (Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight()))); + @endcode + + @see getRectangle, updateFromComponent + */ + void applyToComponent (Component& comp) const throw(); + + /** Updates this object's co-ordinates to match the given rectangle. + + This will set all co-ordinates based on the given rectangle, re-calculating + any proportional distances, and using the current anchor points. + + So for example if the x co-ordinate mode is currently proportional, this will + re-calculate x based on the rectangle's relative position within the target + rectangle's width. + + If the target rectangle's width or height are zero then it may not be possible + to re-calculate some proportional co-ordinates. In this case, those co-ordinates + will not be changed. + */ + void updateFrom (const Rectangle& newPosition, + const Rectangle& targetSpaceToBeRelativeTo) throw(); + + /** Same functionality as updateFrom(), but taking doubles instead of ints. + */ + void updateFromDouble (const double x, const double y, + const double width, const double height, + const Rectangle& targetSpaceToBeRelativeTo) throw(); + + /** Updates this object's co-ordinates to match the bounds of this component. + + This is equivalent to calling updateFrom() with the component's bounds and + it parent size. + + If the component doesn't currently have a parent, then proportional co-ordinates + might not be updated because it would need to know the parent's size to do the + maths for this. + */ + void updateFromComponent (const Component& comp) throw(); + + /** Specifies the point within the rectangle, relative to which it should be positioned. */ + enum AnchorPoint + { + anchorAtLeftOrTop = 1 << 0, /**< The x or y co-ordinate specifies where the left or top edge of the rectangle should be. */ + anchorAtRightOrBottom = 1 << 1, /**< The x or y co-ordinate specifies where the right or bottom edge of the rectangle should be. */ + anchorAtCentre = 1 << 2 /**< The x or y co-ordinate specifies where the centre of the rectangle should be. */ + }; + + /** Specifies how an x or y co-ordinate should be interpreted. */ + enum PositionMode + { + absoluteFromParentTopLeft = 1 << 3, /**< The x or y co-ordinate specifies an absolute distance from the parent's top or left edge. */ + absoluteFromParentBottomRight = 1 << 4, /**< The x or y co-ordinate specifies an absolute distance from the parent's bottom or right edge. */ + absoluteFromParentCentre = 1 << 5, /**< The x or y co-ordinate specifies an absolute distance from the parent's centre. */ + proportionOfParentSize = 1 << 6 /**< The x or y co-ordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */ + }; + + /** Specifies how the width or height should be interpreted. */ + enum SizeMode + { + absoluteSize = 1 << 0, /**< The width or height specifies an absolute size. */ + parentSizeMinusAbsolute = 1 << 1, /**< The width or height is an amount that should be subtracted from the parent's width or height. */ + proportionalSize = 1 << 2, /**< The width or height specifies a proportion of the parent's width or height. */ + }; + + /** Sets all options for all co-ordinates. + + This requires a reference rectangle to be specified, because if you're changing any + of the modes from proportional to absolute or vice-versa, then it'll need to convert + the co-ordinates, and will need to know the parent size so it can calculate this. + */ + void setModes (const AnchorPoint xAnchorMode, + const PositionMode xPositionMode, + const AnchorPoint yAnchorMode, + const PositionMode yPositionMode, + const SizeMode widthMode, + const SizeMode heightMode, + const Rectangle& targetSpaceToBeRelativeTo) throw(); + + /** Returns the anchoring mode for the x co-ordinate. + To change any of the modes, use setModes(). + */ + AnchorPoint getAnchorPointX() const throw(); + + /** Returns the positioning mode for the x co-ordinate. + To change any of the modes, use setModes(). + */ + PositionMode getPositionModeX() const throw(); + + /** Returns the raw x co-ordinate. + + If the x position mode is absolute, then this will be the absolute value. If it's + proportional, then this will be a fractional proportion, where 1.0 means the full + width of the parent space. + */ + double getX() const throw() { return x; } + + /** Sets the raw value of the x co-ordinate. + + See getX() for the meaning of this value. + */ + void setX (const double newX) throw() { x = newX; } + + /** Returns the anchoring mode for the y co-ordinate. + To change any of the modes, use setModes(). + */ + AnchorPoint getAnchorPointY() const throw(); + + /** Returns the positioning mode for the y co-ordinate. + To change any of the modes, use setModes(). + */ + PositionMode getPositionModeY() const throw(); + + /** Returns the raw y co-ordinate. + + If the y position mode is absolute, then this will be the absolute value. If it's + proportional, then this will be a fractional proportion, where 1.0 means the full + height of the parent space. + */ + double getY() const throw() { return y; } + + /** Sets the raw value of the y co-ordinate. + + See getY() for the meaning of this value. + */ + void setY (const double newY) throw() { y = newY; } + + /** Returns the mode used to calculate the width. + To change any of the modes, use setModes(). + */ + SizeMode getWidthMode() const throw(); + + /** Returns the raw width value. + + If the width mode is absolute, then this will be the absolute value. If the mode is + proportional, then this will be a fractional proportion, where 1.0 means the full + width of the parent space. + */ + double getWidth() const throw() { return w; } + + /** Sets the raw width value. + + See getWidth() for the details about what this value means. + */ + void setWidth (const double newWidth) throw() { w = newWidth; } + + /** Returns the mode used to calculate the height. + To change any of the modes, use setModes(). + */ + SizeMode getHeightMode() const throw(); + + /** Returns the raw height value. + + If the height mode is absolute, then this will be the absolute value. If the mode is + proportional, then this will be a fractional proportion, where 1.0 means the full + height of the parent space. + */ + double getHeight() const throw() { return h; } + + /** Sets the raw height value. + + See getHeight() for the details about what this value means. + */ + void setHeight (const double newHeight) throw() { h = newHeight; } + + /** If the size and position are constance, and wouldn't be affected by changes + in the parent's size, then this will return true. + */ + bool isPositionAbsolute() const throw(); + + /** Compares two objects. */ + const bool operator== (const PositionedRectangle& other) const throw(); + + /** Compares two objects. */ + const bool operator!= (const PositionedRectangle& other) const throw(); + + juce_UseDebuggingNewOperator + +private: + double x, y, w, h; + uint8 xMode, yMode, wMode, hMode; + + void addPosDescription (String& result, const uint8 mode, const double value) const throw(); + void addSizeDescription (String& result, const uint8 mode, const double value) const throw(); + void decodePosString (const String& s, uint8& mode, double& value) throw(); + void decodeSizeString (const String& s, uint8& mode, double& value) throw(); + void applyPosAndSize (double& xOut, double& wOut, const double x, const double w, + const uint8 xMode, const uint8 wMode, + const int parentPos, const int parentSize) const throw(); + void updatePosAndSize (double& xOut, double& wOut, double x, const double w, + const uint8 xMode, const uint8 wMode, + const int parentPos, const int parentSize) const throw(); +}; + +#endif // __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ +/********* End of inlined file: juce_PositionedRectangle.h *********/ + +#endif +#ifndef __JUCE_RECTANGLE_JUCEHEADER__ + +#endif +#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ + +#endif +#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ + +/********* Start of inlined file: juce_CameraDevice.h *********/ +#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ +#define __JUCE_CAMERADEVICE_JUCEHEADER__ + +#if JUCE_USE_CAMERA + +/** + Receives callbacks with images from a CameraDevice. + + @see CameraDevice::addListener +*/ +class CameraImageListener +{ +public: + CameraImageListener() {} + virtual ~CameraImageListener() {} + + /** This method is called when a new image arrives. + + This may be called by any thread, so be careful about thread-safety, + and make sure that you process the data as quickly as possible to + avoid glitching! + */ + virtual void imageReceived (Image& image) = 0; +}; + +/** + Controls any camera capture devices that might be available. + + Use getAvailableDevices() to list the devices that are attached to the + system, then call openDevice to open one for use. Once you have a CameraDevice + object, you can get a viewer component from it, and use its methods to + stream to a file or capture still-frames. +*/ +class JUCE_API CameraDevice +{ +public: + /** Destructor. */ + virtual ~CameraDevice(); + + /** Returns a list of the available cameras on this machine. + + You can open one of these devices by calling openDevice(). + */ + static const StringArray getAvailableDevices(); + + /** Opens a camera device. + + The index parameter indicates which of the items returned by getAvailableDevices() + to open. + + The size constraints allow the method to choose between different resolutions if + the camera supports this. If the resolution cam't be specified (e.g. on the Mac) + then these will be ignored. + */ + static CameraDevice* openDevice (int deviceIndex, + int minWidth = 128, int minHeight = 64, + int maxWidth = 1024, int maxHeight = 768); + + /** Returns the name of this device */ + const String getName() const throw() { return name; } + + /** Creates a component that can be used to display a preview of the + video from this camera. + */ + Component* createViewerComponent(); + + /** Starts recording video to the specified file. + + You should use getFileExtension() to find out the correct extension to + use for your filename. + + If the file exists, it will be deleted before the recording starts. + + This method may not start recording instantly, so if you need to know the + exact time at which the file begins, you can call getTimeOfFirstRecordedFrame() + after the recording has finished. + */ + void startRecordingToFile (const File& file); + + /** Stops recording, after a call to startRecordingToFile(). + */ + void stopRecording(); + + /** Returns the file extension that should be used for the files + that you pass to startRecordingToFile(). + + This may be platform-specific, e.g. ".mov" or ".avi". + */ + static const String getFileExtension(); + + /** After calling stopRecording(), this method can be called to return the timestamp + of the first frame that was written to the file. + */ + const Time getTimeOfFirstRecordedFrame() const; + + /** Adds a listener to receive images from the camera. + + Be very careful not to delete the listener without first removing it by calling + removeListener(). + */ + void addListener (CameraImageListener* listenerToAdd); + + /** Removes a listener that was previously added with addListener(). + */ + void removeListener (CameraImageListener* listenerToRemove); + + juce_UseDebuggingNewOperator + +protected: + /** @internal */ + CameraDevice (const String& name, int index); + +private: + void* internal; + bool isRecording; + String name; + + CameraDevice (const CameraDevice&); + const CameraDevice& operator= (const CameraDevice&); +}; + +#endif +#endif // __JUCE_CAMERADEVICE_JUCEHEADER__ +/********* End of inlined file: juce_CameraDevice.h *********/ + +#endif +#ifndef __JUCE_IMAGE_JUCEHEADER__ + +#endif +#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ + +/********* Start of inlined file: juce_ImageCache.h *********/ +#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ +#define __JUCE_IMAGECACHE_JUCEHEADER__ + +/** + A global cache of images that have been loaded from files or memory. + + If you're loading an image and may need to use the image in more than one + place, this is used to allow the same image to be shared rather than loading + multiple copies into memory. + + Another advantage is that after images are released, they will be kept in + memory for a few seconds before it is actually deleted, so if you're repeatedly + loading/deleting the same image, it'll reduce the chances of having to reload it + each time. + + @see Image, ImageFileFormat +*/ +class JUCE_API ImageCache : private DeletedAtShutdown, + private Timer +{ +public: + + /** Loads an image from a file, (or just returns the image if it's already cached). + + If the cache already contains an image that was loaded from this file, + that image will be returned. Otherwise, this method will try to load the + file, add it to the cache, and return it. + + It's very important not to delete the image that is returned - instead use + the ImageCache::release() method. + + Also, remember that the image returned is shared, so drawing into it might + affect other things that are using it! + + @param file the file to try to load + @returns the image, or null if it there was an error loading it + @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom + */ + static Image* getFromFile (const File& file); + + /** Loads an image from an in-memory image file, (or just returns the image if it's already cached). + + If the cache already contains an image that was loaded from this block of memory, + that image will be returned. Otherwise, this method will try to load the + file, add it to the cache, and return it. + + It's very important not to delete the image that is returned - instead use + the ImageCache::release() method. + + Also, remember that the image returned is shared, so drawing into it might + affect other things that are using it! + + @param imageData the block of memory containing the image data + @param dataSize the data size in bytes + @returns the image, or null if it there was an error loading it + @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom + */ + static Image* getFromMemory (const void* imageData, + const int dataSize); + + /** Releases an image that was previously created by the ImageCache. + + If an image has been returned by the getFromFile() or getFromMemory() methods, + it mustn't be deleted directly, but should be released with this method + instead. + + @see getFromFile, getFromMemory + */ + static void release (Image* const imageToRelease); + + /** Checks whether an image is in the cache or not. + + @returns true if the image is currently in the cache + */ + static bool isImageInCache (Image* const imageToLookFor); + + /** Increments the reference-count for a cached image. + + If the image isn't in the cache, this method won't do anything. + */ + static void incReferenceCount (Image* const image); + + /** Checks the cache for an image with a particular hashcode. + + If there's an image in the cache with this hashcode, it will be returned, + otherwise it will return zero. + + If an image is returned, it must be released with the release() method + when no longer needed, to maintain the correct reference counts. + + @param hashCode the hash code that would have been associated with the + image by addImageToCache() + @see addImageToCache + */ + static Image* getFromHashCode (const int64 hashCode); + + /** Adds an image to the cache with a user-defined hash-code. + + After calling this, responsibilty for deleting the image will be taken + by the ImageCache. + + The image will be initially be given a reference count of 1, so call + the release() method to delete it. + + @param image the image to add + @param hashCode the hash-code to associate with it + @see getFromHashCode + */ + static void addImageToCache (Image* const image, + const int64 hashCode); + + /** Changes the amount of time before an unused image will be removed from the cache. + + By default this is about 5 seconds. + */ + static void setCacheTimeout (const int millisecs); + + juce_UseDebuggingNewOperator + +private: + + CriticalSection lock; + VoidArray images; + + ImageCache() throw(); + ImageCache (const ImageCache&); + const ImageCache& operator= (const ImageCache&); + ~ImageCache(); + + void timerCallback(); +}; + +#endif // __JUCE_IMAGECACHE_JUCEHEADER__ +/********* End of inlined file: juce_ImageCache.h *********/ + +#endif +#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ + +/********* Start of inlined file: juce_ImageConvolutionKernel.h *********/ +#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ +#define __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ + +/** + Represents a filter kernel to use in convoluting an image. + + @see Image::applyConvolution +*/ +class JUCE_API ImageConvolutionKernel +{ +public: + + /** Creates an empty convulution kernel. + + @param size the length of each dimension of the kernel, so e.g. if the size + is 5, it will create a 5x5 kernel + */ + ImageConvolutionKernel (const int size) throw(); + + /** Destructor. */ + ~ImageConvolutionKernel() throw(); + + /** Resets all values in the kernel to zero. + */ + void clear() throw(); + + /** Sets the value of a specific cell in the kernel. + + The x and y parameters must be in the range 0 < x < getKernelSize(). + + @see setOverallSum + */ + void setKernelValue (const int x, + const int y, + const float value) throw(); + + /** Rescales all values in the kernel to make the total add up to a fixed value. + + This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum). + */ + void setOverallSum (const float desiredTotalSum) throw(); + + /** Multiplies all values in the kernel by a value. */ + void rescaleAllValues (const float multiplier) throw(); + + /** Intialises the kernel for a gaussian blur. + + @param blurRadius this may be larger or smaller than the kernel's actual + size but this will obviously be wasteful or clip at the + edges. Ideally the kernel should be just larger than + (blurRadius * 2). + */ + void createGaussianBlur (const float blurRadius) throw(); + + /** Returns the size of the kernel. + + E.g. if it's a 3x3 kernel, this returns 3. + */ + int getKernelSize() const throw() { return size; } + + /** Returns a 2-dimensional array of the kernel's values. + + The size of each dimension of the array will be getKernelSize(). + */ + float** getValues() const throw() { return values; } + + /** Applies the kernel to an image. + + @param destImage the image that will receive the resultant convoluted pixels. + @param sourceImage an optional source image to read from - if this is 0, then the + destination image will be used as the source. If an image is + specified, it must be exactly the same size and type as the destination + image. + @param x the region of the image to apply the filter to + @param y the region of the image to apply the filter to + @param width the region of the image to apply the filter to + @param height the region of the image to apply the filter to + */ + void applyToImage (Image& destImage, + const Image* sourceImage, + int x, + int y, + int width, + int height) const; + + juce_UseDebuggingNewOperator + +private: + HeapBlock values; + const int size; + + // no reason not to implement these one day.. + ImageConvolutionKernel (const ImageConvolutionKernel&); + const ImageConvolutionKernel& operator= (const ImageConvolutionKernel&); +}; + +#endif // __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ +/********* End of inlined file: juce_ImageConvolutionKernel.h *********/ + +#endif +#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ + +/********* Start of inlined file: juce_ImageFileFormat.h *********/ +#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ +#define __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ + +/** + Base-class for codecs that can read and write image file formats such + as PNG, JPEG, etc. + + This class also contains static methods to make it easy to load images + from files, streams or from memory. + + @see Image, ImageCache +*/ +class JUCE_API ImageFileFormat +{ +protected: + + /** Creates an ImageFormat. */ + ImageFileFormat() throw() {} + +public: + /** Destructor. */ + virtual ~ImageFileFormat() throw() {} + + /** Returns a description of this file format. + + E.g. "JPEG", "PNG" + */ + virtual const String getFormatName() = 0; + + /** Returns true if the given stream seems to contain data that this format + understands. + + The format class should only read the first few bytes of the stream and sniff + for header bytes that it understands. + + @see decodeImage + */ + virtual bool canUnderstand (InputStream& input) = 0; + + /** Tries to decode and return an image from the given stream. + + This will be called for an image format after calling its canUnderStand() method + to see if it can handle the stream. + + @param input the stream to read the data from. The stream will be positioned + at the start of the image data (but this may not necessarily + be position 0) + @returns the image that was decoded, or 0 if it fails. It's the + caller's responsibility to delete this image when no longer needed. + @see loadFrom + */ + virtual Image* decodeImage (InputStream& input) = 0; + + /** Attempts to write an image to a stream. + + To specify extra information like encoding quality, there will be appropriate parameters + in the subclasses of the specific file types. + + @returns true if it nothing went wrong. + */ + virtual bool writeImageToStream (const Image& sourceImage, + OutputStream& destStream) = 0; + + /** Tries the built-in decoders to see if it can find one to read this stream. + + There are currently built-in decoders for PNG, JPEG and GIF formats. + + The object that is returned should not be deleted by the caller. + + @see canUnderstand, decodeImage, loadFrom + */ + static ImageFileFormat* findImageFormatForStream (InputStream& input); + + /** Tries to load an image from a stream. + + This will use the findImageFormatForStream() method to locate a suitable + codec, and use that to load the image. + + @returns the image that was decoded, or 0 if it fails to load one. It's the + caller's responsibility to delete this image when no longer needed. + */ + static Image* loadFrom (InputStream& input); + + /** Tries to load an image from a file. + + This will use the findImageFormatForStream() method to locate a suitable + codec, and use that to load the image. + + @returns the image that was decoded, or 0 if it fails to load one. It's the + caller's responsibility to delete this image when no longer needed. + */ + static Image* loadFrom (const File& file); + + /** Tries to load an image from a block of raw image data. + + This will use the findImageFormatForStream() method to locate a suitable + codec, and use that to load the image. + + @returns the image that was decoded, or 0 if it fails to load one. It's the + caller's responsibility to delete this image when no longer needed. + */ + static Image* loadFrom (const void* rawData, + const int numBytesOfData); + +}; + +/** + A type of ImageFileFormat for reading and writing PNG files. + + @see ImageFileFormat, JPEGImageFormat +*/ +class JUCE_API PNGImageFormat : public ImageFileFormat +{ +public: + + PNGImageFormat() throw(); + ~PNGImageFormat() throw(); + + const String getFormatName(); + bool canUnderstand (InputStream& input); + + Image* decodeImage (InputStream& input); + + bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); +}; + +/** + A type of ImageFileFormat for reading and writing JPEG files. + + @see ImageFileFormat, PNGImageFormat +*/ +class JUCE_API JPEGImageFormat : public ImageFileFormat +{ +public: + + JPEGImageFormat() throw(); + ~JPEGImageFormat() throw(); + + /** Specifies the quality to be used when writing a JPEG file. + + @param newQuality a value 0 to 1.0, where 0 is low quality, 1.0 is best, or + any negative value is "default" quality + */ + void setQuality (const float newQuality); + + const String getFormatName(); + + bool canUnderstand (InputStream& input); + + Image* decodeImage (InputStream& input); + + bool writeImageToStream (const Image& sourceImage, OutputStream& destStream); + +private: + float quality; +}; + +#endif // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ +/********* End of inlined file: juce_ImageFileFormat.h *********/ #endif #ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ diff --git a/src/audio/audio_file_formats/juce_AudioCDReader.h b/src/audio/audio_file_formats/juce_AudioCDReader.h index c4739b6af2..1ee92fa095 100644 --- a/src/audio/audio_file_formats/juce_AudioCDReader.h +++ b/src/audio/audio_file_formats/juce_AudioCDReader.h @@ -29,6 +29,7 @@ #if JUCE_USE_CDREADER #include "juce_AudioFormatReader.h" +#include "../../containers/juce_Array.h" #include "../../text/juce_StringArray.h" #if JUCE_MAC #include "../../io/files/juce_File.h" diff --git a/src/audio/audio_file_formats/juce_AudioFormat.h b/src/audio/audio_file_formats/juce_AudioFormat.h index 14c832678e..213d200b95 100644 --- a/src/audio/audio_file_formats/juce_AudioFormat.h +++ b/src/audio/audio_file_formats/juce_AudioFormat.h @@ -28,6 +28,7 @@ #include "juce_AudioFormatReader.h" #include "juce_AudioFormatWriter.h" +#include "../../containers/juce_Array.h" //============================================================================== diff --git a/src/audio/audio_file_formats/juce_AudioFormatManager.h b/src/audio/audio_file_formats/juce_AudioFormatManager.h index 47f8c7490a..78c3ae44af 100644 --- a/src/audio/audio_file_formats/juce_AudioFormatManager.h +++ b/src/audio/audio_file_formats/juce_AudioFormatManager.h @@ -28,6 +28,7 @@ #include "juce_AudioFormat.h" #include "../../core/juce_Singleton.h" +#include "../../containers/juce_VoidArray.h" //============================================================================== diff --git a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp index 6a141b2de9..b99fc0c43f 100644 --- a/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp @@ -85,7 +85,7 @@ public: lastThreadId (0), dataHandle (0) { - bufferList = (AudioBufferList*) juce_calloc (256); + bufferList.calloc (256, 1); #ifdef WIN32 if (InitializeQTML (0) != noErr) @@ -143,24 +143,22 @@ public: if (err != noErr) return; - AudioChannelLayout* const qt_audio_channel_layout - = (AudioChannelLayout*) juce_calloc (output_layout_size); + HeapBlock qt_audio_channel_layout; + qt_audio_channel_layout.calloc (output_layout_size, 1); err = MovieAudioExtractionGetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, output_layout_size, qt_audio_channel_layout, 0); - qt_audio_channel_layout->mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; + qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo; err = MovieAudioExtractionSetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout, - sizeof (qt_audio_channel_layout), + output_layout_size, qt_audio_channel_layout); - juce_free (qt_audio_channel_layout); - err = MovieAudioExtractionGetProperty (extractor, kQTPropertyClass_MovieAudioExtraction_Audio, kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, @@ -223,7 +221,6 @@ public: DisposeMovie (movie); juce_free (bufferList->mBuffers[0].mData); - juce_free (bufferList); #if JUCE_MAC ExitMoviesOnThread (); @@ -308,7 +305,7 @@ private: Thread::ThreadID lastThreadId; MovieAudioExtractionRef extractor; AudioStreamBasicDescription inputStreamDesc; - AudioBufferList* bufferList; + HeapBlock bufferList; Handle dataHandle; /*OSErr readMovieStream (long offset, long size, void* dataPtr) diff --git a/src/audio/audio_file_formats/juce_WavAudioFormat.cpp b/src/audio/audio_file_formats/juce_WavAudioFormat.cpp index 927eeb6ffd..17324d65d6 100644 --- a/src/audio/audio_file_formats/juce_WavAudioFormat.cpp +++ b/src/audio/audio_file_formats/juce_WavAudioFormat.cpp @@ -276,17 +276,17 @@ public: bwavSize = length; // Broadcast-wav extension chunk.. - BWAVChunk* const bwav = (BWAVChunk*) juce_calloc (jmax (length + 1, (int) sizeof (BWAVChunk))); + HeapBlock bwav; + bwav.calloc (jmax (length + 1, (int) sizeof (BWAVChunk)), 1); input->read (bwav, length); bwav->copyTo (metadataValues); - juce_free (bwav); } else if (chunkType == chunkName ("smpl")) { - SMPLChunk* const smpl = (SMPLChunk*) juce_calloc (jmax (length + 1, (int) sizeof (SMPLChunk))); + HeapBlock smpl; + smpl.calloc (jmax (length + 1, (int) sizeof (SMPLChunk)), 1); input->read (smpl, length); smpl->copyTo (metadataValues, length); - juce_free (smpl); } else if (chunkEnd <= input->getPosition()) { diff --git a/src/audio/audio_sources/juce_ChannelRemappingAudioSource.h b/src/audio/audio_sources/juce_ChannelRemappingAudioSource.h index 54e84ec4cc..b2f750b8ed 100644 --- a/src/audio/audio_sources/juce_ChannelRemappingAudioSource.h +++ b/src/audio/audio_sources/juce_ChannelRemappingAudioSource.h @@ -28,6 +28,7 @@ #include "juce_AudioSource.h" #include "../../text/juce_XmlElement.h" +#include "../../containers/juce_Array.h" //============================================================================== diff --git a/src/audio/dsp/juce_AudioSampleBuffer.cpp b/src/audio/dsp/juce_AudioSampleBuffer.cpp index ccb6be81c4..1cc542eb32 100644 --- a/src/audio/dsp/juce_AudioSampleBuffer.cpp +++ b/src/audio/dsp/juce_AudioSampleBuffer.cpp @@ -41,18 +41,35 @@ AudioSampleBuffer::AudioSampleBuffer (const int numChannels_, jassert (numSamples >= 0); jassert (numChannels_ > 0); - allocatedBytes = numChannels * numSamples * sizeof (float) + 32; - allocatedData = (float*) juce_malloc (allocatedBytes); - channels = (float**) juce_malloc ((numChannels_ + 1) * sizeof (float*)); + allocateData(); +} - float* chan = allocatedData; - for (int i = 0; i < numChannels_; ++i) +AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) throw() + : numChannels (other.numChannels), + size (other.size) +{ + allocateData(); + const int numBytes = size * sizeof (float); + + for (int i = 0; i < numChannels; ++i) + memcpy (channels[i], other.channels[i], numBytes); +} + +void AudioSampleBuffer::allocateData() +{ + const int channelListSize = (numChannels + 1) * sizeof (float*); + allocatedBytes = numChannels * size * sizeof (float) + channelListSize + 32; + allocatedData.malloc (allocatedBytes); + channels = (float**) allocatedData; + + float* chan = (float*) (allocatedData + channelListSize); + for (int i = 0; i < numChannels; ++i) { channels[i] = chan; - chan += numSamples; + chan += size; } - channels [numChannels_] = 0; + channels [numChannels] = 0; } AudioSampleBuffer::AudioSampleBuffer (float** dataToReferTo, @@ -60,45 +77,41 @@ AudioSampleBuffer::AudioSampleBuffer (float** dataToReferTo, const int numSamples) throw() : numChannels (numChannels_), size (numSamples), - allocatedBytes (0), - allocatedData (0) + allocatedBytes (0) { jassert (numChannels_ > 0); - - // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) - if (numChannels_ < numElementsInArray (preallocatedChannelSpace)) - channels = (float**) preallocatedChannelSpace; - else - channels = (float**) juce_malloc ((numChannels_ + 1) * sizeof (float*)); - - for (int i = 0; i < numChannels_; ++i) - { - // you have to pass in the same number of valid pointers as numChannels - jassert (dataToReferTo[i] != 0); - - channels[i] = dataToReferTo[i]; - } - - channels [numChannels_] = 0; + allocateChannels (dataToReferTo); } void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, - const int numChannels_, - const int numSamples) throw() + const int newNumChannels, + const int newNumSamples) throw() { - jassert (numChannels_ > 0); + jassert (newNumChannels > 0); - juce_free (allocatedData); - allocatedData = 0; allocatedBytes = 0; + allocatedData.free(); - if (numChannels_ > numChannels) - channels = (float**) juce_realloc (channels, (numChannels_ + 1) * sizeof (float*)); + numChannels = newNumChannels; + size = newNumSamples; - numChannels = numChannels_; - size = numSamples; + allocateChannels (dataToReferTo); +} - for (int i = 0; i < numChannels_; ++i) +void AudioSampleBuffer::allocateChannels (float** const dataToReferTo) +{ + // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) + if (numChannels < numElementsInArray (preallocatedChannelSpace)) + { + channels = (float**) preallocatedChannelSpace; + } + else + { + allocatedData.malloc (numChannels + 1, sizeof (float*)); + channels = (float**) allocatedData; + } + + for (int i = 0; i < numChannels; ++i) { // you have to pass in the same number of valid pointers as numChannels jassert (dataToReferTo[i] != 0); @@ -106,38 +119,7 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, channels[i] = dataToReferTo[i]; } - channels [numChannels_] = 0; -} - -AudioSampleBuffer::AudioSampleBuffer (const AudioSampleBuffer& other) throw() - : numChannels (other.numChannels), - size (other.size) -{ - channels = (float**) juce_malloc ((other.numChannels + 1) * sizeof (float*)); - - if (other.allocatedData != 0) - { - allocatedBytes = numChannels * size * sizeof (float) + 32; - allocatedData = (float*) juce_malloc (allocatedBytes); - - memcpy (allocatedData, other.allocatedData, allocatedBytes); - - float* chan = allocatedData; - for (int i = 0; i < numChannels; ++i) - { - channels[i] = chan; - chan += size; - } - - channels [numChannels] = 0; - } - else - { - allocatedData = 0; - allocatedBytes = 0; - - memcpy (channels, other.channels, sizeof (channels)); - } + channels [numChannels] = 0; } const AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& other) throw() @@ -157,10 +139,6 @@ const AudioSampleBuffer& AudioSampleBuffer::operator= (const AudioSampleBuffer& AudioSampleBuffer::~AudioSampleBuffer() throw() { - juce_free (allocatedData); - - if (channels != (float**) preallocatedChannelSpace) - juce_free (channels); } void AudioSampleBuffer::setSize (const int newNumChannels, @@ -173,26 +151,29 @@ void AudioSampleBuffer::setSize (const int newNumChannels, if (newNumSamples != size || newNumChannels != numChannels) { - const int newTotalBytes = newNumChannels * newNumSamples * sizeof (float) + 32; + const int channelListSize = (newNumChannels + 1) * sizeof (float*); + const int newTotalBytes = (newNumChannels * newNumSamples * sizeof (float)) + channelListSize + 32; if (keepExistingContent) { - float* const newData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes) - : (float*) juce_malloc (newTotalBytes); + HeapBlock newData; + newData.allocate (newTotalBytes, clearExtraSpace); - const int sizeToCopy = sizeof (float) * jmin (newNumSamples, size); + const int numChansToCopy = jmin (numChannels, newNumChannels); + const int numBytesToCopy = sizeof (float) * jmin (newNumSamples, size); - for (int i = jmin (newNumChannels, numChannels); --i >= 0;) + float** const newChannels = (float**) newData; + float* newChan = (float*) (newData + channelListSize); + for (int i = 0; i < numChansToCopy; ++i) { - memcpy (newData + i * newNumSamples, - channels[i], - sizeToCopy); + memcpy (newChan, channels[i], numBytesToCopy); + newChannels[i] = newChan; + newChan += newNumSamples; } - juce_free (allocatedData); - - allocatedData = newData; + allocatedData.swapWith (newData); allocatedBytes = newTotalBytes; + channels = (float**) allocatedData; } else { @@ -203,29 +184,22 @@ void AudioSampleBuffer::setSize (const int newNumChannels, } else { - juce_free (allocatedData); - - allocatedData = (clearExtraSpace) ? (float*) juce_calloc (newTotalBytes) - : (float*) juce_malloc (newTotalBytes); allocatedBytes = newTotalBytes; + allocatedData.allocate (newTotalBytes, clearExtraSpace); + channels = (float**) allocatedData; + } + + float* chan = (float*) (allocatedData + channelListSize); + for (int i = 0; i < newNumChannels; ++i) + { + channels[i] = chan; + chan += newNumSamples; } } - size = newNumSamples; - - if (newNumChannels > numChannels) - channels = (float**) juce_realloc (channels, (newNumChannels + 1) * sizeof (float*)); - - numChannels = newNumChannels; - - float* chan = allocatedData; - for (int i = 0; i < newNumChannels; ++i) - { - channels[i] = chan; - chan += size; - } - channels [newNumChannels] = 0; + size = newNumSamples; + numChannels = newNumChannels; } } @@ -679,7 +653,8 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer, } else { - chans[0] = (int*) juce_malloc (sizeof (int) * numSamples * 2); + HeapBlock tempBuffer (numSamples * 2); + chans[0] = tempBuffer; if (numChannels > 1) chans[1] = chans[0] + numSamples; @@ -711,8 +686,6 @@ void AudioSampleBuffer::writeToAudioWriter (AudioFormatWriter* writer, } writer->write ((const int**) chans, numSamples); - - juce_free (chans[0]); } } } diff --git a/src/audio/dsp/juce_AudioSampleBuffer.h b/src/audio/dsp/juce_AudioSampleBuffer.h index 2d3ab4627c..04cc44c425 100644 --- a/src/audio/dsp/juce_AudioSampleBuffer.h +++ b/src/audio/dsp/juce_AudioSampleBuffer.h @@ -26,6 +26,7 @@ #ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ #define __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ +#include "../../containers/juce_HeapBlock.h" class AudioFormatReader; class AudioFormatWriter; @@ -425,8 +426,11 @@ public: private: int numChannels, size, allocatedBytes; float** channels; - float* allocatedData; + HeapBlock allocatedData; float* preallocatedChannelSpace [32]; + + void allocateData(); + void allocateChannels (float** const dataToReferTo); }; diff --git a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm index 9392fb7205..fe0f73caba 100644 --- a/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm +++ b/src/audio/plugins/formats/juce_AudioUnitPluginFormat.mm @@ -276,7 +276,7 @@ private: CriticalSection lock; bool initialised, wantsMidiMessages, wasPlaying; - AudioBufferList* outputBufferList; + HeapBlock outputBufferList; AudioTimeStamp timeStamp; AudioSampleBuffer* currentBuffer; @@ -375,7 +375,6 @@ AudioUnitPluginInstance::AudioUnitPluginInstance (const String& fileOrIdentifier initialised (false), wantsMidiMessages (false), audioUnit (0), - outputBufferList (0), currentBuffer (0) { try @@ -419,8 +418,6 @@ AudioUnitPluginInstance::~AudioUnitPluginInstance() audioUnit = 0; } } - - juce_free (outputBufferList); } bool AudioUnitPluginInstance::getComponentDescFromFile (const String& fileOrIdentifier) @@ -602,8 +599,7 @@ void AudioUnitPluginInstance::prepareToPlay (double sampleRate_, kAudioUnitScope_Output, 0, &stream, sizeof (stream)); - juce_free (outputBufferList); - outputBufferList = (AudioBufferList*) juce_calloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * (numOuts + 1)); + outputBufferList.calloc (sizeof (AudioBufferList) + sizeof (AudioBuffer) * (numOuts + 1), 1); outputBufferList->mNumberBuffers = numOuts; for (int i = numOuts; --i >= 0;) @@ -627,8 +623,7 @@ void AudioUnitPluginInstance::releaseResources() AudioUnitReset (audioUnit, kAudioUnitScope_Output, 0); AudioUnitReset (audioUnit, kAudioUnitScope_Global, 0); - juce_free (outputBufferList); - outputBufferList = 0; + outputBufferList.free(); currentBuffer = 0; } } @@ -901,7 +896,8 @@ private: && AudioUnitGetPropertyInfo (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, 0, &dataSize, &isWritable) == noErr) { - AudioUnitCocoaViewInfo* info = (AudioUnitCocoaViewInfo*) juce_calloc (dataSize); + HeapBlock info; + info.calloc (dataSize, 1); if (AudioUnitGetProperty (plugin.audioUnit, kAudioUnitProperty_CocoaUI, kAudioUnitScope_Global, 0, info, &dataSize) == noErr) @@ -926,8 +922,6 @@ private: CFRelease (info->mCocoaAUViewBundleLocation); } } - - juce_free (info); } if (createGenericViewIfNeeded && (pluginView == 0)) diff --git a/src/audio/plugins/formats/juce_VSTMidiEventList.h b/src/audio/plugins/formats/juce_VSTMidiEventList.h index d0d8dbd655..f721787bc2 100644 --- a/src/audio/plugins/formats/juce_VSTMidiEventList.h +++ b/src/audio/plugins/formats/juce_VSTMidiEventList.h @@ -40,7 +40,7 @@ class VSTMidiEventList public: //============================================================================== VSTMidiEventList() - : events (0), numEventsUsed (0), numEventsAllocated (0) + : numEventsUsed (0), numEventsAllocated (0) { } @@ -138,9 +138,9 @@ public: const int size = 20 + sizeof (VstEvent*) * numEventsNeeded; if (events == 0) - events = (VstEvents*) juce_calloc (size); + events.calloc (size, 1); else - events = (VstEvents*) juce_realloc (events, size); + events.realloc (size, 1); for (int i = numEventsAllocated; i < numEventsNeeded; ++i) { @@ -170,15 +170,14 @@ public: juce_free (e); } - juce_free (events); - events = 0; + events.free(); numEventsUsed = 0; numEventsAllocated = 0; } } //============================================================================== - VstEvents* events; + HeapBlock events; private: int numEventsUsed, numEventsAllocated; diff --git a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp index fecf0a5dd6..b838698eb2 100644 --- a/src/audio/plugins/formats/juce_VSTPluginFormat.cpp +++ b/src/audio/plugins/formats/juce_VSTPluginFormat.cpp @@ -769,7 +769,7 @@ private: MidiBuffer incomingMidi; VSTMidiEventList midiEventsToSend; VstTimeInfo vstHostTime; - float** channels; + HeapBlock channels; ReferenceCountedObjectPtr module; @@ -808,7 +808,6 @@ VSTPluginInstance::VSTPluginInstance (const ReferenceCountedObjectPtr initialDelay); - juce_free (channels); - channels = (float**) juce_calloc (sizeof (float*) * jmax (16, getNumOutputChannels() + 2, getNumInputChannels() + 2)); + channels.calloc (jmax (16, getNumOutputChannels(), getNumInputChannels()) + 2); vstHostTime.tempo = 120.0; vstHostTime.timeSigNumerator = 4; @@ -1020,8 +1015,7 @@ void VSTPluginInstance::releaseResources() incomingMidi.clear(); midiEventsToSend.freeEvents(); - juce_free (channels); - channels = 0; + channels.free(); } void VSTPluginInstance::processBlock (AudioSampleBuffer& buffer, diff --git a/src/audio/processors/juce_AudioProcessorGraph.cpp b/src/audio/processors/juce_AudioProcessorGraph.cpp index dc8f2b25cd..571c152e7f 100644 --- a/src/audio/processors/juce_AudioProcessorGraph.cpp +++ b/src/audio/processors/juce_AudioProcessorGraph.cpp @@ -508,7 +508,7 @@ public: totalChans (jmax (1, totalChans_)), midiBufferToUse (midiBufferToUse_) { - channels = (float**) juce_calloc (sizeof (float*) * totalChans); + channels.calloc (totalChans); while (audioChannelsToUse.size() < totalChans) audioChannelsToUse.add (0); @@ -516,7 +516,6 @@ public: ~ProcessBufferOp() throw() { - juce_free (channels); } void perform (AudioSampleBuffer& sharedBufferChans, const OwnedArray & sharedMidiBuffers, const int numSamples) throw() @@ -534,7 +533,7 @@ public: private: Array audioChannelsToUse; - float** channels; + HeapBlock channels; int totalChans; int midiBufferToUse; diff --git a/src/containers/juce_BitArray.cpp b/src/containers/juce_BitArray.cpp index 77ed1a4f42..edc3620e97 100644 --- a/src/containers/juce_BitArray.cpp +++ b/src/containers/juce_BitArray.cpp @@ -39,7 +39,7 @@ BitArray::BitArray() throw() highestBit (-1), negative (false) { - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); } BitArray::BitArray (const int value) throw() @@ -47,7 +47,7 @@ BitArray::BitArray (const int value) throw() highestBit (31), negative (value < 0) { - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); values[0] = abs (value); highestBit = getHighestBit(); } @@ -57,7 +57,7 @@ BitArray::BitArray (int64 value) throw() highestBit (63), negative (value < 0) { - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); if (value < 0) value = -value; @@ -72,7 +72,7 @@ BitArray::BitArray (const unsigned int value) throw() highestBit (31), negative (false) { - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); values[0] = value; highestBit = getHighestBit(); } @@ -82,28 +82,23 @@ BitArray::BitArray (const BitArray& other) throw() highestBit (other.getHighestBit()), negative (other.negative) { - const int bytes = sizeof (unsigned int) * (numValues + 1); - values = (unsigned int*) juce_malloc (bytes); - memcpy (values, other.values, bytes); + values.malloc (numValues + 1); + memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1)); } BitArray::~BitArray() throw() { - juce_free (values); } const BitArray& BitArray::operator= (const BitArray& other) throw() { if (this != &other) { - juce_free (values); - highestBit = other.getHighestBit(); numValues = jmax (4, (highestBit >> 5) + 1); negative = other.negative; - const int memSize = sizeof (unsigned int) * (numValues + 1); - values = (unsigned int*)juce_malloc (memSize); - memcpy (values, other.values, memSize); + values.malloc (numValues + 1); + memcpy (values, other.values, sizeof (unsigned int) * (numValues + 1)); } return *this; @@ -167,9 +162,8 @@ void BitArray::clear() throw() { if (numValues > 16) { - juce_free (values); numValues = 4; - values = (unsigned int*) juce_calloc (sizeof (unsigned int) * (numValues + 1)); + values.calloc (numValues + 1); } else { @@ -821,7 +815,7 @@ void BitArray::ensureSize (const int numVals) throw() { int oldSize = numValues; numValues = ((numVals + 2) * 3) / 2; - values = (unsigned int*) juce_realloc (values, sizeof (unsigned int) * numValues + 4); + values.realloc (numValues + 1); while (oldSize < numValues) values [oldSize++] = 0; diff --git a/src/containers/juce_BitArray.h b/src/containers/juce_BitArray.h index 629f1ea074..6fd13990c9 100644 --- a/src/containers/juce_BitArray.h +++ b/src/containers/juce_BitArray.h @@ -28,6 +28,7 @@ #include "../text/juce_String.h" #include "juce_Array.h" +#include "juce_HeapBlock.h" class MemoryBlock; @@ -334,7 +335,7 @@ public: private: void ensureSize (const int numVals) throw(); - unsigned int* values; + HeapBlock values; int numValues, highestBit; bool negative; }; diff --git a/src/containers/juce_HeapBlock.h b/src/containers/juce_HeapBlock.h new file mode 100644 index 0000000000..cc42a34e86 --- /dev/null +++ b/src/containers/juce_HeapBlock.h @@ -0,0 +1,240 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-9 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ +#define __JUCE_HEAPBLOCK_JUCEHEADER__ + + +//============================================================================== +/** + Very simple container class to hold a pointer to some data on the heap. + + When you need to allocate some heap storage for something, always try to use + this class instead of allocating the memory directly using malloc/free. + + A HeapBlock object can be treated in pretty much exactly the same way + as an char*, but as long as you allocate it on the stack or as a class member, + it's almost impossible for it to leak memory. + + It also makes your code much more concise and readable than doing the same thing + using direct allocations, + + E.g. instead of this: + @code + int* temp = (int*) juce_malloc (1024 * sizeof (int)); + memcpy (temp, xyz, 1024 * sizeof (int)); + juce_free (temp); + temp = (int*) juce_calloc (2048 * sizeof (int)); + temp[0] = 1234; + memcpy (foobar, temp, 2048 * sizeof (int)); + juce_free (temp); + @endcode + + ..you could just write this: + @code + HeapBlock temp (1024); + memcpy (temp, xyz, 1024 * sizeof (int)); + temp.calloc (2048); + temp[0] = 1234; + memcpy (foobar, temp, 2048 * sizeof (int)); + @endcode + + The class is extremely lightweight, containing only a pointer to the + data, and exposes malloc/realloc/calloc/free methods that do the same jobs + as their less object-oriented counterparts. Despite adding safety, you probably + won't sacrifice any performance by using this in place of normal pointers. + + @see Array, OwnedArray, MemoryBlock +*/ +template +class HeapBlock +{ +public: + //============================================================================== + /** Creates a HeapBlock which is initially just a null pointer. + + After creation, you can resize the array using the malloc(), calloc(), + or realloc() methods. + */ + HeapBlock() : data (0) + { + } + + /** Creates a HeapBlock containing a number of elements. + + The contents of the block are undefined, as it will have been created by a + malloc call. + + If you want an array of zero values, you can use the calloc() method instead. + */ + HeapBlock (const int numElements) + : data ((ElementType*) ::juce_malloc (numElements * sizeof (ElementType))) + { + } + + /** Destructor. + + This will free the data, if any has been allocated. + */ + ~HeapBlock() + { + ::juce_free (data); + } + + //============================================================================== + /** Returns a raw pointer to the allocated data. + This may be a null pointer if the data hasn't yet been allocated, or if it has been + freed by calling the free() method. + */ + inline operator ElementType*() const { return data; } + + /** Returns a void pointer to the allocated data. + This may be a null pointer if the data hasn't yet been allocated, or if it has been + freed by calling the free() method. + */ + inline operator void*() const { return (void*) data; } + + /** Lets you use indirect calls to the first element in the array. + Obviously this will cause problems if the array hasn't been initialised, because it'll + be referencing a null pointer. + */ + inline ElementType* operator->() const { return data; } + + /** Returns a pointer to the data by casting it to any type you need. + */ + template + inline operator CastType*() const { return (CastType*) data; } + + /** Returns a reference to one of the data elements. + Obviously there's no bounds-checking here, as this object is just a dumb pointer and + has no idea of the size it currently has allocated. + */ + inline ElementType& operator[] (const pointer_sized_int index) const { return data [index]; } + + /** Returns a pointer to a data element at an offset from the start of the array. + This is the same as doing pointer arithmetic on the raw pointer itself. + */ + inline ElementType* operator+ (const pointer_sized_int index) const { return data + index; } + + /** Returns a reference to the raw data pointer. + Beware that the pointer returned here will become invalid as soon as you call + any of the allocator methods on this object! + */ + inline ElementType** operator&() const { return (ElementType**) &data; } + + //============================================================================== + /** Compares the pointer with another pointer. + This can be handy for checking whether this is a null pointer. + */ + inline bool operator== (const ElementType* const otherPointer) const { return otherPointer == data; } + + /** Compares the pointer with another pointer. + This can be handy for checking whether this is a null pointer. + */ + inline bool operator!= (const ElementType* const otherPointer) const { return otherPointer != data; } + + //============================================================================== + /** Allocates a specified amount of memory. + + This uses the normal malloc to allocate an amount of memory for this object. + Any previously allocated memory will be freed by this method. + + The number of bytes allocated will be (newNumElements * elementSize). Normally + you wouldn't need to specify the second parameter, but it can be handy if you need + to allocate a size in bytes rather than in terms of the number of elements. + + The data that is allocated will be freed when this object is deleted, or when you + call free() or any of the allocation methods. + */ + void malloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + ::juce_free (data); + data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + } + + /** Allocates a specified amount of memory and clears it. + This does the same job as the malloc() method, but clears the memory that it allocates. + */ + void calloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + ::juce_free (data); + data = (ElementType*) ::juce_calloc (newNumElements * elementSize); + } + + /** Allocates a specified amount of memory and optionally clears it. + This does the same job as either malloc() or calloc(), depending on the + initialiseToZero parameter. + */ + void allocate (const int newNumElements, const bool initialiseToZero) + { + ::juce_free (data); + + if (initialiseToZero) + data = (ElementType*) ::juce_calloc (newNumElements * sizeof (ElementType)); + else + data = (ElementType*) ::juce_malloc (newNumElements * sizeof (ElementType)); + } + + /** Re-allocates a specified amount of memory. + + The semantics of this method are the same as malloc() and calloc(), but it + uses realloc() to keep as much of the existing data as possible. + */ + void realloc (const int newNumElements, const unsigned int elementSize = sizeof (ElementType)) + { + if (data == 0) + data = (ElementType*) ::juce_malloc (newNumElements * elementSize); + else + data = (ElementType*) ::juce_realloc (data, newNumElements * elementSize); + } + + /** Frees any currently-allocated data. + This will free the data and reset this object to be a null pointer. + */ + void free() + { + ::juce_free (data); + data = 0; + } + + /** Swaps this object's data with the data of another HeapBlock. + The two objects simply exchange their data pointers. + */ + void swapWith (HeapBlock & other) + { + swapVariables (data, other.data); + } + + +private: + //============================================================================== + ElementType* data; + + HeapBlock (const HeapBlock&); + const HeapBlock& operator= (const HeapBlock&); +}; + + +#endif // __JUCE_HEAPBLOCK_JUCEHEADER__ diff --git a/src/containers/juce_MemoryBlock.cpp b/src/containers/juce_MemoryBlock.cpp index 3b92bce1cf..5541adf0f6 100644 --- a/src/containers/juce_MemoryBlock.cpp +++ b/src/containers/juce_MemoryBlock.cpp @@ -32,8 +32,7 @@ BEGIN_JUCE_NAMESPACE //============================================================================== MemoryBlock::MemoryBlock() throw() - : data (0), - size (0) + : size (0) { } @@ -43,35 +42,28 @@ MemoryBlock::MemoryBlock (const int initialSize, if (initialSize > 0) { size = initialSize; - - if (initialiseToZero) - data = (char*) juce_calloc (initialSize); - else - data = (char*) juce_malloc (initialSize); + data.allocate (initialSize, initialiseToZero); } else { - data = 0; size = 0; } } MemoryBlock::MemoryBlock (const MemoryBlock& other) throw() - : data (0), - size (other.size) + : size (other.size) { if (size > 0) { jassert (other.data != 0); - data = (char*) juce_malloc (size); + data.malloc (size); memcpy (data, other.data, size); } } MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, const int sizeInBytes) throw() - : data (0), - size (jmax (0, sizeInBytes)) + : size (jmax (0, sizeInBytes)) { jassert (sizeInBytes >= 0); @@ -79,7 +71,7 @@ MemoryBlock::MemoryBlock (const void* const dataToInitialiseFrom, { jassert (dataToInitialiseFrom != 0); // non-zero size, but a zero pointer passed-in? - data = (char*) juce_malloc (size); + data.malloc (size); if (dataToInitialiseFrom != 0) memcpy (data, dataToInitialiseFrom, size); @@ -90,8 +82,6 @@ MemoryBlock::~MemoryBlock() throw() { jassert (size >= 0); // should never happen jassert (size == 0 || data != 0); // non-zero size but no data allocated? - - juce_free (data); } const MemoryBlock& MemoryBlock::operator= (const MemoryBlock& other) throw() @@ -126,25 +116,21 @@ void MemoryBlock::setSize (const int newSize, { if (newSize <= 0) { - juce_free (data); - data = 0; + data.free(); size = 0; } else { if (data != 0) { - data = (char*) juce_realloc (data, newSize); + data.realloc (newSize); if (initialiseToZero && (newSize > size)) zeromem (data + size, newSize - size); } else { - if (initialiseToZero) - data = (char*) juce_calloc (newSize); - else - data = (char*) juce_malloc (newSize); + data.allocate (newSize, initialiseToZero); } size = newSize; @@ -242,7 +228,7 @@ void MemoryBlock::removeSection (int startByte, int numBytesToRemove) throw() const String MemoryBlock::toString() const throw() { - return String (data, size); + return String ((const char*) data, size); } //============================================================================== diff --git a/src/containers/juce_MemoryBlock.h b/src/containers/juce_MemoryBlock.h index 068766cdd9..e3f63f05e4 100644 --- a/src/containers/juce_MemoryBlock.h +++ b/src/containers/juce_MemoryBlock.h @@ -27,6 +27,7 @@ #define __JUCE_MEMORYBLOCK_JUCEHEADER__ #include "../text/juce_String.h" +#include "juce_HeapBlock.h" //============================================================================== @@ -232,7 +233,7 @@ public: private: //============================================================================== - char* data; + HeapBlock data; int size; }; diff --git a/src/containers/juce_Variant.cpp b/src/containers/juce_Variant.cpp index b0cd527ffe..ac2ca73231 100644 --- a/src/containers/juce_Variant.cpp +++ b/src/containers/juce_Variant.cpp @@ -318,10 +318,9 @@ void var::writeToStream (OutputStream& output) const throw() const int len = value.stringValue->copyToUTF8 (0); output.writeCompressedInt (len + 1); output.writeByte (5); - uint8* const temp = (uint8*) juce_malloc (len); + HeapBlock temp (len); value.stringValue->copyToUTF8 (temp); output.write (temp, len); - juce_free (temp); break; } case objectType: output.writeCompressedInt (0); jassertfalse; break; // Can't write an object to a stream! diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h index ea6b5ae31d..61baf0baf7 100644 --- a/src/containers/juce_Variant.h +++ b/src/containers/juce_Variant.h @@ -29,6 +29,7 @@ #include "juce_ReferenceCountedObject.h" #include "juce_OwnedArray.h" #include "../text/juce_StringArray.h" +#include "../containers/juce_Array.h" #include "../io/streams/juce_OutputStream.h" #include "../io/streams/juce_InputStream.h" diff --git a/src/core/juce_Memory.h b/src/core/juce_Memory.h index 88e875216f..80beee2bd7 100644 --- a/src/core/juce_Memory.h +++ b/src/core/juce_Memory.h @@ -37,13 +37,24 @@ //============================================================================== // Win32 debug non-DLL versions.. - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) _malloc_dbg (numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) _calloc_dbg (1, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) _realloc_dbg (location, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) _free_dbg (location, _NORMAL_BLOCK) #else @@ -57,13 +68,24 @@ extern JUCE_API void* juce_DebugRealloc (void* const block, const int size, const char* file, const int line); extern JUCE_API void juce_DebugFree (void* const block); - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) JUCE_NAMESPACE::juce_DebugMalloc (numBytes, __FILE__, __LINE__) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) JUCE_NAMESPACE::juce_DebugCalloc (numBytes, __FILE__, __LINE__) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_DebugRealloc (location, numBytes, __FILE__, __LINE__) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) JUCE_NAMESPACE::juce_DebugFree (location) #endif @@ -89,13 +111,24 @@ extern JUCE_API void* juce_Realloc (void* const block, const int size); extern JUCE_API void juce_Free (void* const block); - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) JUCE_NAMESPACE::juce_Malloc (numBytes) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) JUCE_NAMESPACE::juce_Calloc (numBytes) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) JUCE_NAMESPACE::juce_Realloc (location, numBytes) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) JUCE_NAMESPACE::juce_Free (location) #define juce_UseDebuggingNewOperator \ @@ -108,13 +141,24 @@ //============================================================================== // Mac, Linux and Win32 (release) versions.. - /** This should be used instead of calling malloc directly. */ + /** This should be used instead of calling malloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_malloc(numBytes) malloc (numBytes) - /** This should be used instead of calling calloc directly. */ + + /** This should be used instead of calling calloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_calloc(numBytes) calloc (1, numBytes) - /** This should be used instead of calling realloc directly. */ + + /** This should be used instead of calling realloc directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_realloc(location, numBytes) realloc (location, numBytes) - /** This should be used instead of calling free directly. */ + + /** This should be used instead of calling free directly. + Only use direct memory allocation if there's really no way to use a HeapBlock object instead! + */ #define juce_free(location) free (location) #endif diff --git a/src/cryptography/juce_BlowFish.cpp b/src/cryptography/juce_BlowFish.cpp index f5ba6ef7b5..c787eeab41 100644 --- a/src/cryptography/juce_BlowFish.cpp +++ b/src/cryptography/juce_BlowFish.cpp @@ -309,7 +309,7 @@ BlowFish::BlowFish (const uint8* keyData, int keyBytes) int i, j; for (i = 4; --i >= 0;) { - s[i] = (uint32*) juce_malloc (256 * sizeof (uint32)); + s[i].malloc (256); memcpy (s[i], initialSValues + i * 256, 256 * sizeof (uint32)); } @@ -355,7 +355,7 @@ BlowFish::BlowFish (const uint8* keyData, int keyBytes) BlowFish::BlowFish (const BlowFish& other) { for (int i = 4; --i >= 0;) - s[i] = (uint32*) juce_malloc (256 * sizeof (uint32)); + s[i].malloc (256); operator= (other); } @@ -372,8 +372,6 @@ const BlowFish& BlowFish::operator= (const BlowFish& other) BlowFish::~BlowFish() { - for (int i = 4; --i >= 0;) - juce_free (s[i]); } uint32 BlowFish::F (uint32 x) const diff --git a/src/cryptography/juce_BlowFish.h b/src/cryptography/juce_BlowFish.h index a2fbf4cb63..eaa8d03641 100644 --- a/src/cryptography/juce_BlowFish.h +++ b/src/cryptography/juce_BlowFish.h @@ -26,6 +26,8 @@ #ifndef __JUCE_BLOWFISH_JUCEHEADER__ #define __JUCE_BLOWFISH_JUCEHEADER__ +#include "../containers/juce_HeapBlock.h" + //============================================================================== /** @@ -64,7 +66,7 @@ public: private: uint32 p[18]; - uint32* s[4]; + HeapBlock s[4]; uint32 F (uint32 x) const; }; diff --git a/src/gui/components/code_editor/juce_CodeDocument.h b/src/gui/components/code_editor/juce_CodeDocument.h index f849d63431..1ed189354d 100644 --- a/src/gui/components/code_editor/juce_CodeDocument.h +++ b/src/gui/components/code_editor/juce_CodeDocument.h @@ -28,6 +28,7 @@ #include "../../../utilities/juce_UndoManager.h" #include "../../graphics/colour/juce_Colour.h" +#include "../../../containers/juce_VoidArray.h" class CodeDocumentLine; diff --git a/src/gui/components/special/juce_MidiKeyboardComponent.cpp b/src/gui/components/special/juce_MidiKeyboardComponent.cpp index 95657c1799..0c2bba990f 100644 --- a/src/gui/components/special/juce_MidiKeyboardComponent.cpp +++ b/src/gui/components/special/juce_MidiKeyboardComponent.cpp @@ -702,7 +702,7 @@ void MidiKeyboardComponent::resetAnyKeysInUse() void MidiKeyboardComponent::updateNoteUnderMouse (int x, int y) { - float mousePositionVelocity; + float mousePositionVelocity = 0.0f; const int newNote = (mouseDragging || isMouseOver()) ? xyToNote (x, y, mousePositionVelocity) : -1; diff --git a/src/gui/graphics/colour/juce_ColourGradient.cpp b/src/gui/graphics/colour/juce_ColourGradient.cpp index 127756c4ac..eebf6881df 100644 --- a/src/gui/graphics/colour/juce_ColourGradient.cpp +++ b/src/gui/graphics/colour/juce_ColourGradient.cpp @@ -138,7 +138,7 @@ const Colour ColourGradient::getColourAtPosition (const float position) const th } //============================================================================== -PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, int& numEntries) const throw() +int ColourGradient::createLookupTable (const AffineTransform& transform, HeapBlock & lookupTable) const throw() { #ifdef JUCE_DEBUG // trying to use the object without setting its co-ordinates? Have a careful read of @@ -153,9 +153,8 @@ PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, transform.transformPoint (tx2, ty2); const double distance = juce_hypot (tx1 - tx2, ty1 - ty2); - numEntries = jlimit (1, (numColours - 1) << 8, 3 * (int) distance); - - PixelARGB* const lookupTable = (PixelARGB*) juce_calloc (numEntries * sizeof (PixelARGB)); + const int numEntries = jlimit (1, (numColours - 1) << 8, 3 * (int) distance); + lookupTable.malloc (numEntries); if (numColours >= 2) { @@ -191,7 +190,7 @@ PixelARGB* ColourGradient::createLookupTable (const AffineTransform& transform, jassertfalse // no colours specified! } - return lookupTable; + return numEntries; } bool ColourGradient::isOpaque() const throw() diff --git a/src/gui/graphics/colour/juce_ColourGradient.h b/src/gui/graphics/colour/juce_ColourGradient.h index 711d53a59c..95cf6b406b 100644 --- a/src/gui/graphics/colour/juce_ColourGradient.h +++ b/src/gui/graphics/colour/juce_ColourGradient.h @@ -29,6 +29,7 @@ #include "juce_Colour.h" #include "../geometry/juce_AffineTransform.h" #include "../../../containers/juce_Array.h" +#include "../../../containers/juce_HeapBlock.h" //============================================================================== @@ -123,10 +124,10 @@ public: //============================================================================== /** Creates a set of interpolated premultiplied ARGB values. - - The caller must delete the array that is returned using juce_free(). + This will resize the HeapBlock, fill it with the colours, and will return the number of + colours that it added. */ - PixelARGB* createLookupTable (const AffineTransform& transform, int& numEntries) const throw(); + int createLookupTable (const AffineTransform& transform, HeapBlock & resultLookupTable) const throw(); /** Returns true if all colours are opaque. */ bool isOpaque() const throw(); diff --git a/src/gui/graphics/contexts/juce_EdgeTable.cpp b/src/gui/graphics/contexts/juce_EdgeTable.cpp index 66ba68bce8..4bc4ac9efa 100644 --- a/src/gui/graphics/contexts/juce_EdgeTable.cpp +++ b/src/gui/graphics/contexts/juce_EdgeTable.cpp @@ -53,7 +53,7 @@ EdgeTable::EdgeTable (const Rectangle& bounds_, lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), needToCheckEmptinesss (true) { - table = (int*) juce_malloc ((bounds.getHeight() + 1) * lineStrideElements * sizeof (int)); + table.malloc ((bounds.getHeight() + 1) * lineStrideElements); int* t = table; for (int i = bounds.getHeight(); --i >= 0;) @@ -127,8 +127,8 @@ EdgeTable::EdgeTable (const Rectangle& rectangleToAdd) throw() lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), needToCheckEmptinesss (true) { - table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int)); - *table = 0; + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); + table[0] = 0; const int x1 = rectangleToAdd.getX() << 8; const int x2 = rectangleToAdd.getRight() << 8; @@ -151,7 +151,7 @@ EdgeTable::EdgeTable (const RectangleList& rectanglesToAdd) throw() lineStrideElements ((juce_edgeTableDefaultEdgesPerLine << 1) + 1), needToCheckEmptinesss (true) { - table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int)); + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); int* t = table; for (int i = bounds.getHeight(); --i >= 0;) @@ -186,8 +186,8 @@ EdgeTable::EdgeTable (const float x, const float y, const float w, const float h needToCheckEmptinesss (true) { jassert (w > 0 && h > 0); - table = (int*) juce_malloc (jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int)); - *table = 0; + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); + table[0] = 0; const int x1 = roundFloatToInt (x * 256.0f); const int x2 = roundFloatToInt ((x + w) * 256.0f); @@ -262,22 +262,18 @@ EdgeTable::EdgeTable (const EdgeTable& other) throw() const EdgeTable& EdgeTable::operator= (const EdgeTable& other) throw() { - juce_free (table); - bounds = other.bounds; maxEdgesPerLine = other.maxEdgesPerLine; lineStrideElements = other.lineStrideElements; needToCheckEmptinesss = other.needToCheckEmptinesss; - const int tableSize = jmax (1, bounds.getHeight()) * lineStrideElements * sizeof (int); - table = (int*) juce_malloc (tableSize); + table.malloc (jmax (1, bounds.getHeight()) * lineStrideElements); copyEdgeTableData (table, lineStrideElements, other.table, lineStrideElements, bounds.getHeight()); return *this; } EdgeTable::~EdgeTable() throw() { - juce_free (table); } //============================================================================== @@ -340,12 +336,12 @@ void EdgeTable::remapTableForNumEdges (const int newNumEdgesPerLine) throw() jassert (bounds.getHeight() > 0); const int newLineStrideElements = maxEdgesPerLine * 2 + 1; - int* const newTable = (int*) juce_malloc (bounds.getHeight() * newLineStrideElements * sizeof (int)); + + HeapBlock newTable (bounds.getHeight() * newLineStrideElements); copyEdgeTableData (newTable, newLineStrideElements, table, lineStrideElements, bounds.getHeight()); - juce_free (table); - table = newTable; + table.swapWith (newTable); lineStrideElements = newLineStrideElements; } } diff --git a/src/gui/graphics/contexts/juce_EdgeTable.h b/src/gui/graphics/contexts/juce_EdgeTable.h index 6a5e5a42a0..9787009799 100644 --- a/src/gui/graphics/contexts/juce_EdgeTable.h +++ b/src/gui/graphics/contexts/juce_EdgeTable.h @@ -195,7 +195,7 @@ public: private: // table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc - int* table; + HeapBlock table; Rectangle bounds; int maxEdgesPerLine, lineStrideElements; bool needToCheckEmptinesss; diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index a6a3368791..a3862a262d 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -41,13 +41,13 @@ BEGIN_JUCE_NAMESPACE #define JUCE_USE_SSE_INSTRUCTIONS 1 #endif +#if JUCE_MSVC && JUCE_DEBUG + #pragma warning (disable: 4714) // warning about forcedinline methods not being inlined +#endif + #if JUCE_MSVC #pragma warning (push) #pragma warning (disable: 4127) // "expression is constant" warning - - #if JUCE_DEBUG - #pragma warning (disable: 4714) // warning about forcedinline methods not being inlined - #endif #endif //============================================================================== @@ -520,12 +520,11 @@ public: maxY (srcData_.height - 1), scratchSize (2048) { - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } ~TransformedImageFillEdgeTableRenderer() throw() { - juce_free (scratchBuffer); } forcedinline void setEdgeTableYPos (const int newY) throw() @@ -550,8 +549,7 @@ public: if (width > scratchSize) { scratchSize = width; - juce_free (scratchBuffer); - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } SrcPixelType* span = scratchBuffer; @@ -582,8 +580,7 @@ public: if (width > scratchSize) { scratchSize = width; - juce_free (scratchBuffer); - scratchBuffer = (SrcPixelType*) juce_malloc (scratchSize * sizeof (SrcPixelType)); + scratchBuffer.malloc (scratchSize); } uint8* mask = (uint8*) scratchBuffer; @@ -893,7 +890,7 @@ private: const int pixelOffsetInt, maxX, maxY; int y; DestPixelType* linePixels; - SrcPixelType* scratchBuffer; + HeapBlock scratchBuffer; int scratchSize; TransformedImageFillEdgeTableRenderer (const TransformedImageFillEdgeTableRenderer&); @@ -983,8 +980,8 @@ public: transform = AffineTransform::identity; } - int numLookupEntries; - PixelARGB* const lookupTable = g2.createLookupTable (transform, numLookupEntries); + HeapBlock lookupTable; + const int numLookupEntries = g2.createLookupTable (transform, lookupTable); jassert (numLookupEntries > 0); switch (image.getFormat()) @@ -993,8 +990,6 @@ public: case Image::RGB: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity, (PixelRGB*) 0); break; default: renderGradient (et, destData, g2, transform, lookupTable, numLookupEntries, isIdentity, (PixelAlpha*) 0); break; } - - juce_free (lookupTable); } else if (fillType.isTiledImage()) { diff --git a/src/gui/graphics/fonts/juce_TextLayout.h b/src/gui/graphics/fonts/juce_TextLayout.h index bb83347c7e..b5f8ff4d27 100644 --- a/src/gui/graphics/fonts/juce_TextLayout.h +++ b/src/gui/graphics/fonts/juce_TextLayout.h @@ -28,6 +28,7 @@ #include "juce_Font.h" #include "../contexts/juce_Justification.h" +#include "../../../containers/juce_VoidArray.h" class Graphics; diff --git a/src/gui/graphics/geometry/juce_PathIterator.cpp b/src/gui/graphics/geometry/juce_PathIterator.cpp index f3e34be5e3..f943408ada 100644 --- a/src/gui/graphics/geometry/juce_PathIterator.cpp +++ b/src/gui/graphics/geometry/juce_PathIterator.cpp @@ -48,17 +48,16 @@ PathFlatteningIterator::PathFlatteningIterator (const Path& path_, tolerence (tolerence_ * tolerence_), subPathCloseX (0), subPathCloseY (0), + stackBase (32), index (0), stackSize (32) { - stackBase = (float*) juce_malloc (stackSize * sizeof (float)); isIdentityTransform = transform.isIdentity(); stackPos = stackBase; } PathFlatteningIterator::~PathFlatteningIterator() throw() { - juce_free (stackBase); } bool PathFlatteningIterator::next() throw() @@ -159,7 +158,7 @@ bool PathFlatteningIterator::next() throw() if (offset >= stackSize - 10) { stackSize <<= 1; - stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float)); + stackBase.realloc (stackSize); stackPos = stackBase + offset; } @@ -209,7 +208,7 @@ bool PathFlatteningIterator::next() throw() if (offset >= stackSize - 16) { stackSize <<= 1; - stackBase = (float*) juce_realloc (stackBase, stackSize * sizeof (float)); + stackBase.realloc (stackSize); stackPos = stackBase + offset; } diff --git a/src/gui/graphics/geometry/juce_PathIterator.h b/src/gui/graphics/geometry/juce_PathIterator.h index 045f34068d..7ea8b17811 100644 --- a/src/gui/graphics/geometry/juce_PathIterator.h +++ b/src/gui/graphics/geometry/juce_PathIterator.h @@ -110,7 +110,7 @@ private: float tolerence, subPathCloseX, subPathCloseY; bool isIdentityTransform; - float* stackBase; + HeapBlock stackBase; float* stackPos; int index, stackSize; diff --git a/src/gui/graphics/geometry/juce_PathStrokeType.cpp b/src/gui/graphics/geometry/juce_PathStrokeType.cpp index deece0c8be..1add4db0eb 100644 --- a/src/gui/graphics/geometry/juce_PathStrokeType.cpp +++ b/src/gui/graphics/geometry/juce_PathStrokeType.cpp @@ -30,7 +30,6 @@ BEGIN_JUCE_NAMESPACE #include "juce_PathStrokeType.h" #include "juce_PathIterator.h" -#include "../../../containers/juce_VoidArray.h" //============================================================================== diff --git a/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp b/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp index bcaa9434c7..9834323135 100644 --- a/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp +++ b/src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp @@ -326,7 +326,8 @@ bool juce_writeJPEGImageToStream (const Image& image, jpegCompStruct.dest = &dest; dest.output = &out; - dest.buffer = (char*) juce_malloc (bufferSize); + HeapBlock tempBuffer (bufferSize); + dest.buffer = (char*) tempBuffer; dest.next_output_byte = (JOCTET*) dest.buffer; dest.free_in_buffer = bufferSize; dest.init_destination = jpegWriteInit; @@ -382,8 +383,6 @@ bool juce_writeJPEGImageToStream (const Image& image, jpeg_finish_compress (&jpegCompStruct); jpeg_destroy_compress (&jpegCompStruct); - juce_free (dest.buffer); - out.flush(); return true; diff --git a/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp b/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp index 9b85437d1e..196ebda450 100644 --- a/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp +++ b/src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp @@ -178,17 +178,17 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() || pngInfoStruct->num_trans > 0; // Load the image into a temp buffer in the pnglib format.. - uint8* const tempBuffer = (uint8*) juce_malloc (height * (width << 2)); + HeapBlock tempBuffer (height * (width << 2)); - png_bytepp rows = (png_bytepp) juce_malloc (sizeof (png_bytep) * height); - int y; - for (y = (int) height; --y >= 0;) - rows[y] = (png_bytep) (tempBuffer + (width << 2) * y); + { + HeapBlock rows (height); + for (int y = (int) height; --y >= 0;) + rows[y] = (png_bytep) (tempBuffer + (width << 2) * y); - png_read_image (pngReadStruct, rows); - png_read_end (pngReadStruct, pngInfoStruct); + png_read_image (pngReadStruct, rows); + png_read_end (pngReadStruct, pngInfoStruct); + } - juce_free (rows); png_destroy_read_struct (&pngReadStruct, &pngInfoStruct, 0); // now convert the data to a juce image format.. @@ -201,7 +201,7 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() uint8* srcRow = tempBuffer; uint8* destRow = destData.data; - for (y = 0; y < (int) height; ++y) + for (int y = 0; y < (int) height; ++y) { const uint8* src = srcRow; srcRow += (width << 2); @@ -228,8 +228,6 @@ Image* juce_loadPNGImageFromStream (InputStream& in) throw() } } } - - juce_free (tempBuffer); } return image; @@ -273,7 +271,7 @@ bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw() PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - png_bytep rowData = (png_bytep) juce_malloc (width * 4 * sizeof (png_byte)); + HeapBlock rowData (width * 4); png_color_8 sig_bit; sig_bit.red = 8; @@ -322,8 +320,6 @@ bool juce_writePNGImageToStream (const Image& image, OutputStream& out) throw() png_write_rows (pngWriteStruct, &rowData, 1); } - juce_free (rowData); - png_write_end (pngWriteStruct, pngInfoStruct); png_destroy_write_struct (&pngWriteStruct, &pngInfoStruct); diff --git a/src/gui/graphics/imaging/juce_Image.cpp b/src/gui/graphics/imaging/juce_Image.cpp index d9ccd024ea..1b50f5a594 100644 --- a/src/gui/graphics/imaging/juce_Image.cpp +++ b/src/gui/graphics/imaging/juce_Image.cpp @@ -65,10 +65,9 @@ Image::Image (const PixelFormat format_, pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1); lineStride = (pixelStride * jmax (1, imageWidth_) + 3) & ~3; - const int dataSize = lineStride * jmax (1, imageHeight_); - imageData = (uint8*) (clearImage ? juce_calloc (dataSize) - : juce_malloc (dataSize)); + imageDataAllocated.allocate (lineStride * jmax (1, imageHeight_), clearImage); + imageData = imageDataAllocated; } Image::Image (const Image& other) @@ -78,9 +77,9 @@ Image::Image (const Image& other) { pixelStride = (format == RGB) ? 3 : ((format == ARGB) ? 4 : 1); lineStride = (pixelStride * jmax (1, imageWidth) + 3) & ~3; - const int dataSize = lineStride * jmax (1, imageHeight); - imageData = (uint8*) juce_malloc (dataSize); + imageDataAllocated.malloc (lineStride * jmax (1, imageHeight)); + imageData = imageDataAllocated; BitmapData srcData (other, 0, 0, imageWidth, imageHeight); setPixelData (0, 0, imageWidth, imageHeight, srcData.data, srcData.lineStride); @@ -88,7 +87,6 @@ Image::Image (const Image& other) Image::~Image() { - juce_free (imageData); } //============================================================================== diff --git a/src/gui/graphics/imaging/juce_Image.h b/src/gui/graphics/imaging/juce_Image.h index 48ff1c94ed..8239686469 100644 --- a/src/gui/graphics/imaging/juce_Image.h +++ b/src/gui/graphics/imaging/juce_Image.h @@ -291,9 +291,9 @@ protected: const int imageHeight); int pixelStride, lineStride; + HeapBlock imageDataAllocated; uint8* imageData; - private: //============================================================================== const Image& operator= (const Image&); diff --git a/src/gui/graphics/imaging/juce_ImageCache.h b/src/gui/graphics/imaging/juce_ImageCache.h index a3c1e7a5b9..8937e84ff9 100644 --- a/src/gui/graphics/imaging/juce_ImageCache.h +++ b/src/gui/graphics/imaging/juce_ImageCache.h @@ -30,6 +30,7 @@ #include "../../../io/files/juce_File.h" #include "../../../events/juce_Timer.h" #include "../../../utilities/juce_DeletedAtShutdown.h" +#include "../../../containers/juce_VoidArray.h" //============================================================================== diff --git a/src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp b/src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp index 1550174b4f..1e9690d0b4 100644 --- a/src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp +++ b/src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp @@ -32,22 +32,14 @@ BEGIN_JUCE_NAMESPACE //============================================================================== ImageConvolutionKernel::ImageConvolutionKernel (const int size_) throw() - : size (size_) + : values (size_ * size_), + size (size_) { - values = new float* [size]; - - for (int i = size; --i >= 0;) - values[i] = new float [size]; - clear(); } ImageConvolutionKernel::~ImageConvolutionKernel() throw() { - for (int i = size; --i >= 0;) - delete[] values[i]; - - delete[] values; } //============================================================================== @@ -58,7 +50,7 @@ void ImageConvolutionKernel::setKernelValue (const int x, if (((unsigned int) x) < (unsigned int) size && ((unsigned int) y) < (unsigned int) size) { - values[x][y] = value; + values [x + y * size] = value; } else { @@ -68,27 +60,24 @@ void ImageConvolutionKernel::setKernelValue (const int x, void ImageConvolutionKernel::clear() throw() { - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - values[x][y] = 0; + for (int i = size * size; --i >= 0;) + values[i] = 0; } void ImageConvolutionKernel::setOverallSum (const float desiredTotalSum) throw() { double currentTotal = 0.0; - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - currentTotal += values[x][y]; + for (int i = size * size; --i >= 0;) + currentTotal += values[i]; rescaleAllValues ((float) (desiredTotalSum / currentTotal)); } void ImageConvolutionKernel::rescaleAllValues (const float multiplier) throw() { - for (int y = size; --y >= 0;) - for (int x = size; --x >= 0;) - values[x][y] *= multiplier; + for (int i = size * size; --i >= 0;) + values[i] *= multiplier; } //============================================================================== @@ -104,7 +93,7 @@ void ImageConvolutionKernel::createGaussianBlur (const float radius) throw() const int cx = x - centre; const int cy = y - centre; - values[x][y] = (float) exp (radiusFactor * (cx * cx + cy * cy)); + values [x + y * size] = (float) exp (radiusFactor * (cx * cx + cy * cy)); } } @@ -190,7 +179,7 @@ void ImageConvolutionKernel::applyToImage (Image& destImage, if (sx >= 0) { - const float kernelMult = values[xx][yy]; + const float kernelMult = values [xx + yy * size]; c1 += kernelMult * *src++; c2 += kernelMult * *src++; c3 += kernelMult * *src++; @@ -245,7 +234,7 @@ void ImageConvolutionKernel::applyToImage (Image& destImage, if (sx >= 0) { - const float kernelMult = values[xx][yy]; + const float kernelMult = values [xx + yy * size]; c1 += kernelMult * *src++; c2 += kernelMult * *src++; c3 += kernelMult * *src++; diff --git a/src/gui/graphics/imaging/juce_ImageConvolutionKernel.h b/src/gui/graphics/imaging/juce_ImageConvolutionKernel.h index b5eb37b21c..65f6e24797 100644 --- a/src/gui/graphics/imaging/juce_ImageConvolutionKernel.h +++ b/src/gui/graphics/imaging/juce_ImageConvolutionKernel.h @@ -119,8 +119,8 @@ public: juce_UseDebuggingNewOperator private: - float** values; - int size; + HeapBlock values; + const int size; // no reason not to implement these one day.. ImageConvolutionKernel (const ImageConvolutionKernel&); diff --git a/src/io/files/juce_FileOutputStream.cpp b/src/io/files/juce_FileOutputStream.cpp index 15d65a07ea..9bfa20bf4f 100644 --- a/src/io/files/juce_FileOutputStream.cpp +++ b/src/io/files/juce_FileOutputStream.cpp @@ -58,7 +58,7 @@ FileOutputStream::FileOutputStream (const File& f, } } - buffer = (char*) juce_malloc (jmax (bufferSize_, 16)); + buffer.malloc (jmax (bufferSize_, 16)); } FileOutputStream::~FileOutputStream() @@ -66,7 +66,6 @@ FileOutputStream::~FileOutputStream() flush(); juce_fileClose (fileHandle); - juce_free (buffer); } int64 FileOutputStream::getPosition() diff --git a/src/io/files/juce_FileOutputStream.h b/src/io/files/juce_FileOutputStream.h index fffa35b187..56f24633e1 100644 --- a/src/io/files/juce_FileOutputStream.h +++ b/src/io/files/juce_FileOutputStream.h @@ -84,7 +84,7 @@ private: void* fileHandle; int64 currentPosition; int bufferSize, bytesInBuffer; - char* buffer; + HeapBlock buffer; }; #endif // __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__ diff --git a/src/io/files/juce_ZipFile.h b/src/io/files/juce_ZipFile.h index f54b688bde..11d4f54e0c 100644 --- a/src/io/files/juce_ZipFile.h +++ b/src/io/files/juce_ZipFile.h @@ -30,6 +30,7 @@ #include "../streams/juce_InputStream.h" #include "../streams/juce_InputSource.h" #include "../../threads/juce_CriticalSection.h" +#include "../../containers/juce_VoidArray.h" //============================================================================== diff --git a/src/io/network/juce_URL.cpp b/src/io/network/juce_URL.cpp index 2728204530..3f4914bdf6 100644 --- a/src/io/network/juce_URL.cpp +++ b/src/io/network/juce_URL.cpp @@ -550,7 +550,7 @@ const StringPairArray& URL::getMimeTypesOfUploadFiles() const throw() const String URL::removeEscapeChars (const String& s) { const int len = s.length(); - uint8* const resultUTF8 = (uint8*) juce_calloc (len * 4); + HeapBlock resultUTF8 (len * 4); uint8* r = resultUTF8; for (int i = 0; i < len; ++i) @@ -572,9 +572,7 @@ const String URL::removeEscapeChars (const String& s) *r++ = c; } - const String stringResult (String::fromUTF8 (resultUTF8)); - juce_free (resultUTF8); - return stringResult; + return String::fromUTF8 (resultUTF8); } const String URL::addEscapeChars (const String& s, const bool isParameter) diff --git a/src/io/streams/juce_BufferedInputStream.cpp b/src/io/streams/juce_BufferedInputStream.cpp index 3d477cb338..6563611731 100644 --- a/src/io/streams/juce_BufferedInputStream.cpp +++ b/src/io/streams/juce_BufferedInputStream.cpp @@ -47,15 +47,13 @@ BufferedInputStream::BufferedInputStream (InputStream* const source_, bufferSize = jmin (jmax (32, sourceSize), bufferSize); bufferStart = position; - buffer = (char*) juce_malloc (bufferSize); + buffer.malloc (bufferSize); } BufferedInputStream::~BufferedInputStream() throw() { if (deleteSourceWhenDestroyed) delete source; - - juce_free (buffer); } //============================================================================== @@ -94,7 +92,7 @@ void BufferedInputStream::ensureBuffered() && position >= bufferStart) { const int bytesToKeep = (int) (lastReadPos - position); - memmove (buffer, buffer + position - bufferStart, bytesToKeep); + memmove (buffer, buffer + (int) (position - bufferStart), bytesToKeep); bufferStart = position; @@ -122,7 +120,7 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) if (position >= bufferStart && position + maxBytesToRead <= lastReadPos) { - memcpy (destBuffer, buffer + (position - bufferStart), maxBytesToRead); + memcpy (destBuffer, buffer + (int) (position - bufferStart), maxBytesToRead); position += maxBytesToRead; return maxBytesToRead; @@ -140,7 +138,7 @@ int BufferedInputStream::read (void* destBuffer, int maxBytesToRead) if (bytesAvailable > 0) { - memcpy (destBuffer, buffer + (position - bufferStart), bytesAvailable); + memcpy (destBuffer, buffer + (int) (position - bufferStart), bytesAvailable); maxBytesToRead -= bytesAvailable; bytesRead += bytesAvailable; position += bytesAvailable; @@ -168,7 +166,7 @@ const String BufferedInputStream::readString() { const int maxChars = (int) (lastReadPos - position); - const char* const src = buffer + (position - bufferStart); + const char* const src = buffer + (int) (position - bufferStart); for (int i = 0; i < maxChars; ++i) { diff --git a/src/io/streams/juce_BufferedInputStream.h b/src/io/streams/juce_BufferedInputStream.h index b0acde494c..64dc8c22af 100644 --- a/src/io/streams/juce_BufferedInputStream.h +++ b/src/io/streams/juce_BufferedInputStream.h @@ -77,7 +77,7 @@ private: const bool deleteSourceWhenDestroyed; int bufferSize; int64 position, lastReadPos, bufferStart, bufferOverlap; - char* buffer; + HeapBlock buffer; void ensureBuffered(); BufferedInputStream (const BufferedInputStream&); diff --git a/src/io/streams/juce_GZIPCompressorOutputStream.cpp b/src/io/streams/juce_GZIPCompressorOutputStream.cpp index 88c180f5f4..4ed01774e7 100644 --- a/src/io/streams/juce_GZIPCompressorOutputStream.cpp +++ b/src/io/streams/juce_GZIPCompressorOutputStream.cpp @@ -49,7 +49,7 @@ using namespace zlibNamespace; class GZIPCompressorHelper { private: - z_stream* stream; + HeapBlock stream; uint8* data; int dataSize, compLevel, strategy; bool setParams; @@ -66,7 +66,7 @@ public: finished (false), shouldFinish (false) { - stream = (z_stream*) juce_calloc (sizeof (z_stream)); + stream.calloc (1); if (deflateInit2 (stream, compLevel, @@ -75,18 +75,14 @@ public: 8, strategy) != Z_OK) { - juce_free (stream); - stream = 0; + stream.free(); } } ~GZIPCompressorHelper() { if (stream != 0) - { deflateEnd (stream); - juce_free (stream); - } } bool needsInput() const throw() @@ -143,14 +139,14 @@ GZIPCompressorOutputStream::GZIPCompressorOutputStream (OutputStream* const dest const bool deleteDestStream_, const bool noWrap) : destStream (destStream_), - deleteDestStream (deleteDestStream_) + deleteDestStream (deleteDestStream_), + buffer (gzipCompBufferSize) { if (compressionLevel < 1 || compressionLevel > 9) compressionLevel = -1; helper = new GZIPCompressorHelper (compressionLevel, noWrap); - buffer = (uint8*) juce_malloc (gzipCompBufferSize); } GZIPCompressorOutputStream::~GZIPCompressorOutputStream() @@ -160,8 +156,6 @@ GZIPCompressorOutputStream::~GZIPCompressorOutputStream() GZIPCompressorHelper* const h = (GZIPCompressorHelper*) helper; delete h; - juce_free (buffer); - if (deleteDestStream) delete destStream; } diff --git a/src/io/streams/juce_GZIPCompressorOutputStream.h b/src/io/streams/juce_GZIPCompressorOutputStream.h index 50a3e62cb4..dad214ba61 100644 --- a/src/io/streams/juce_GZIPCompressorOutputStream.h +++ b/src/io/streams/juce_GZIPCompressorOutputStream.h @@ -73,7 +73,7 @@ public: private: OutputStream* const destStream; const bool deleteDestStream; - uint8* buffer; + HeapBlock buffer; void* helper; bool doNextBlock(); diff --git a/src/io/streams/juce_GZIPDecompressorInputStream.cpp b/src/io/streams/juce_GZIPDecompressorInputStream.cpp index 1f1b159168..160a718d22 100644 --- a/src/io/streams/juce_GZIPDecompressorInputStream.cpp +++ b/src/io/streams/juce_GZIPDecompressorInputStream.cpp @@ -81,7 +81,7 @@ using namespace zlibNamespace; class GZIPDecompressHelper { private: - z_stream* stream; + HeapBlock stream; uint8* data; int dataSize; @@ -95,13 +95,12 @@ public: needsDictionary (false), error (false) { - stream = (z_stream*) juce_calloc (sizeof (z_stream)); + stream.calloc (1); if (inflateInit2 (stream, (noWrap) ? -MAX_WBITS : MAX_WBITS) != Z_OK) { - juce_free (stream); - stream = 0; + stream.free(); error = true; finished = true; } @@ -110,10 +109,7 @@ public: ~GZIPDecompressHelper() throw() { if (stream != 0) - { inflateEnd (stream); - juce_free (stream); - } } bool needsInput() const throw() { return dataSize <= 0; } @@ -177,16 +173,14 @@ GZIPDecompressorInputStream::GZIPDecompressorInputStream (InputStream* const sou isEof (false), activeBufferSize (0), originalSourcePos (sourceStream_->getPosition()), - currentPos (0) + currentPos (0), + buffer (gzipDecompBufferSize) { - buffer = (uint8*) juce_malloc (gzipDecompBufferSize); helper = new GZIPDecompressHelper (noWrap_); } GZIPDecompressorInputStream::~GZIPDecompressorInputStream() { - juce_free (buffer); - if (deleteSourceWhenDestroyed) delete sourceStream; diff --git a/src/io/streams/juce_GZIPDecompressorInputStream.h b/src/io/streams/juce_GZIPDecompressorInputStream.h index d2db5ff305..9d16637cdd 100644 --- a/src/io/streams/juce_GZIPDecompressorInputStream.h +++ b/src/io/streams/juce_GZIPDecompressorInputStream.h @@ -80,7 +80,7 @@ private: bool isEof; int activeBufferSize; int64 originalSourcePos, currentPos; - uint8* buffer; + HeapBlock buffer; void* helper; GZIPDecompressorInputStream (const GZIPDecompressorInputStream&); diff --git a/src/io/streams/juce_OutputStream.cpp b/src/io/streams/juce_OutputStream.cpp index 0bb9210e5a..1140d527a9 100644 --- a/src/io/streams/juce_OutputStream.cpp +++ b/src/io/streams/juce_OutputStream.cpp @@ -170,18 +170,16 @@ void OutputStream::writeDoubleBigEndian (double value) void OutputStream::writeString (const String& text) { const int numBytes = text.copyToUTF8 (0); - uint8* const temp = (uint8*) juce_malloc (numBytes); + HeapBlock temp (numBytes); text.copyToUTF8 (temp); write (temp, numBytes); // (numBytes includes the terminating null). - - juce_free (temp); } void OutputStream::printf (const char* pf, ...) { unsigned int bufSize = 256; - char* buf = (char*) juce_malloc (bufSize); + HeapBlock buf (bufSize); for (;;) { @@ -202,12 +200,9 @@ void OutputStream::printf (const char* pf, ...) break; } - juce_free (buf); bufSize += 256; - buf = (char*) juce_malloc (bufSize); + buf.malloc (bufSize); } - - juce_free (buf); } OutputStream& OutputStream::operator<< (const int number) diff --git a/src/juce_app_includes.h b/src/juce_app_includes.h index 668f13c348..9b4b98b7e0 100644 --- a/src/juce_app_includes.h +++ b/src/juce_app_includes.h @@ -44,53 +44,47 @@ #ifndef __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__ #include "application/juce_ApplicationProperties.h" #endif -#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ - #include "audio/midi/juce_MidiBuffer.h" +#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AiffAudioFormat.h" #endif -#ifndef __JUCE_MIDIFILE_JUCEHEADER__ - #include "audio/midi/juce_MidiFile.h" +#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioCDBurner.h" #endif -#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ - #include "audio/midi/juce_MidiKeyboardState.h" +#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioCDReader.h" #endif -#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ - #include "audio/midi/juce_MidiMessageCollector.h" +#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioFormat.h" #endif -#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ - #include "audio/midi/juce_MidiMessageSequence.h" +#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioFormatManager.h" #endif -#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ - #include "audio/midi/juce_MidiMessage.h" +#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioFormatReader.h" #endif -#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ - #include "audio/dsp/juce_AudioDataConverters.h" +#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioFormatWriter.h" #endif -#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ - #include "audio/dsp/juce_AudioSampleBuffer.h" +#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioSubsectionReader.h" #endif -#ifndef __JUCE_IIRFILTER_JUCEHEADER__ - #include "audio/dsp/juce_IIRFilter.h" +#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioThumbnail.h" #endif -#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ - #include "audio/processors/juce_AudioPlayHead.h" +#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ + #include "audio/audio_file_formats/juce_AudioThumbnailCache.h" #endif -#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ - #include "audio/processors/juce_AudioProcessor.h" +#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_FlacAudioFormat.h" #endif -#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ - #include "audio/processors/juce_AudioProcessorEditor.h" +#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_OggVorbisAudioFormat.h" #endif -#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ - #include "audio/processors/juce_AudioProcessorGraph.h" +#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_QuickTimeAudioFormat.h" #endif -#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ - #include "audio/processors/juce_AudioProcessorListener.h" -#endif -#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ - #include "audio/processors/juce_AudioProcessorPlayer.h" -#endif -#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ - #include "audio/processors/juce_GenericAudioProcessorEditor.h" +#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ + #include "audio/audio_file_formats/juce_WavAudioFormat.h" #endif #ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__ #include "audio/audio_sources/juce_AudioFormatReaderSource.h" @@ -140,11 +134,32 @@ #ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__ #include "audio/devices/juce_MidiOutput.h" #endif -#ifndef __JUCE_SAMPLER_JUCEHEADER__ - #include "audio/synthesisers/juce_Sampler.h" +#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__ + #include "audio/dsp/juce_AudioDataConverters.h" #endif -#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ - #include "audio/synthesisers/juce_Synthesiser.h" +#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__ + #include "audio/dsp/juce_AudioSampleBuffer.h" +#endif +#ifndef __JUCE_IIRFILTER_JUCEHEADER__ + #include "audio/dsp/juce_IIRFilter.h" +#endif +#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__ + #include "audio/midi/juce_MidiBuffer.h" +#endif +#ifndef __JUCE_MIDIFILE_JUCEHEADER__ + #include "audio/midi/juce_MidiFile.h" +#endif +#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__ + #include "audio/midi/juce_MidiKeyboardState.h" +#endif +#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__ + #include "audio/midi/juce_MidiMessage.h" +#endif +#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__ + #include "audio/midi/juce_MidiMessageCollector.h" +#endif +#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__ + #include "audio/midi/juce_MidiMessageSequence.h" #endif #ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__ #include "audio/plugins/formats/juce_AudioUnitPluginFormat.h" @@ -182,47 +197,32 @@ #ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__ #include "audio/plugins/juce_PluginListComponent.h" #endif -#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AiffAudioFormat.h" +#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__ + #include "audio/processors/juce_AudioPlayHead.h" #endif -#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioFormat.h" +#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__ + #include "audio/processors/juce_AudioProcessor.h" #endif -#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioFormatManager.h" +#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__ + #include "audio/processors/juce_AudioProcessorEditor.h" #endif -#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioFormatReader.h" +#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__ + #include "audio/processors/juce_AudioProcessorGraph.h" #endif -#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioFormatWriter.h" +#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__ + #include "audio/processors/juce_AudioProcessorListener.h" #endif -#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioSubsectionReader.h" +#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__ + #include "audio/processors/juce_AudioProcessorPlayer.h" #endif -#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioThumbnail.h" +#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__ + #include "audio/processors/juce_GenericAudioProcessorEditor.h" #endif -#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioThumbnailCache.h" +#ifndef __JUCE_SAMPLER_JUCEHEADER__ + #include "audio/synthesisers/juce_Sampler.h" #endif -#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_FlacAudioFormat.h" -#endif -#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_WavAudioFormat.h" -#endif -#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioCDReader.h" -#endif -#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_OggVorbisAudioFormat.h" -#endif -#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__ - #include "audio/audio_file_formats/juce_QuickTimeAudioFormat.h" -#endif -#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__ - #include "audio/audio_file_formats/juce_AudioCDBurner.h" +#ifndef __JUCE_SYNTHESISER_JUCEHEADER__ + #include "audio/synthesisers/juce_Synthesiser.h" #endif #ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__ #include "events/juce_ActionBroadcaster.h" @@ -269,126 +269,6 @@ #ifndef __JUCE_TIMER_JUCEHEADER__ #include "events/juce_Timer.h" #endif -#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__ - #include "gui/graphics/colour/juce_PixelFormats.h" -#endif -#ifndef __JUCE_COLOUR_JUCEHEADER__ - #include "gui/graphics/colour/juce_Colour.h" -#endif -#ifndef __JUCE_COLOURS_JUCEHEADER__ - #include "gui/graphics/colour/juce_Colours.h" -#endif -#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__ - #include "gui/graphics/colour/juce_ColourGradient.h" -#endif -#ifndef __JUCE_TYPEFACE_JUCEHEADER__ - #include "gui/graphics/fonts/juce_Typeface.h" -#endif -#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ - #include "gui/graphics/fonts/juce_TextLayout.h" -#endif -#ifndef __JUCE_FONT_JUCEHEADER__ - #include "gui/graphics/fonts/juce_Font.h" -#endif -#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ - #include "gui/graphics/fonts/juce_GlyphArrangement.h" -#endif -#ifndef __JUCE_FILLTYPE_JUCEHEADER__ - #include "gui/graphics/contexts/juce_FillType.h" -#endif -#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ - #include "gui/graphics/contexts/juce_Justification.h" -#endif -#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ - #include "gui/graphics/contexts/juce_RectanglePlacement.h" -#endif -#ifndef __JUCE_EDGETABLE_JUCEHEADER__ - #include "gui/graphics/contexts/juce_EdgeTable.h" -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ - #include "gui/graphics/contexts/juce_LowLevelGraphicsContext.h" -#endif -#ifndef __JUCE_GRAPHICS_JUCEHEADER__ - #include "gui/graphics/contexts/juce_Graphics.h" -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ - #include "gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" -#endif -#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ - #include "gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h" -#endif -#ifndef __JUCE_PATH_JUCEHEADER__ - #include "gui/graphics/geometry/juce_Path.h" -#endif -#ifndef __JUCE_BORDERSIZE_JUCEHEADER__ - #include "gui/graphics/geometry/juce_BorderSize.h" -#endif -#ifndef __JUCE_LINE_JUCEHEADER__ - #include "gui/graphics/geometry/juce_Line.h" -#endif -#ifndef __JUCE_POINT_JUCEHEADER__ - #include "gui/graphics/geometry/juce_Point.h" -#endif -#ifndef __JUCE_RECTANGLE_JUCEHEADER__ - #include "gui/graphics/geometry/juce_Rectangle.h" -#endif -#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ - #include "gui/graphics/geometry/juce_PathStrokeType.h" -#endif -#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ - #include "gui/graphics/geometry/juce_PositionedRectangle.h" -#endif -#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ - #include "gui/graphics/geometry/juce_RectangleList.h" -#endif -#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ - #include "gui/graphics/geometry/juce_PathIterator.h" -#endif -#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ - #include "gui/graphics/geometry/juce_AffineTransform.h" -#endif -#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ - #include "gui/graphics/imaging/juce_CameraDevice.h" -#endif -#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ - #include "gui/graphics/imaging/juce_ImageCache.h" -#endif -#ifndef __JUCE_IMAGE_JUCEHEADER__ - #include "gui/graphics/imaging/juce_Image.h" -#endif -#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ - #include "gui/graphics/imaging/juce_ImageFileFormat.h" -#endif -#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ - #include "gui/graphics/imaging/juce_ImageConvolutionKernel.h" -#endif -#ifndef __JUCE_DRAWABLE_JUCEHEADER__ - #include "gui/graphics/drawables/juce_Drawable.h" -#endif -#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ - #include "gui/graphics/drawables/juce_DrawableComposite.h" -#endif -#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ - #include "gui/graphics/drawables/juce_DrawableImage.h" -#endif -#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ - #include "gui/graphics/drawables/juce_DrawableText.h" -#endif -#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ - #include "gui/graphics/drawables/juce_DrawablePath.h" -#endif -#ifndef __JUCE_COMPONENT_JUCEHEADER__ - #include "gui/components/juce_Component.h" -#endif -#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ - #include "gui/components/juce_ComponentDeletionWatcher.h" -#endif -#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ - #include "gui/components/juce_ComponentListener.h" -#endif -#ifndef __JUCE_DESKTOP_JUCEHEADER__ - #include "gui/components/juce_Desktop.h" -#endif #ifndef __JUCE_ARROWBUTTON_JUCEHEADER__ #include "gui/components/buttons/juce_ArrowButton.h" #endif @@ -416,89 +296,17 @@ #ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__ #include "gui/components/buttons/juce_ToolbarButton.h" #endif -#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ - #include "gui/graphics/effects/juce_DropShadowEffect.h" -#endif -#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ - #include "gui/graphics/effects/juce_GlowEffect.h" -#endif -#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ - #include "gui/graphics/effects/juce_ImageEffectFilter.h" -#endif -#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ - #include "gui/graphics/effects/juce_ReduceOpacityEffect.h" -#endif -#ifndef __JUCE_KEYLISTENER_JUCEHEADER__ - #include "gui/components/keyboard/juce_KeyListener.h" -#endif -#ifndef __JUCE_KEYPRESS_JUCEHEADER__ - #include "gui/components/keyboard/juce_KeyPress.h" -#endif -#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ - #include "gui/components/keyboard/juce_KeyPressMappingSet.h" -#endif -#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ - #include "gui/components/keyboard/juce_KeyboardFocusTraverser.h" -#endif -#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ - #include "gui/components/keyboard/juce_ModifierKeys.h" -#endif -#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ - #include "gui/components/keyboard/juce_KeyMappingEditorComponent.h" +#ifndef __JUCE_CODEDOCUMENT_JUCEHEADER__ + #include "gui/components/code_editor/juce_CodeDocument.h" #endif #ifndef __JUCE_CODEEDITORCOMPONENT_JUCEHEADER__ #include "gui/components/code_editor/juce_CodeEditorComponent.h" #endif -#ifndef __JUCE_CPLUSPLUSCODETOKENISER_JUCEHEADER__ - #include "gui/components/code_editor/juce_CPlusPlusCodeTokeniser.h" -#endif -#ifndef __JUCE_CODEDOCUMENT_JUCEHEADER__ - #include "gui/components/code_editor/juce_CodeDocument.h" -#endif #ifndef __JUCE_CODETOKENISER_JUCEHEADER__ #include "gui/components/code_editor/juce_CodeTokeniser.h" #endif -#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ - #include "gui/components/menus/juce_MenuBarComponent.h" -#endif -#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ - #include "gui/components/menus/juce_MenuBarModel.h" -#endif -#ifndef __JUCE_POPUPMENU_JUCEHEADER__ - #include "gui/components/menus/juce_PopupMenu.h" -#endif -#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ - #include "gui/components/menus/juce_PopupMenuCustomComponent.h" -#endif -#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ - #include "gui/components/mouse/juce_ComponentDragger.h" -#endif -#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__ - #include "gui/components/mouse/juce_DragAndDropTarget.h" -#endif -#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ - #include "gui/components/mouse/juce_FileDragAndDropTarget.h" -#endif -#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ - #include "gui/components/mouse/juce_LassoComponent.h" -#endif -#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__ - #include "gui/components/mouse/juce_MouseCursor.h" -#endif -#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ - #include "gui/components/mouse/juce_MouseEvent.h" -#endif -#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ - #include "gui/components/mouse/juce_MouseHoverDetector.h" -#endif -#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ - #include "gui/components/mouse/juce_MouseListener.h" -#endif -#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ - #include "gui/components/mouse/juce_TooltipClient.h" -#endif -#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ - #include "gui/components/mouse/juce_DragAndDropContainer.h" +#ifndef __JUCE_CPLUSPLUSCODETOKENISER_JUCEHEADER__ + #include "gui/components/code_editor/juce_CPlusPlusCodeTokeniser.h" #endif #ifndef __JUCE_COMBOBOX_JUCEHEADER__ #include "gui/components/controls/juce_ComboBox.h" @@ -506,6 +314,9 @@ #ifndef __JUCE_LABEL_JUCEHEADER__ #include "gui/components/controls/juce_Label.h" #endif +#ifndef __JUCE_LISTBOX_JUCEHEADER__ + #include "gui/components/controls/juce_ListBox.h" +#endif #ifndef __JUCE_PROGRESSBAR_JUCEHEADER__ #include "gui/components/controls/juce_ProgressBar.h" #endif @@ -521,47 +332,95 @@ #ifndef __JUCE_TABLELISTBOX_JUCEHEADER__ #include "gui/components/controls/juce_TableListBox.h" #endif +#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ + #include "gui/components/controls/juce_TextEditor.h" +#endif #ifndef __JUCE_TOOLBAR_JUCEHEADER__ #include "gui/components/controls/juce_Toolbar.h" #endif +#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ + #include "gui/components/controls/juce_ToolbarItemComponent.h" +#endif #ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__ #include "gui/components/controls/juce_ToolbarItemFactory.h" #endif -#ifndef __JUCE_LISTBOX_JUCEHEADER__ - #include "gui/components/controls/juce_ListBox.h" -#endif #ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__ #include "gui/components/controls/juce_ToolbarItemPalette.h" #endif #ifndef __JUCE_TREEVIEW_JUCEHEADER__ #include "gui/components/controls/juce_TreeView.h" #endif -#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__ - #include "gui/components/controls/juce_TextEditor.h" +#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h" #endif -#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__ - #include "gui/components/controls/juce_ToolbarItemComponent.h" +#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ + #include "gui/components/filebrowser/juce_DirectoryContentsList.h" #endif -#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_BooleanPropertyComponent.h" +#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileBrowserComponent.h" #endif -#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_ButtonPropertyComponent.h" +#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileBrowserListener.h" #endif -#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_ChoicePropertyComponent.h" +#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileChooser.h" #endif -#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ - #include "gui/components/properties/juce_PropertyPanel.h" +#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileChooserDialogBox.h" #endif -#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_PropertyComponent.h" +#ifndef __JUCE_FILEFILTER_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileFilter.h" #endif -#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_SliderPropertyComponent.h" +#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileListComponent.h" #endif -#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ - #include "gui/components/properties/juce_TextPropertyComponent.h" +#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FilenameComponent.h" +#endif +#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FilePreviewComponent.h" +#endif +#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileSearchPathListComponent.h" +#endif +#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_FileTreeComponent.h" +#endif +#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ + #include "gui/components/filebrowser/juce_ImagePreviewComponent.h" +#endif +#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ + #include "gui/components/filebrowser/juce_WildcardFileFilter.h" +#endif +#ifndef __JUCE_COMPONENT_JUCEHEADER__ + #include "gui/components/juce_Component.h" +#endif +#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__ + #include "gui/components/juce_ComponentDeletionWatcher.h" +#endif +#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__ + #include "gui/components/juce_ComponentListener.h" +#endif +#ifndef __JUCE_DESKTOP_JUCEHEADER__ + #include "gui/components/juce_Desktop.h" +#endif +#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__ + #include "gui/components/keyboard/juce_KeyboardFocusTraverser.h" +#endif +#ifndef __JUCE_KEYLISTENER_JUCEHEADER__ + #include "gui/components/keyboard/juce_KeyListener.h" +#endif +#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__ + #include "gui/components/keyboard/juce_KeyMappingEditorComponent.h" +#endif +#ifndef __JUCE_KEYPRESS_JUCEHEADER__ + #include "gui/components/keyboard/juce_KeyPress.h" +#endif +#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__ + #include "gui/components/keyboard/juce_KeyPressMappingSet.h" +#endif +#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ + #include "gui/components/keyboard/juce_ModifierKeys.h" #endif #ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__ #include "gui/components/layout/juce_ComponentAnimator.h" @@ -605,74 +464,74 @@ #ifndef __JUCE_VIEWPORT_JUCEHEADER__ #include "gui/components/layout/juce_Viewport.h" #endif -#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.h" +#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ + #include "gui/components/lookandfeel/juce_LookAndFeel.h" #endif -#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__ - #include "gui/components/filebrowser/juce_DirectoryContentsList.h" +#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ + #include "gui/components/lookandfeel/juce_OldSchoolLookAndFeel.h" #endif -#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileBrowserListener.h" +#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__ + #include "gui/components/menus/juce_MenuBarComponent.h" #endif -#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileListComponent.h" +#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__ + #include "gui/components/menus/juce_MenuBarModel.h" #endif -#ifndef __JUCE_FILEFILTER_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileFilter.h" +#ifndef __JUCE_POPUPMENU_JUCEHEADER__ + #include "gui/components/menus/juce_PopupMenu.h" #endif -#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileTreeComponent.h" +#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__ + #include "gui/components/menus/juce_PopupMenuCustomComponent.h" #endif -#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileChooserDialogBox.h" +#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__ + #include "gui/components/mouse/juce_ComponentDragger.h" #endif -#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FilePreviewComponent.h" +#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__ + #include "gui/components/mouse/juce_DragAndDropContainer.h" #endif -#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FilenameComponent.h" +#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__ + #include "gui/components/mouse/juce_DragAndDropTarget.h" #endif -#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileSearchPathListComponent.h" +#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__ + #include "gui/components/mouse/juce_FileDragAndDropTarget.h" #endif -#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__ - #include "gui/components/filebrowser/juce_WildcardFileFilter.h" +#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__ + #include "gui/components/mouse/juce_LassoComponent.h" #endif -#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_ImagePreviewComponent.h" +#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__ + #include "gui/components/mouse/juce_MouseCursor.h" #endif -#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileBrowserComponent.h" +#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__ + #include "gui/components/mouse/juce_MouseEvent.h" #endif -#ifndef __JUCE_FILECHOOSER_JUCEHEADER__ - #include "gui/components/filebrowser/juce_FileChooser.h" +#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__ + #include "gui/components/mouse/juce_MouseHoverDetector.h" #endif -#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_AlertWindow.h" +#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__ + #include "gui/components/mouse/juce_MouseListener.h" #endif -#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_DialogWindow.h" +#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__ + #include "gui/components/mouse/juce_TooltipClient.h" #endif -#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_DocumentWindow.h" +#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_BooleanPropertyComponent.h" #endif -#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_ResizableWindow.h" +#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_ButtonPropertyComponent.h" #endif -#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ - #include "gui/components/windows/juce_SplashScreen.h" +#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_ChoicePropertyComponent.h" #endif -#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_TooltipWindow.h" +#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_PropertyComponent.h" #endif -#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_TopLevelWindow.h" +#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__ + #include "gui/components/properties/juce_PropertyPanel.h" #endif -#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ - #include "gui/components/windows/juce_ThreadWithProgressWindow.h" +#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_SliderPropertyComponent.h" #endif -#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ - #include "gui/components/windows/juce_ComponentPeer.h" +#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__ + #include "gui/components/properties/juce_TextPropertyComponent.h" #endif #ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__ #include "gui/components/special/juce_ActiveXControlComponent.h" @@ -707,20 +566,161 @@ #ifndef __JUCE_PREFERENCESPANEL_JUCEHEADER__ #include "gui/components/special/juce_PreferencesPanel.h" #endif -#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ - #include "gui/components/special/juce_WebBrowserComponent.h" +#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__ + #include "gui/components/special/juce_QuickTimeMovieComponent.h" #endif #ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__ #include "gui/components/special/juce_SystemTrayIconComponent.h" #endif -#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__ - #include "gui/components/special/juce_QuickTimeMovieComponent.h" +#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__ + #include "gui/components/special/juce_WebBrowserComponent.h" #endif -#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__ - #include "gui/components/lookandfeel/juce_LookAndFeel.h" +#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_AlertWindow.h" #endif -#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__ - #include "gui/components/lookandfeel/juce_OldSchoolLookAndFeel.h" +#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__ + #include "gui/components/windows/juce_ComponentPeer.h" +#endif +#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_DialogWindow.h" +#endif +#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_DocumentWindow.h" +#endif +#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_ResizableWindow.h" +#endif +#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__ + #include "gui/components/windows/juce_SplashScreen.h" +#endif +#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_ThreadWithProgressWindow.h" +#endif +#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_TooltipWindow.h" +#endif +#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__ + #include "gui/components/windows/juce_TopLevelWindow.h" +#endif +#ifndef __JUCE_COLOUR_JUCEHEADER__ + #include "gui/graphics/colour/juce_Colour.h" +#endif +#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__ + #include "gui/graphics/colour/juce_ColourGradient.h" +#endif +#ifndef __JUCE_COLOURS_JUCEHEADER__ + #include "gui/graphics/colour/juce_Colours.h" +#endif +#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__ + #include "gui/graphics/colour/juce_PixelFormats.h" +#endif +#ifndef __JUCE_EDGETABLE_JUCEHEADER__ + #include "gui/graphics/contexts/juce_EdgeTable.h" +#endif +#ifndef __JUCE_FILLTYPE_JUCEHEADER__ + #include "gui/graphics/contexts/juce_FillType.h" +#endif +#ifndef __JUCE_GRAPHICS_JUCEHEADER__ + #include "gui/graphics/contexts/juce_Graphics.h" +#endif +#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__ + #include "gui/graphics/contexts/juce_Justification.h" +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__ + #include "gui/graphics/contexts/juce_LowLevelGraphicsContext.h" +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__ + #include "gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.h" +#endif +#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__ + #include "gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.h" +#endif +#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__ + #include "gui/graphics/contexts/juce_RectanglePlacement.h" +#endif +#ifndef __JUCE_DRAWABLE_JUCEHEADER__ + #include "gui/graphics/drawables/juce_Drawable.h" +#endif +#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawableComposite.h" +#endif +#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawableImage.h" +#endif +#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawablePath.h" +#endif +#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__ + #include "gui/graphics/drawables/juce_DrawableText.h" +#endif +#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__ + #include "gui/graphics/effects/juce_DropShadowEffect.h" +#endif +#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__ + #include "gui/graphics/effects/juce_GlowEffect.h" +#endif +#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__ + #include "gui/graphics/effects/juce_ImageEffectFilter.h" +#endif +#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__ + #include "gui/graphics/effects/juce_ReduceOpacityEffect.h" +#endif +#ifndef __JUCE_FONT_JUCEHEADER__ + #include "gui/graphics/fonts/juce_Font.h" +#endif +#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__ + #include "gui/graphics/fonts/juce_GlyphArrangement.h" +#endif +#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__ + #include "gui/graphics/fonts/juce_TextLayout.h" +#endif +#ifndef __JUCE_TYPEFACE_JUCEHEADER__ + #include "gui/graphics/fonts/juce_Typeface.h" +#endif +#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__ + #include "gui/graphics/geometry/juce_AffineTransform.h" +#endif +#ifndef __JUCE_BORDERSIZE_JUCEHEADER__ + #include "gui/graphics/geometry/juce_BorderSize.h" +#endif +#ifndef __JUCE_LINE_JUCEHEADER__ + #include "gui/graphics/geometry/juce_Line.h" +#endif +#ifndef __JUCE_PATH_JUCEHEADER__ + #include "gui/graphics/geometry/juce_Path.h" +#endif +#ifndef __JUCE_PATHITERATOR_JUCEHEADER__ + #include "gui/graphics/geometry/juce_PathIterator.h" +#endif +#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__ + #include "gui/graphics/geometry/juce_PathStrokeType.h" +#endif +#ifndef __JUCE_POINT_JUCEHEADER__ + #include "gui/graphics/geometry/juce_Point.h" +#endif +#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__ + #include "gui/graphics/geometry/juce_PositionedRectangle.h" +#endif +#ifndef __JUCE_RECTANGLE_JUCEHEADER__ + #include "gui/graphics/geometry/juce_Rectangle.h" +#endif +#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__ + #include "gui/graphics/geometry/juce_RectangleList.h" +#endif +#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ + #include "gui/graphics/imaging/juce_CameraDevice.h" +#endif +#ifndef __JUCE_IMAGE_JUCEHEADER__ + #include "gui/graphics/imaging/juce_Image.h" +#endif +#ifndef __JUCE_IMAGECACHE_JUCEHEADER__ + #include "gui/graphics/imaging/juce_ImageCache.h" +#endif +#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__ + #include "gui/graphics/imaging/juce_ImageConvolutionKernel.h" +#endif +#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__ + #include "gui/graphics/imaging/juce_ImageFileFormat.h" #endif #ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__ #include "utilities/juce_DeletedAtShutdown.h" diff --git a/src/juce_core_includes.h b/src/juce_core_includes.h index e429ea620a..503fdf062c 100644 --- a/src/juce_core_includes.h +++ b/src/juce_core_includes.h @@ -26,75 +26,21 @@ #ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ #define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__ -#ifndef __JUCE_ATOMIC_JUCEHEADER__ - #include "core/juce_Atomic.h" -#endif -#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ - #include "core/juce_DataConversions.h" -#endif -#ifndef __JUCE_FILELOGGER_JUCEHEADER__ - #include "core/juce_FileLogger.h" -#endif -#ifndef __JUCE_INITIALISATION_JUCEHEADER__ - #include "core/juce_Initialisation.h" -#endif -#ifndef __JUCE_LOGGER_JUCEHEADER__ - #include "core/juce_Logger.h" -#endif -#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ - #include "core/juce_PlatformUtilities.h" -#endif -#ifndef __JUCE_MEMORY_JUCEHEADER__ - #include "core/juce_Memory.h" -#endif -#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ - #include "core/juce_PerformanceCounter.h" -#endif -#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ - #include "core/juce_PlatformDefs.h" -#endif -#ifndef __JUCE_SINGLETON_JUCEHEADER__ - #include "core/juce_Singleton.h" -#endif -#ifndef __JUCE_RANDOM_JUCEHEADER__ - #include "core/juce_Random.h" -#endif -#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ - #include "core/juce_RelativeTime.h" -#endif -#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ - #include "core/juce_SystemStats.h" -#endif -#ifndef __JUCE_TIME_JUCEHEADER__ - #include "core/juce_Time.h" -#endif -#ifndef __JUCE_UUID_JUCEHEADER__ - #include "core/juce_Uuid.h" -#endif -#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ - #include "core/juce_StandardHeader.h" -#endif -#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__ - #include "core/juce_MathsFunctions.h" -#endif -#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ - #include "core/juce_TargetPlatform.h" -#endif #ifndef __JUCE_ARRAY_JUCEHEADER__ #include "containers/juce_Array.h" #endif #ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__ #include "containers/juce_ArrayAllocationBase.h" #endif -#ifndef __JUCE_VARIANT_JUCEHEADER__ - #include "containers/juce_Variant.h" -#endif #ifndef __JUCE_BITARRAY_JUCEHEADER__ #include "containers/juce_BitArray.h" #endif #ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__ #include "containers/juce_ElementComparator.h" #endif +#ifndef __JUCE_HEAPBLOCK_JUCEHEADER__ + #include "containers/juce_HeapBlock.h" +#endif #ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__ #include "containers/juce_MemoryBlock.h" #endif @@ -116,11 +62,80 @@ #ifndef __JUCE_SPARSESET_JUCEHEADER__ #include "containers/juce_SparseSet.h" #endif +#ifndef __JUCE_VALUETREE_JUCEHEADER__ + #include "containers/juce_ValueTree.h" +#endif +#ifndef __JUCE_VARIANT_JUCEHEADER__ + #include "containers/juce_Variant.h" +#endif #ifndef __JUCE_VOIDARRAY_JUCEHEADER__ #include "containers/juce_VoidArray.h" #endif -#ifndef __JUCE_VALUETREE_JUCEHEADER__ - #include "containers/juce_ValueTree.h" +#ifndef __JUCE_ATOMIC_JUCEHEADER__ + #include "core/juce_Atomic.h" +#endif +#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__ + #include "core/juce_DataConversions.h" +#endif +#ifndef __JUCE_FILELOGGER_JUCEHEADER__ + #include "core/juce_FileLogger.h" +#endif +#ifndef __JUCE_INITIALISATION_JUCEHEADER__ + #include "core/juce_Initialisation.h" +#endif +#ifndef __JUCE_LOGGER_JUCEHEADER__ + #include "core/juce_Logger.h" +#endif +#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__ + #include "core/juce_MathsFunctions.h" +#endif +#ifndef __JUCE_MEMORY_JUCEHEADER__ + #include "core/juce_Memory.h" +#endif +#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__ + #include "core/juce_PerformanceCounter.h" +#endif +#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__ + #include "core/juce_PlatformDefs.h" +#endif +#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__ + #include "core/juce_PlatformUtilities.h" +#endif +#ifndef __JUCE_RANDOM_JUCEHEADER__ + #include "core/juce_Random.h" +#endif +#ifndef __JUCE_RELATIVETIME_JUCEHEADER__ + #include "core/juce_RelativeTime.h" +#endif +#ifndef __JUCE_SINGLETON_JUCEHEADER__ + #include "core/juce_Singleton.h" +#endif +#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__ + #include "core/juce_StandardHeader.h" +#endif +#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__ + #include "core/juce_SystemStats.h" +#endif +#ifndef __JUCE_TARGETPLATFORM_JUCEHEADER__ + #include "core/juce_TargetPlatform.h" +#endif +#ifndef __JUCE_TIME_JUCEHEADER__ + #include "core/juce_Time.h" +#endif +#ifndef __JUCE_UUID_JUCEHEADER__ + #include "core/juce_Uuid.h" +#endif +#ifndef __JUCE_BLOWFISH_JUCEHEADER__ + #include "cryptography/juce_BlowFish.h" +#endif +#ifndef __JUCE_MD5_JUCEHEADER__ + #include "cryptography/juce_MD5.h" +#endif +#ifndef __JUCE_PRIMES_JUCEHEADER__ + #include "cryptography/juce_Primes.h" +#endif +#ifndef __JUCE_RSAKEY_JUCEHEADER__ + #include "cryptography/juce_RSAKey.h" #endif #ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__ #include "io/files/juce_DirectoryIterator.h" @@ -143,18 +158,6 @@ #ifndef __JUCE_ZIPFILE_JUCEHEADER__ #include "io/files/juce_ZipFile.h" #endif -#ifndef __JUCE_BLOWFISH_JUCEHEADER__ - #include "cryptography/juce_BlowFish.h" -#endif -#ifndef __JUCE_MD5_JUCEHEADER__ - #include "cryptography/juce_MD5.h" -#endif -#ifndef __JUCE_PRIMES_JUCEHEADER__ - #include "cryptography/juce_Primes.h" -#endif -#ifndef __JUCE_RSAKEY_JUCEHEADER__ - #include "cryptography/juce_RSAKey.h" -#endif #ifndef __JUCE_SOCKET_JUCEHEADER__ #include "io/network/juce_Socket.h" #endif @@ -191,15 +194,15 @@ #ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__ #include "io/streams/juce_SubregionStream.h" #endif +#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ + #include "text/juce_CharacterFunctions.h" +#endif #ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__ #include "text/juce_LocalisedStrings.h" #endif #ifndef __JUCE_STRING_JUCEHEADER__ #include "text/juce_String.h" #endif -#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ - #include "text/juce_CharacterFunctions.h" -#endif #ifndef __JUCE_STRINGARRAY_JUCEHEADER__ #include "text/juce_StringArray.h" #endif diff --git a/src/native/linux/juce_linux_JackAudio.cpp b/src/native/linux/juce_linux_JackAudio.cpp index 5d508325ba..7b70c959db 100644 --- a/src/native/linux/juce_linux_JackAudio.cpp +++ b/src/native/linux/juce_linux_JackAudio.cpp @@ -127,8 +127,6 @@ public: outputId (outputId_), isOpen_ (false), callback (0), - inChans (0), - outChans (0), totalNumberOfInputChannels (0), totalNumberOfOutputChannels (0) { @@ -167,8 +165,8 @@ public: JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0)); } - inChans = (float**) juce_calloc (sizeof (float*) * (totalNumberOfInputChannels + 2)); - outChans = (float**) juce_calloc (sizeof (float*) * (totalNumberOfOutputChannels + 2)); + inChans.calloc (totalNumberOfInputChannels + 2); + outChans.calloc (totalNumberOfOutputChannels + 2); } } @@ -180,9 +178,6 @@ public: JUCE_NAMESPACE::jack_client_close (client); client = 0; } - - juce_free (inChans); - juce_free (outChans); } const StringArray getChannelNames (bool forInput) const @@ -447,8 +442,7 @@ private: AudioIODeviceCallback* callback; CriticalSection callbackLock; - float** inChans; - float** outChans; + HeapBlock inChans, outChans; int totalNumberOfInputChannels; int totalNumberOfOutputChannels; VoidArray inputPorts, outputPorts; diff --git a/src/native/linux/juce_linux_Midi.cpp b/src/native/linux/juce_linux_Midi.cpp index be1f1acb9c..7ca71324e5 100644 --- a/src/native/linux/juce_linux_Midi.cpp +++ b/src/native/linux/juce_linux_Midi.cpp @@ -301,7 +301,7 @@ public: if (snd_midi_event_new (maxEventSize, &midiParser) >= 0) { - uint8* const buffer = (uint8*) juce_malloc (maxEventSize); + HeapBlock buffer (maxEventSize); const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN); struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd)); @@ -345,7 +345,6 @@ public: } snd_midi_event_free (midiParser); - juce_free (buffer); } }; diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 323b941250..d7bdebb92b 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -392,7 +392,7 @@ static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& i { const int width = image.getWidth(); const int height = image.getHeight(); - uint32* const colour = (uint32*) juce_malloc (width * height * sizeof (uint32)); + HeapBlock colour (width * height); int index = 0; for (int y = 0; y < height; ++y) @@ -408,7 +408,6 @@ static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& i GC gc = XCreateGC (display, pixmap, 0, 0); XPutImage (display, pixmap, gc, ximage, 0, 0, 0, 0, width, height); XFreeGC (display, gc); - juce_free (colour); return pixmap; } @@ -418,7 +417,8 @@ static Pixmap juce_createMaskPixmapFromImage (Display* display, const Image& ima const int width = image.getWidth(); const int height = image.getHeight(); const int stride = (width + 7) >> 3; - uint8* const mask = (uint8*) juce_calloc (stride * height); + HeapBlock mask; + mask.calloc (stride * height); const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); for (int y = 0; y < height; ++y) @@ -433,12 +433,8 @@ static Pixmap juce_createMaskPixmapFromImage (Display* display, const Image& ima } } - Pixmap pixmap = XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), - (char*) mask, width, height, 1, 0, 1); - - juce_free (mask); - - return pixmap; + return XCreatePixmapFromBitmapData (display, DefaultRootWindow (display), + (char*) mask, width, height, 1, 0, 1); } @@ -506,7 +502,8 @@ public: if (! usingXShm) #endif { - imageData = (uint8*) juce_malloc (lineStride * h); + imageDataAllocated.malloc (lineStride * h); + imageData = imageDataAllocated; if (format_ == ARGB && clearImage) zeromem (imageData, h * lineStride); @@ -534,7 +531,8 @@ public: const int pixelStride = 2; const int lineStride = ((w * pixelStride + 3) & ~3); - xImage->data = (char*) juce_malloc (lineStride * h); + imageData16Bit.malloc (lineStride * h); + xImage->data = imageData16Bit; xImage->bitmap_pad = 16; xImage->depth = pixelStride * 8; xImage->bytes_per_line = lineStride; @@ -567,13 +565,9 @@ public: else #endif { - juce_free (xImage->data); xImage->data = 0; XDestroyImage (xImage); } - - if (! is16Bit) - imageData = 0; // to stop the base class freeing this (for the 16-bit version we want it to free it) } void blitToWindow (Window window, int dx, int dy, int dw, int dh, int sx, int sy) @@ -629,6 +623,7 @@ public: private: XImage* xImage; const bool is16Bit; + HeapBlock imageData16Bit; #if JUCE_USE_XSHM XShmSegmentInfo segmentInfo; @@ -1094,7 +1089,7 @@ public: void setIcon (const Image& newIcon) { const int dataSize = newIcon.getWidth() * newIcon.getHeight() + 2; - unsigned long* const data = (unsigned long*) juce_malloc (dataSize * sizeof (uint32)); + HeapBlock data (dataSize); int index = 0; data[index++] = newIcon.getWidth(); @@ -1109,8 +1104,6 @@ public: XA_CARDINAL, 32, PropModeReplace, (unsigned char*) data, dataSize); - juce_free (data); - deleteIconPixmaps(); XWMHints* wmHints = XGetWMHints (display, windowH); @@ -2739,8 +2732,9 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot } const int stride = (cursorW + 7) >> 3; - uint8* const maskPlane = (uint8*) juce_calloc (stride * cursorH); - uint8* const sourcePlane = (uint8*) juce_calloc (stride * cursorH); + HeapBlock maskPlane, sourcePlane; + maskPlane.calloc (stride * cursorH); + sourcePlane.calloc (stride * cursorH); const bool msbfirst = (BitmapBitOrder (display) == MSBFirst); @@ -2764,9 +2758,6 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot Pixmap sourcePixmap = XCreatePixmapFromBitmapData (display, root, (char*) sourcePlane, cursorW, cursorH, 0xffff, 0, 1); Pixmap maskPixmap = XCreatePixmapFromBitmapData (display, root, (char*) maskPlane, cursorW, cursorH, 0xffff, 0, 1); - juce_free (maskPlane); - juce_free (sourcePlane); - XColor white, black; black.red = black.green = black.blue = 0; white.red = white.green = white.blue = 0xffff; diff --git a/src/native/mac/juce_mac_CoreAudio.cpp b/src/native/mac/juce_mac_CoreAudio.cpp index 8c05590627..37eadd462d 100644 --- a/src/native/mac/juce_mac_CoreAudio.cpp +++ b/src/native/mac/juce_mac_CoreAudio.cpp @@ -77,16 +77,11 @@ public: started (false), sampleRate (0), bufferSize (512), - audioBuffer (0), numInputChans (0), numOutputChans (0), callbacksAllowed (true), numInputChannelInfos (0), - numOutputChannelInfos (0), - tempInputBuffers (0), - tempOutputBuffers (0), - inputChannelInfo (0), - outputChannelInfo (0) + numOutputChannelInfos (0) { jassert (deviceID != 0); @@ -111,24 +106,15 @@ public: stop (false); delete inputDevice; - - juce_free (audioBuffer); - juce_free (tempInputBuffers); - juce_free (tempOutputBuffers); - juce_free (inputChannelInfo); - juce_free (outputChannelInfo); } void allocateTempBuffers() { const int tempBufSize = bufferSize + 4; - juce_free (audioBuffer); - audioBuffer = (float*) juce_calloc ((numInputChans + numOutputChans) * tempBufSize * sizeof (float)); + audioBuffer.calloc ((numInputChans + numOutputChans) * tempBufSize); - juce_free (tempInputBuffers); - tempInputBuffers = (float**) juce_calloc (sizeof (float*) * (numInputChans + 2)); - juce_free (tempOutputBuffers); - tempOutputBuffers = (float**) juce_calloc (sizeof (float*) * (numOutputChans + 2)); + tempInputBuffers.calloc (numInputChans + 2); + tempOutputBuffers.calloc (numOutputChans + 2); int i, count = 0; for (i = 0; i < numInputChans; ++i) @@ -151,7 +137,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); + HeapBlock bufList; + bufList.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) { @@ -211,8 +198,6 @@ public: } } } - - juce_free (bufList); } } @@ -252,7 +237,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); + HeapBlock ranges; + ranges.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) { @@ -273,8 +259,6 @@ public: if (bufferSize > 0) bufferSizes.addIfNotAlreadyThere (bufferSize); } - - juce_free (ranges); } if (bufferSizes.size() == 0 && bufferSize > 0) @@ -288,7 +272,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioValueRange* ranges = (AudioValueRange*) juce_calloc (size); + HeapBlock ranges; + ranges.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges))) { @@ -307,8 +292,6 @@ public: } } } - - juce_free (ranges); } if (sampleRates.size() == 0 && sampleRate > 0) @@ -340,12 +323,10 @@ public: inChanNames.clear(); outChanNames.clear(); - juce_free (inputChannelInfo); - inputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numInputChans + 2)); + inputChannelInfo.calloc (numInputChans + 2); numInputChannelInfos = 0; - juce_free (outputChannelInfo); - outputChannelInfo = (CallbackDetailsForChannel*) juce_calloc (sizeof (CallbackDetailsForChannel) * (numOutputChans + 2)); + outputChannelInfo.calloc (numOutputChans + 2); numOutputChannelInfos = 0; fillInChannelInfo (true); @@ -356,36 +337,31 @@ public: const StringArray getSources (bool input) { StringArray s; - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + for (int i = 0; i < num; ++i) { - for (int i = 0; i < num; ++i) + AudioValueTranslation avt; + char buffer[256]; + + avt.mInputData = (void*) &(types[i]); + avt.mInputDataSize = sizeof (UInt32); + avt.mOutputData = buffer; + avt.mOutputDataSize = 256; + + UInt32 transSize = sizeof (avt); + + AudioObjectPropertyAddress pa; + pa.mSelector = kAudioDevicePropertyDataSourceNameForID; + pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + pa.mElement = kAudioObjectPropertyElementMaster; + + if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt))) { - AudioValueTranslation avt; - char buffer[256]; - - avt.mInputData = (void*) &(types[i]); - avt.mInputDataSize = sizeof (UInt32); - avt.mOutputData = buffer; - avt.mOutputDataSize = 256; - - UInt32 transSize = sizeof (avt); - - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSourceNameForID; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; - - if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &transSize, &avt))) - { - DBG (buffer); - s.add (buffer); - } + DBG (buffer); + s.add (buffer); } - - juce_free (types); } return s; @@ -406,21 +382,16 @@ public: { if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ¤tSourceID))) { - int num = 0; - OSType* const types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + for (int i = 0; i < num; ++i) { - for (int i = 0; i < num; ++i) + if (types[num] == currentSourceID) { - if (types[num] == currentSourceID) - { - result = i; - break; - } + result = i; + break; } - - juce_free (types); } } } @@ -432,24 +403,19 @@ public: { if (deviceID != 0) { - int num = 0; - OSType* types = getAllDataSourcesForDevice (deviceID, input, num); + HeapBlock types; + const int num = getAllDataSourcesForDevice (deviceID, input, types); - if (types != 0) + if (((unsigned int) index) < (unsigned int) num) { - if (((unsigned int) index) < (unsigned int) num) - { - AudioObjectPropertyAddress pa; - pa.mSelector = kAudioDevicePropertyDataSource; - pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; - pa.mElement = kAudioObjectPropertyElementMaster; + AudioObjectPropertyAddress pa; + pa.mSelector = kAudioDevicePropertyDataSource; + pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; + pa.mElement = kAudioObjectPropertyElementMaster; - OSType typeId = types[index]; + OSType typeId = types[index]; - OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); - } - - juce_free (types); + OK (AudioObjectSetPropertyData (deviceID, &pa, 0, 0, sizeof (typeId), &typeId)); } } } @@ -764,7 +730,8 @@ public: && AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size) == noErr && size > 0) { - AudioDeviceID* devs = (AudioDeviceID*) juce_calloc (size); + HeapBlock devs; + devs.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, devs))) { @@ -786,8 +753,6 @@ public: } } } - - juce_free (devs); } return result; @@ -815,7 +780,7 @@ private: bool started; double sampleRate; int bufferSize; - float* audioBuffer; + HeapBlock audioBuffer; int numInputChans, numOutputChans; bool callbacksAllowed; @@ -827,10 +792,8 @@ private: }; int numInputChannelInfos, numOutputChannelInfos; - CallbackDetailsForChannel* inputChannelInfo; - CallbackDetailsForChannel* outputChannelInfo; - float** tempInputBuffers; - float** tempOutputBuffers; + HeapBlock inputChannelInfo, outputChannelInfo; + HeapBlock tempInputBuffers, tempOutputBuffers; CoreAudioInternal (const CoreAudioInternal&); const CoreAudioInternal& operator= (const CoreAudioInternal&); @@ -875,34 +838,24 @@ private: } //============================================================================== - static OSType* getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, int& num) + static int getAllDataSourcesForDevice (AudioDeviceID deviceID, const bool input, HeapBlock & types) { - OSType* types = 0; - UInt32 size = 0; - num = 0; - AudioObjectPropertyAddress pa; pa.mSelector = kAudioDevicePropertyDataSources; pa.mScope = kAudioObjectPropertyScopeWildcard; pa.mElement = kAudioObjectPropertyElementMaster; + UInt32 size = 0; if (deviceID != 0 && OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - types = (OSType*) juce_calloc (size); + types.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, types))) - { - num = size / sizeof (OSType); - } - else - { - juce_free (types); - types = 0; - } + return size / sizeof (OSType); } - return types; + return 0; } }; @@ -1193,7 +1146,8 @@ public: if (OK (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size))) { - AudioDeviceID* const devs = (AudioDeviceID*) juce_calloc (size); + HeapBlock devs; + devs.calloc (size, 1); if (OK (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, devs))) { @@ -1231,8 +1185,6 @@ public: alreadyLogged = true; } - - juce_free (devs); } inputDeviceNames.appendNumbersToDuplicates (false, true); @@ -1340,7 +1292,8 @@ private: if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) { - AudioBufferList* const bufList = (AudioBufferList*) juce_calloc (size); + HeapBlock bufList; + bufList.calloc (size, 1); if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) { @@ -1352,8 +1305,6 @@ private: total += b.mNumberChannels; } } - - juce_free (bufList); } return total; diff --git a/src/native/mac/juce_mac_CoreGraphicsContext.mm b/src/native/mac/juce_mac_CoreGraphicsContext.mm index bca8f41a77..2f42ee8e25 100644 --- a/src/native/mac/juce_mac_CoreGraphicsContext.mm +++ b/src/native/mac/juce_mac_CoreGraphicsContext.mm @@ -132,7 +132,6 @@ public: CoreGraphicsContext (CGContextRef context_, const float flipHeight_) : context (context_), flipHeight (flipHeight_), - gradientLookupTable (0), numGradientLookupEntries (0) { CGContextRetain (context); @@ -155,7 +154,6 @@ public: CGColorSpaceRelease (rgbColourSpace); CGColorSpaceRelease (greyColourSpace); delete state; - delete gradientLookupTable; } //============================================================================== @@ -183,7 +181,7 @@ public: { const int numRects = clipRegion.getNumRectangles(); - CGRect* const rects = new CGRect [numRects]; + HeapBlock rects (numRects); for (int i = 0; i < numRects; ++i) { const Rectangle& r = clipRegion.getRectangle(i); @@ -191,8 +189,6 @@ public: } CGContextClipToRects (context, rects, numRects); - delete[] rects; - return ! isClipEmpty(); } } @@ -565,7 +561,7 @@ private: SavedState* state; OwnedArray stateStack; - PixelARGB* gradientLookupTable; + HeapBlock gradientLookupTable; int numGradientLookupEntries; static void gradientCallback (void* info, const CGFloat* inData, CGFloat* outData) @@ -584,8 +580,7 @@ private: CGShadingRef createGradient (const AffineTransform& transform, ColourGradient gradient) throw() { - delete gradientLookupTable; - gradientLookupTable = gradient.createLookupTable (transform, numGradientLookupEntries); + numGradientLookupEntries = gradient.createLookupTable (transform, gradientLookupTable); --numGradientLookupEntries; CGShadingRef result = 0; diff --git a/src/native/mac/juce_mac_CoreMidi.cpp b/src/native/mac/juce_mac_CoreMidi.cpp index 805ceb4735..c32fefd444 100644 --- a/src/native/mac/juce_mac_CoreMidi.cpp +++ b/src/native/mac/juce_mac_CoreMidi.cpp @@ -334,7 +334,8 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) const int maxPacketSize = 256; int pos = 0, bytesLeft = message.getRawDataSize(); const int numPackets = (bytesLeft + maxPacketSize - 1) / maxPacketSize; - MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 * numPackets + message.getRawDataSize()); + HeapBlock packets; + packets.malloc (32 * numPackets + message.getRawDataSize(), 1); packets->numPackets = numPackets; MIDIPacket* p = packets->packet; @@ -353,8 +354,6 @@ void MidiOutput::sendMessageNow (const MidiMessage& message) MIDISend (mpe->port, mpe->endPoint, packets); else MIDIReceived (mpe->endPoint, packets); - - juce_free (packets); } else { diff --git a/src/native/mac/juce_mac_Fonts.mm b/src/native/mac/juce_mac_Fonts.mm index e5a3c0e48b..392ef4d8df 100644 --- a/src/native/mac/juce_mac_Fonts.mm +++ b/src/native/mac/juce_mac_Fonts.mm @@ -201,45 +201,38 @@ public: return 0; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); float x = 0; #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; for (int i = 0; i < length; ++i) x += advances[i].width; - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) for (int i = 0; i < length; ++i) x += advances[i]; - - juce_free (advances); } #endif - juce_free (glyphs); - return x * unitsToHeightScaleFactor; } @@ -251,10 +244,11 @@ public: return; const int length = text.length(); - CGGlyph* const glyphs = createGlyphsForString (text, length); + HeapBlock glyphs; + createGlyphsForString (text, length, glyphs); #if SUPPORT_ONLY_10_4_FONTS - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; int x = 0; @@ -265,12 +259,11 @@ public: resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - juce_free (advances); #else #if SUPPORT_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) { - NSSize* const advances = (NSSize*) juce_malloc (length * sizeof (NSSize)); + HeapBlock advances (length); [nsFont getAdvancements: advances forGlyphs: (NSGlyph*) glyphs count: length]; float x = 0; @@ -280,13 +273,11 @@ public: xOffsets.add (x * unitsToHeightScaleFactor); resultGlyphs.add (((NSGlyph*) glyphs)[i]); } - - juce_free (advances); } else #endif { - int* const advances = (int*) juce_malloc (length * sizeof (int)); + HeapBlock advances (length); if (CGFontGetGlyphAdvances (fontRef, glyphs, length, advances)) { @@ -298,12 +289,8 @@ public: resultGlyphs.add (glyphs[i]); } } - - juce_free (advances); } #endif - - juce_free (glyphs); } bool getOutlineForGlyph (int glyphNumber, Path& path) @@ -369,19 +356,20 @@ private: AffineTransform pathTransform; #endif - CGGlyph* createGlyphsForString (const juce_wchar* const text, const int length) throw() + void createGlyphsForString (const juce_wchar* const text, const int length, HeapBlock & glyphs) throw() { #if SUPPORT_10_4_FONTS #if ! SUPPORT_ONLY_10_4_FONTS if (NEW_CGFONT_FUNCTIONS_UNAVAILABLE) #endif { - NSGlyph* const g = (NSGlyph*) juce_malloc (sizeof (NSGlyph) * length); + glyphs.malloc (sizeof (NSGlyph) * length, 1); + NSGlyph* const g = (NSGlyph*) glyphs; for (int i = 0; i < length; ++i) g[i] = (NSGlyph) [nsFont _defaultGlyphForChar: text[i]]; - return (CGGlyph*) g; + return; } #endif @@ -389,12 +377,10 @@ private: if (charToGlyphMapper == 0) charToGlyphMapper = new CharToGlyphMapper (fontRef); - CGGlyph* const g = (CGGlyph*) juce_malloc (sizeof (CGGlyph) * length); + glyphs.malloc (length); for (int i = 0; i < length; ++i) - g[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); - - return g; + glyphs[i] = (CGGlyph) charToGlyphMapper->getGlyphForCharacter (text[i]); #endif } diff --git a/src/native/mac/juce_mac_Strings.mm b/src/native/mac/juce_mac_Strings.mm index 6d2716a616..bfc95d8301 100644 --- a/src/native/mac/juce_mac_Strings.mm +++ b/src/native/mac/juce_mac_Strings.mm @@ -58,20 +58,15 @@ const String PlatformUtilities::cfStringToJuceString (CFStringRef cfString) { #if JUCE_STRINGS_ARE_UNICODE CFRange range = { 0, CFStringGetLength (cfString) }; - UniChar* const u = (UniChar*) juce_malloc (sizeof (UniChar) * (range.length + 1)); - + HeapBlock u (range.length + 1); CFStringGetCharacters (cfString, range, u); u[range.length] = 0; - result = convertUTF16ToString (u); - - juce_free (u); #else const int len = CFStringGetLength (cfString); - char* buffer = (char*) juce_malloc (len + 1); + HeapBlock buffer (len + 1); CFStringGetCString (cfString, buffer, len + 1, CFStringGetSystemEncoding()); result = buffer; - juce_free (buffer); #endif } @@ -83,16 +78,12 @@ CFStringRef PlatformUtilities::juceStringToCFString (const String& s) #if JUCE_STRINGS_ARE_UNICODE const int len = s.length(); const juce_wchar* t = (const juce_wchar*) s; - - UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4); + HeapBlock temp (len + 2); for (int i = 0; i <= len; ++i) temp[i] = t[i]; - CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); - juce_free (temp); - - return result; + return CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); #else return CFStringCreateWithCString (kCFAllocatorDefault, @@ -126,8 +117,9 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) { const int len = s.length(); - UniChar* const tempIn = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); - UniChar* const tempOut = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4); + HeapBlock tempIn, tempOut; + tempIn.calloc (len + 2); + tempOut.calloc (len + 2); for (int i = 0; i <= len; ++i) tempIn[i] = s[i]; @@ -153,9 +145,6 @@ const String PlatformUtilities::convertToPrecomposedUnicode (const String& s) t[i] = 0; } - juce_free (tempIn); - juce_free (tempOut); - DisposeUnicodeToTextInfo (&conversionInfo); } diff --git a/src/native/windows/juce_win32_ASIO.cpp b/src/native/windows/juce_win32_ASIO.cpp index d15a2b27d0..3328ef850e 100644 --- a/src/native/windows/juce_win32_ASIO.cpp +++ b/src/native/windows/juce_win32_ASIO.cpp @@ -88,7 +88,6 @@ public: optionalDllForDirectLoading (optionalDllForDirectLoading_), currentBitDepth (16), currentSampleRate (0), - tempBuffer (0), isOpen_ (false), isStarted (false), postOutput (true), @@ -115,8 +114,6 @@ public: close(); log ("ASIO - exiting"); removeCurrentDriver(); - - juce_free (tempBuffer); } void updateSampleRates() @@ -451,9 +448,7 @@ public: { buffersCreated = true; - juce_free (tempBuffer); - - tempBuffer = (float*) juce_calloc (totalBuffers * currentBlockSizeSamples * sizeof (float) + 128); + tempBuffer.calloc (totalBuffers * currentBlockSizeSamples + 32); int n = 0; Array types; @@ -840,7 +835,7 @@ private: bool outputChannelLittleEndian [maxASIOChannels]; WaitableEvent event1; - float* tempBuffer; + HeapBlock tempBuffer; int volatile bufferIndex, numActiveInputChans, numActiveOutputChans; bool isOpen_, isStarted; diff --git a/src/native/windows/juce_win32_AudioCDReader.cpp b/src/native/windows/juce_win32_AudioCDReader.cpp index 949927d26c..b10ac5ce16 100644 --- a/src/native/windows/juce_win32_AudioCDReader.cpp +++ b/src/native/windows/juce_win32_AudioCDReader.cpp @@ -2328,7 +2328,7 @@ bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples) hr = info->redbook->CreateAudioTrack ((long) numSamples / (bytesPerBlock * 4)); - byte* const buffer = (byte*) juce_malloc (bytesPerBlock); + HeapBlock buffer (bytesPerBlock); AudioSampleBuffer sourceBuffer (2, samplesPerBlock); int samplesDone = 0; @@ -2366,8 +2366,6 @@ bool AudioCDBurner::addAudioTrack (AudioSource* source, int numSamples) break; } - juce_free (buffer); - hr = info->redbook->CloseAudioTrack(); delete source; diff --git a/src/native/windows/juce_win32_CameraDevice.cpp b/src/native/windows/juce_win32_CameraDevice.cpp index c84524e6e3..ee91b247ee 100644 --- a/src/native/windows/juce_win32_CameraDevice.cpp +++ b/src/native/windows/juce_win32_CameraDevice.cpp @@ -196,14 +196,14 @@ public: if (getPin (filter, PINDIR_OUTPUT, &pin)) { ComSmartPtr pushSource; - hr = pin->QueryInterface (IID_IAMPushSource, (void**) &pushSource); + HRESULT hr = pin->QueryInterface (IID_IAMPushSource, (void**) &pushSource); if (pushSource != 0) { REFERENCE_TIME latency = 0; - hr = ps->GetLatency (&latency); + hr = pushSource->GetLatency (&latency); - firstRecordedTime -= RelativeTime ((double) latency); + firstRecordedTime = firstRecordedTime - RelativeTime ((double) latency); } } } diff --git a/src/native/windows/juce_win32_DirectSound.cpp b/src/native/windows/juce_win32_DirectSound.cpp index 5bdca4eb9c..0e4a430062 100644 --- a/src/native/windows/juce_win32_DirectSound.cpp +++ b/src/native/windows/juce_win32_DirectSound.cpp @@ -1170,8 +1170,7 @@ private: int64 volatile lastBlockTime; double sampleRate; BitArray enabledInputs, enabledOutputs; - float** inputBuffers; - float** outputBuffers; + HeapBlock inputBuffers, outputBuffers; AudioIODeviceCallback* callback; CriticalSection startStopLock; @@ -1196,15 +1195,13 @@ private: for (i = 0; i < numInputBuffers; ++i) juce_free (inputBuffers[i]); - delete[] inputBuffers; - inputBuffers = 0; + inputBuffers.free(); numInputBuffers = 0; for (i = 0; i < numOutputBuffers; ++i) juce_free (outputBuffers[i]); - delete[] outputBuffers; - outputBuffers = 0; + outputBuffers.free(); numOutputBuffers = 0; } @@ -1526,8 +1523,7 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, false); numInputBuffers = enabledInputs.countNumberOfSetBits(); - inputBuffers = new float* [numInputBuffers + 2]; - zeromem (inputBuffers, sizeof (float*) * numInputBuffers + 2); + inputBuffers.calloc (numInputBuffers + 2); int i, numIns = 0; for (i = 0; i <= enabledInputs.getHighestBit(); i += 2) @@ -1554,8 +1550,7 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, false); numOutputBuffers = enabledOutputs.countNumberOfSetBits(); - outputBuffers = new float* [numOutputBuffers + 2]; - zeromem (outputBuffers, sizeof (float*) * numOutputBuffers + 2); + outputBuffers.calloc (numOutputBuffers + 2); int numOuts = 0; for (i = 0; i <= enabledOutputs.getHighestBit(); i += 2) diff --git a/src/native/windows/juce_win32_Files.cpp b/src/native/windows/juce_win32_Files.cpp index 0644f1a30e..184821cfaf 100644 --- a/src/native/windows/juce_win32_Files.cpp +++ b/src/native/windows/juce_win32_Files.cpp @@ -532,7 +532,8 @@ const String File::getVersion() const throw() DWORD handle = 0; DWORD bufferSize = GetFileVersionInfoSize (getFullPathName(), &handle); - void* buffer = juce_calloc (bufferSize); + HeapBlock buffer; + buffer.calloc (bufferSize); if (GetFileVersionInfo (getFullPathName(), 0, bufferSize, buffer)) { @@ -549,7 +550,6 @@ const String File::getVersion() const throw() } } - juce_free (buffer); return result; } diff --git a/src/native/windows/juce_win32_Fonts.cpp b/src/native/windows/juce_win32_Fonts.cpp index c2406f686d..92ba3818ae 100644 --- a/src/native/windows/juce_win32_Fonts.cpp +++ b/src/native/windows/juce_win32_Fonts.cpp @@ -128,7 +128,7 @@ class FontDCHolder : private DeletedAtShutdown public: //============================================================================== FontDCHolder() throw() - : dc (0), kps (0), numKPs (0), size (0), + : dc (0), numKPs (0), size (0), bold (false), italic (false) { } @@ -139,7 +139,6 @@ public: { DeleteDC (dc); DeleteObject (fontH); - juce_free (kps); } clearSingletonInstance(); @@ -161,8 +160,7 @@ public: { DeleteDC (dc); DeleteObject (fontH); - juce_free (kps); - kps = 0; + kps.free(); } fontH = 0; @@ -225,7 +223,7 @@ public: if (kps == 0) { numKPs = GetKerningPairs (dc, 0, 0); - kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs); + kps.calloc (numKPs); GetKerningPairs (dc, numKPs, kps); } @@ -239,7 +237,7 @@ private: HFONT fontH; HDC dc; String fontName; - KERNINGPAIR* kps; + HeapBlock kps; int numKPs, size; bool bold, italic; @@ -304,7 +302,7 @@ public: if (bufSize > 0) { - char* const data = (char*) juce_malloc (bufSize); + HeapBlock data (bufSize); GetGlyphOutline (dc, character, GGO_NATIVE, &gm, bufSize, data, &identityMatrix); @@ -372,8 +370,6 @@ public: glyphPath.closeSubPath(); } - - juce_free (data); } addGlyph (character, glyphPath, gm.gmCellIncX / height); diff --git a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp index ba5bf4b434..d979df1bf9 100644 --- a/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp +++ b/src/native/windows/juce_win32_QuickTimeMovieComponent.cpp @@ -346,15 +346,11 @@ static CFStringRef juceStringToCFString (const String& s) const int len = s.length(); const juce_wchar* const t = (const juce_wchar*) s; - UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4); - + HeapBlock temp (len + 2); for (int i = 0; i <= len; ++i) temp[i] = t[i]; - CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); - juce_free (temp); - - return result; + return CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len); } static bool openMovie (QTNewMoviePropertyElement* props, int prop, Movie& movie) diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index 0a8be4c405..7b0c37acdd 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -211,7 +211,6 @@ public: { DeleteDC (hdc); DeleteObject (hBitmap); - imageData = 0; // to stop the base class freeing this } void blitToWindow (HWND hwnd, HDC dc, const bool transparent, @@ -1814,415 +1813,415 @@ public: private: LRESULT peerWindowProc (HWND h, UINT message, WPARAM wParam, LPARAM lParam) { + if (isValidPeer (this)) { - if (isValidPeer (this)) + switch (message) { - switch (message) - { - case WM_NCHITTEST: - if (hasTitleBar()) - break; + //============================================================================== + case WM_NCHITTEST: + if ((styleFlags & windowIgnoresMouseClicks) != 0) + return HTTRANSPARENT; - return HTCLIENT; + if (hasTitleBar()) + break; - //============================================================================== - case WM_PAINT: + return HTCLIENT; + + //============================================================================== + case WM_PAINT: + handlePaintMessage(); + return 0; + + case WM_NCPAINT: + if (wParam != 1) handlePaintMessage(); - return 0; - case WM_NCPAINT: - if (wParam != 1) - handlePaintMessage(); + if (hasTitleBar()) + break; - if (hasTitleBar()) - break; + return 0; - return 0; + case WM_ERASEBKGND: + case WM_NCCALCSIZE: + if (hasTitleBar()) + break; - case WM_ERASEBKGND: - case WM_NCCALCSIZE: - if (hasTitleBar()) - break; + return 1; - return 1; + //============================================================================== + case WM_MOUSEMOVE: + doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); + return 0; - //============================================================================== - case WM_MOUSEMOVE: - doMouseMove (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam)); - return 0; + case WM_MOUSELEAVE: + doMouseExit(); + return 0; - case WM_MOUSELEAVE: - doMouseExit(); - return 0; + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); + return 0; - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - doMouseDown (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); - return 0; + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); + return 0; - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - doMouseUp (GET_X_LPARAM (lParam), GET_Y_LPARAM (lParam), wParam); - return 0; + case WM_CAPTURECHANGED: + doCaptureChanged(); + return 0; - case WM_CAPTURECHANGED: - doCaptureChanged(); - return 0; + case WM_NCMOUSEMOVE: + if (hasTitleBar()) + break; - case WM_NCMOUSEMOVE: - if (hasTitleBar()) - break; + return 0; - return 0; + case 0x020A: /* WM_MOUSEWHEEL */ + doMouseWheel (wParam, true); + return 0; - case 0x020A: /* WM_MOUSEWHEEL */ - doMouseWheel (wParam, true); - return 0; + case 0x020E: /* WM_MOUSEHWHEEL */ + doMouseWheel (wParam, false); + return 0; - case 0x020E: /* WM_MOUSEHWHEEL */ - doMouseWheel (wParam, false); - return 0; + //============================================================================== + case WM_WINDOWPOSCHANGING: + if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + { + WINDOWPOS* const wp = (WINDOWPOS*) lParam; - //============================================================================== - case WM_WINDOWPOSCHANGING: - if ((styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable)) + if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) { - WINDOWPOS* const wp = (WINDOWPOS*) lParam; - - if ((wp->flags & (SWP_NOMOVE | SWP_NOSIZE)) != (SWP_NOMOVE | SWP_NOSIZE)) + if (constrainer != 0) { - if (constrainer != 0) - { - const Rectangle current (component->getX() - windowBorder.getLeft(), - component->getY() - windowBorder.getTop(), - component->getWidth() + windowBorder.getLeftAndRight(), - component->getHeight() + windowBorder.getTopAndBottom()); + const Rectangle current (component->getX() - windowBorder.getLeft(), + component->getY() - windowBorder.getTop(), + component->getWidth() + windowBorder.getLeftAndRight(), + component->getHeight() + windowBorder.getTopAndBottom()); - constrainer->checkBounds (wp->x, wp->y, wp->cx, wp->cy, - current, - Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), - wp->y != current.getY() && wp->y + wp->cy == current.getBottom(), - wp->x != current.getX() && wp->x + wp->cx == current.getRight(), - wp->y == current.getY() && wp->y + wp->cy != current.getBottom(), - wp->x == current.getX() && wp->x + wp->cx != current.getRight()); - } + constrainer->checkBounds (wp->x, wp->y, wp->cx, wp->cy, + current, + Desktop::getInstance().getAllMonitorDisplayAreas().getBounds(), + wp->y != current.getY() && wp->y + wp->cy == current.getBottom(), + wp->x != current.getX() && wp->x + wp->cx == current.getRight(), + wp->y == current.getY() && wp->y + wp->cy != current.getBottom(), + wp->x == current.getX() && wp->x + wp->cx != current.getRight()); } } + } + return 0; + + case WM_WINDOWPOSCHANGED: + handleMovedOrResized(); + + if (dontRepaint) + break; // needed for non-accelerated openGL windows to draw themselves correctly.. + + return 0; + + //============================================================================== + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (doKeyDown (wParam)) return 0; - case WM_WINDOWPOSCHANGED: - handleMovedOrResized(); + break; - if (dontRepaint) - break; // needed for non-accelerated openGL windows to draw themselves correctly.. - else - return 0; - - //============================================================================== - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if (doKeyDown (wParam)) - return 0; - - break; - - case WM_KEYUP: - case WM_SYSKEYUP: - if (doKeyUp (wParam)) - return 0; - - break; - - case WM_CHAR: - if (doKeyChar ((int) wParam, lParam)) - return 0; - - break; - - case WM_APPCOMMAND: - if (doAppCommand (lParam)) - return TRUE; - - break; - - //============================================================================== - case WM_SETFOCUS: - updateKeyModifiers(); - handleFocusGain(); - break; - - case WM_KILLFOCUS: - if (hasCreatedCaret) - { - hasCreatedCaret = false; - DestroyCaret(); - } - - handleFocusLoss(); - break; - - case WM_ACTIVATEAPP: - // Windows does weird things to process priority when you swap apps, - // so this forces an update when the app is brought to the front - if (wParam != FALSE) - juce_repeatLastProcessPriority(); - else - Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus - - juce_CheckCurrentlyFocusedTopLevelWindow(); - modifiersAtLastCallback = -1; + case WM_KEYUP: + case WM_SYSKEYUP: + if (doKeyUp (wParam)) return 0; - case WM_ACTIVATE: - if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE) - { - modifiersAtLastCallback = -1; - updateKeyModifiers(); - - if (isMinimised()) - { - component->repaint(); - handleMovedOrResized(); - - if (! isValidMessageListener()) - return 0; - } - - if (LOWORD (wParam) == WA_CLICKACTIVE - && component->isCurrentlyBlockedByAnotherModalComponent()) - { - int mx, my; - component->getMouseXYRelative (mx, my); - Component* const underMouse = component->getComponentAt (mx, my); - - if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent()) - Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); - - return 0; - } - - handleBroughtToFront(); - - if (component->isCurrentlyBlockedByAnotherModalComponent()) - Component::getCurrentlyModalComponent()->toFront (true); - - return 0; - } - - break; - - case WM_NCACTIVATE: - // while a temporary window is being shown, prevent Windows from deactivating the - // title bars of our main windows. - if (wParam == 0 && ! shouldDeactivateTitleBar) - wParam = TRUE; // change this and let it get passed to the DefWindowProc. - - break; - - case WM_MOUSEACTIVATE: - if (! component->getMouseClickGrabsKeyboardFocus()) - return MA_NOACTIVATE; - - break; - - case WM_SHOWWINDOW: - if (wParam != 0) - handleBroughtToFront(); - - break; - - case WM_CLOSE: - if (! component->isCurrentlyBlockedByAnotherModalComponent()) - handleUserClosingWindow(); + break; + case WM_CHAR: + if (doKeyChar ((int) wParam, lParam)) return 0; - case WM_QUIT: - if (JUCEApplication::getInstance() != 0) - JUCEApplication::getInstance()->systemRequestedQuit(); - return 0; + break; - case WM_QUERYENDSESSION: - if (JUCEApplication::getInstance() != 0) - { - JUCEApplication::getInstance()->systemRequestedQuit(); - return MessageManager::getInstance()->hasStopMessageBeenSent(); - } + case WM_APPCOMMAND: + if (doAppCommand (lParam)) return TRUE; - //============================================================================== - case WM_TRAYNOTIFY: + break; + + //============================================================================== + case WM_SETFOCUS: + updateKeyModifiers(); + handleFocusGain(); + break; + + case WM_KILLFOCUS: + if (hasCreatedCaret) + { + hasCreatedCaret = false; + DestroyCaret(); + } + + handleFocusLoss(); + break; + + case WM_ACTIVATEAPP: + // Windows does weird things to process priority when you swap apps, + // so this forces an update when the app is brought to the front + if (wParam != FALSE) + juce_repeatLastProcessPriority(); + else + Desktop::getInstance().setKioskModeComponent (0); // turn kiosk mode off if we lose focus + + juce_CheckCurrentlyFocusedTopLevelWindow(); + modifiersAtLastCallback = -1; + return 0; + + case WM_ACTIVATE: + if (LOWORD (wParam) == WA_ACTIVE || LOWORD (wParam) == WA_CLICKACTIVE) + { + modifiersAtLastCallback = -1; + updateKeyModifiers(); + + if (isMinimised()) + { + component->repaint(); + handleMovedOrResized(); + + if (! isValidMessageListener()) + return 0; + } + + if (LOWORD (wParam) == WA_CLICKACTIVE + && component->isCurrentlyBlockedByAnotherModalComponent()) + { + int mx, my; + component->getMouseXYRelative (mx, my); + Component* const underMouse = component->getComponentAt (mx, my); + + if (underMouse != 0 && underMouse->isCurrentlyBlockedByAnotherModalComponent()) + Component::getCurrentlyModalComponent()->inputAttemptWhenModal(); + + return 0; + } + + handleBroughtToFront(); + if (component->isCurrentlyBlockedByAnotherModalComponent()) + Component::getCurrentlyModalComponent()->toFront (true); + + return 0; + } + + break; + + case WM_NCACTIVATE: + // while a temporary window is being shown, prevent Windows from deactivating the + // title bars of our main windows. + if (wParam == 0 && ! shouldDeactivateTitleBar) + wParam = TRUE; // change this and let it get passed to the DefWindowProc. + + break; + + case WM_MOUSEACTIVATE: + if (! component->getMouseClickGrabsKeyboardFocus()) + return MA_NOACTIVATE; + + break; + + case WM_SHOWWINDOW: + if (wParam != 0) + handleBroughtToFront(); + + break; + + case WM_CLOSE: + if (! component->isCurrentlyBlockedByAnotherModalComponent()) + handleUserClosingWindow(); + + return 0; + + case WM_QUIT: + if (JUCEApplication::getInstance() != 0) + JUCEApplication::getInstance()->systemRequestedQuit(); + return 0; + + case WM_QUERYENDSESSION: + if (JUCEApplication::getInstance() != 0) + { + JUCEApplication::getInstance()->systemRequestedQuit(); + return MessageManager::getInstance()->hasStopMessageBeenSent(); + } + return TRUE; + + //============================================================================== + case WM_TRAYNOTIFY: + if (component->isCurrentlyBlockedByAnotherModalComponent()) + { + if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN + || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) { - if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN - || lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) - { - Component* const current = Component::getCurrentlyModalComponent(); + Component* const current = Component::getCurrentlyModalComponent(); - if (current != 0) - current->inputAttemptWhenModal(); - } + if (current != 0) + current->inputAttemptWhenModal(); } - else + } + else + { + const int oldModifiers = currentModifiers; + + MouseEvent e (0, 0, ModifierKeys::getCurrentModifiersRealtime(), component, + getMouseEventTime(), 0, 0, getMouseEventTime(), 1, false); + + if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) + e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); + else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) + e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier); + + if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) { - const int oldModifiers = currentModifiers; + SetFocus (hwnd); + SetForegroundWindow (hwnd); - MouseEvent e (0, 0, ModifierKeys::getCurrentModifiersRealtime(), component, - getMouseEventTime(), 0, 0, getMouseEventTime(), 1, false); - - if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) - e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::leftButtonModifier); - else if (lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) - e.mods = ModifierKeys (e.mods.getRawFlags() | ModifierKeys::rightButtonModifier); - - if (lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN) - { - SetFocus (hwnd); - SetForegroundWindow (hwnd); - - component->mouseDown (e); - } - else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) - { - e.mods = ModifierKeys (oldModifiers); - component->mouseUp (e); - } - else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) - { - e.mods = ModifierKeys (oldModifiers); - component->mouseDoubleClick (e); - } - else if (lParam == WM_MOUSEMOVE) - { - component->mouseMove (e); - } + component->mouseDown (e); } + else if (lParam == WM_LBUTTONUP || lParam == WM_RBUTTONUP) + { + e.mods = ModifierKeys (oldModifiers); + component->mouseUp (e); + } + else if (lParam == WM_LBUTTONDBLCLK || lParam == WM_LBUTTONDBLCLK) + { + e.mods = ModifierKeys (oldModifiers); + component->mouseDoubleClick (e); + } + else if (lParam == WM_MOUSEMOVE) + { + component->mouseMove (e); + } + } + + break; + + //============================================================================== + case WM_SYNCPAINT: + return 0; + + case WM_PALETTECHANGED: + InvalidateRect (h, 0, 0); + break; + + case WM_DISPLAYCHANGE: + InvalidateRect (h, 0, 0); + createPaletteIfNeeded = true; + // intentional fall-through... + case WM_SETTINGCHANGE: // note the fall-through in the previous case! + doSettingChange(); + break; + + case WM_INITMENU: + if (! hasTitleBar()) + { + if (isFullScreen()) + { + EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); + } + else if (! isMinimised()) + { + EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + } + } + break; + + case WM_SYSCOMMAND: + switch (wParam & 0xfff0) + { + case SC_CLOSE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + if (hasTitleBar()) + { + PostMessage (h, WM_CLOSE, 0, 0); + return 0; + } + break; + + case SC_KEYMENU: + // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very + // obscure situations that can arise if a modal loop is started from an alt-key + // keypress). + + if (hasTitleBar() && h == GetCapture()) + ReleaseCapture(); break; - //============================================================================== - case WM_SYNCPAINT: + case SC_MAXIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + setFullScreen (true); return 0; - case WM_PALETTECHANGED: - InvalidateRect (h, 0, 0); - break; + case SC_MINIMIZE: + if (sendInputAttemptWhenModalMessage()) + return 0; - case WM_DISPLAYCHANGE: - InvalidateRect (h, 0, 0); - createPaletteIfNeeded = true; - // intentional fall-through... - case WM_SETTINGCHANGE: // note the fall-through in the previous case! - doSettingChange(); - break; - - case WM_INITMENU: if (! hasTitleBar()) + { + setMinimised (true); + return 0; + } + break; + + case SC_RESTORE: + if (sendInputAttemptWhenModalMessage()) + return 0; + + if (hasTitleBar()) { if (isFullScreen()) { - EnableMenuItem ((HMENU) wParam, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem ((HMENU) wParam, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); - } - else if (! isMinimised()) - { - EnableMenuItem ((HMENU) wParam, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + setFullScreen (false); + return 0; } } - break; - - case WM_SYSCOMMAND: - switch (wParam & 0xfff0) + else { - case SC_CLOSE: - if (sendInputAttemptWhenModalMessage()) - return 0; + if (isMinimised()) + setMinimised (false); + else if (isFullScreen()) + setFullScreen (false); - if (hasTitleBar()) - { - PostMessage (h, WM_CLOSE, 0, 0); - return 0; - } - break; - - case SC_KEYMENU: - // (NB mustn't call sendInputAttemptWhenModalMessage() here because of very - // obscure situations that can arise if a modal loop is started from an alt-key - // keypress). - - if (hasTitleBar() && h == GetCapture()) - ReleaseCapture(); - - break; - - case SC_MAXIMIZE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - setFullScreen (true); return 0; - - case SC_MINIMIZE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - if (! hasTitleBar()) - { - setMinimised (true); - return 0; - } - break; - - case SC_RESTORE: - if (sendInputAttemptWhenModalMessage()) - return 0; - - if (hasTitleBar()) - { - if (isFullScreen()) - { - setFullScreen (false); - return 0; - } - } - else - { - if (isMinimised()) - setMinimised (false); - else if (isFullScreen()) - setFullScreen (false); - - return 0; - } - - break; } break; + } - case WM_NCLBUTTONDOWN: - case WM_NCRBUTTONDOWN: - case WM_NCMBUTTONDOWN: - sendInputAttemptWhenModalMessage(); - break; + break; - //case WM_IME_STARTCOMPOSITION; - // return 0; + case WM_NCLBUTTONDOWN: + case WM_NCRBUTTONDOWN: + case WM_NCMBUTTONDOWN: + sendInputAttemptWhenModalMessage(); + break; - case WM_GETDLGCODE: - return DLGC_WANTALLKEYS; + //case WM_IME_STARTCOMPOSITION; + // return 0; - default: - break; - } + case WM_GETDLGCODE: + return DLGC_WANTALLKEYS; + + default: + break; } } - // (the message manager lock exits before calling this, to avoid deadlocks if - // this calls into non-juce windows) return DefWindowProc (h, message, wParam, lParam); } @@ -2635,8 +2634,9 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot else { const int stride = (maxW + 7) >> 3; - uint8* const andPlane = (uint8*) juce_calloc (stride * maxH); - uint8* const xorPlane = (uint8*) juce_calloc (stride * maxH); + HeapBlock andPlane, xorPlane; + andPlane.calloc (stride * maxH); + xorPlane.calloc (stride * maxH); int index = 0; for (int y = 0; y < maxH; ++y) @@ -2657,9 +2657,6 @@ void* juce_createMouseCursorFromImage (const Image& image, int hotspotX, int hot } cursorH = CreateCursor (0, hotspotX, hotspotY, maxW, maxH, andPlane, xorPlane); - - juce_free (andPlane); - juce_free (xorPlane); } delete newIm; diff --git a/src/text/juce_StringArray.cpp b/src/text/juce_StringArray.cpp index b6d4810066..4b8ae6ddbb 100644 --- a/src/text/juce_StringArray.cpp +++ b/src/text/juce_StringArray.cpp @@ -93,13 +93,8 @@ bool StringArray::operator== (const StringArray& other) const throw() return false; for (int i = size(); --i >= 0;) - { - if (*(String*) other.strings.getUnchecked(i) - != *(String*) strings.getUnchecked(i)) - { + if (*other.strings.getUnchecked(i) != *strings.getUnchecked(i)) return false; - } - } return true; } @@ -111,19 +106,13 @@ bool StringArray::operator!= (const StringArray& other) const throw() void StringArray::clear() throw() { - for (int i = size(); --i >= 0;) - { - String* const s = (String*) strings.getUnchecked(i); - delete s; - } - strings.clear(); } const String& StringArray::operator[] (const int index) const throw() { if (((unsigned int) index) < (unsigned int) strings.size()) - return *(const String*) (strings.getUnchecked (index)); + return *strings.getUnchecked (index); return String::empty; } @@ -160,22 +149,18 @@ void StringArray::addArray (const StringArray& otherArray, numElementsToAdd = otherArray.size() - startIndex; while (--numElementsToAdd >= 0) - strings.add (new String (*(const String*) otherArray.strings.getUnchecked (startIndex++))); + strings.add (new String (*otherArray.strings.getUnchecked (startIndex++))); } void StringArray::set (const int index, const String& newString) throw() { - String* const s = (String*) strings [index]; + String* const s = strings [index]; if (s != 0) - { *s = newString; - } else if (index >= 0) - { add (newString); - } } bool StringArray::contains (const String& stringToLookFor, @@ -184,13 +169,13 @@ bool StringArray::contains (const String& stringToLookFor, if (ignoreCase) { for (int i = size(); --i >= 0;) - if (stringToLookFor.equalsIgnoreCase (*(const String*)(strings.getUnchecked(i)))) + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToLookFor)) return true; } else { for (int i = size(); --i >= 0;) - if (stringToLookFor == *(const String*)(strings.getUnchecked(i))) + if (stringToLookFor == *strings.getUnchecked(i)) return true; } @@ -210,7 +195,7 @@ int StringArray::indexOf (const String& stringToLookFor, { while (i < numElements) { - if (stringToLookFor.equalsIgnoreCase (*(const String*) strings.getUnchecked (i))) + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToLookFor)) return i; ++i; @@ -220,7 +205,7 @@ int StringArray::indexOf (const String& stringToLookFor, { while (i < numElements) { - if (stringToLookFor == *(const String*) strings.getUnchecked (i)) + if (stringToLookFor == *strings.getUnchecked (i)) return i; ++i; @@ -233,13 +218,7 @@ int StringArray::indexOf (const String& stringToLookFor, //============================================================================== void StringArray::remove (const int index) throw() { - String* const s = (String*) strings [index]; - - if (s != 0) - { - strings.remove (index); - delete s; - } + strings.remove (index); } void StringArray::removeString (const String& stringToRemove, @@ -248,14 +227,14 @@ void StringArray::removeString (const String& stringToRemove, if (ignoreCase) { for (int i = size(); --i >= 0;) - if (stringToRemove.equalsIgnoreCase (*(const String*) strings.getUnchecked (i))) - remove (i); + if (strings.getUnchecked(i)->equalsIgnoreCase (stringToRemove)) + strings.remove (i); } else { for (int i = size(); --i >= 0;) - if (stringToRemove == *(const String*) strings.getUnchecked (i)) - remove (i); + if (stringToRemove == *strings.getUnchecked (i)) + strings.remove (i); } } @@ -265,14 +244,14 @@ void StringArray::removeEmptyStrings (const bool removeWhitespaceStrings) throw( if (removeWhitespaceStrings) { for (int i = size(); --i >= 0;) - if (! ((const String*) strings.getUnchecked(i))->containsNonWhitespaceChars()) - remove (i); + if (! strings.getUnchecked(i)->containsNonWhitespaceChars()) + strings.remove (i); } else { for (int i = size(); --i >= 0;) - if (((const String*) strings.getUnchecked(i))->isEmpty()) - remove (i); + if (strings.getUnchecked(i)->isEmpty()) + strings.remove (i); } } @@ -280,7 +259,7 @@ void StringArray::trim() throw() { for (int i = size(); --i >= 0;) { - String& s = *(String*) strings.getUnchecked(i); + String& s = *strings.getUnchecked(i); s = s.trim(); } } @@ -339,13 +318,13 @@ const String StringArray::joinIntoString (const String& separator, return String::empty; if (start == last - 1) - return *(const String*) strings.getUnchecked (start); + return *strings.getUnchecked (start); const int separatorLen = separator.length(); int charsNeeded = separatorLen * (last - start - 1); for (int i = start; i < last; ++i) - charsNeeded += ((const String*) strings.getUnchecked(i))->length(); + charsNeeded += strings.getUnchecked(i)->length(); String result; result.preallocateStorage (charsNeeded); @@ -354,7 +333,7 @@ const String StringArray::joinIntoString (const String& separator, while (start < last) { - const String& s = *(const String*) strings.getUnchecked (start); + const String& s = *strings.getUnchecked (start); const int len = s.length(); if (len > 0) @@ -520,7 +499,7 @@ void StringArray::removeDuplicates (const bool ignoreCase) throw() { for (int i = 0; i < size() - 1; ++i) { - const String& s = *(String*) strings.getUnchecked(i); + const String& s = *strings.getUnchecked(i); int nextIndex = i + 1; @@ -531,7 +510,7 @@ void StringArray::removeDuplicates (const bool ignoreCase) throw() if (nextIndex < 0) break; - remove (nextIndex); + strings.remove (nextIndex); } } } @@ -543,7 +522,7 @@ void StringArray::appendNumbersToDuplicates (const bool ignoreCase, { for (int i = 0; i < size() - 1; ++i) { - String& s = *(String*) strings.getUnchecked(i); + String& s = *strings.getUnchecked(i); int nextIndex = indexOf (s, ignoreCase, i + 1); diff --git a/src/text/juce_StringArray.h b/src/text/juce_StringArray.h index 631c80c7d7..191e7f938c 100644 --- a/src/text/juce_StringArray.h +++ b/src/text/juce_StringArray.h @@ -27,7 +27,7 @@ #define __JUCE_STRINGARRAY_JUCEHEADER__ #include "juce_String.h" -#include "../containers/juce_VoidArray.h" +#include "../containers/juce_OwnedArray.h" #ifndef DOXYGEN // (used in StringArray::appendNumbersToDuplicates) @@ -325,7 +325,7 @@ public: juce_UseDebuggingNewOperator private: - VoidArray strings; + OwnedArray strings; }; diff --git a/src/text/juce_XmlElement.cpp b/src/text/juce_XmlElement.cpp index 7456d737d6..5e24e4fb80 100644 --- a/src/text/juce_XmlElement.cpp +++ b/src/text/juce_XmlElement.cpp @@ -1073,20 +1073,15 @@ XmlElement* XmlElement::findParentElementOf (const XmlElement* const elementToLo return 0; } -XmlElement** XmlElement::getChildElementsAsArray (const int num) const throw() +void XmlElement::getChildElementsAsArray (XmlElement** elems) const throw() { - XmlElement** const elems = new XmlElement* [num]; - XmlElement* e = firstChildElement; - int i = 0; while (e != 0) { - elems [i++] = e; + *elems++ = e; e = e->nextElement; } - - return elems; } void XmlElement::reorderChildElements (XmlElement** const elems, const int num) throw() diff --git a/src/text/juce_XmlElement.h b/src/text/juce_XmlElement.h index 62e9f52374..6c31aa63a1 100644 --- a/src/text/juce_XmlElement.h +++ b/src/text/juce_XmlElement.h @@ -594,10 +594,10 @@ public: if (num > 1) { - XmlElement** const elems = getChildElementsAsArray (num); - sortArray (comparator, elems, 0, num - 1, retainOrderOfEquivalentItems); + HeapBlock elems (num); + getChildElementsAsArray (elems); + sortArray (comparator, (XmlElement**) elems, 0, num - 1, retainOrderOfEquivalentItems); reorderChildElements (elems, num); - delete[] elems; } } @@ -706,7 +706,7 @@ private: const int indentationLevel, const int lineWrapLength) const throw(); - XmlElement** getChildElementsAsArray (const int) const throw(); + void getChildElementsAsArray (XmlElement**) const throw(); void reorderChildElements (XmlElement** const, const int) throw(); }; diff --git a/src/threads/juce_ThreadPool.cpp b/src/threads/juce_ThreadPool.cpp index b18e4bd6c7..39ab22c883 100644 --- a/src/threads/juce_ThreadPool.cpp +++ b/src/threads/juce_ThreadPool.cpp @@ -106,7 +106,7 @@ ThreadPool::ThreadPool (const int numThreads_, { jassert (numThreads_ > 0); // not much point having one of these with no threads in it. - threads = (Thread**) juce_calloc (sizeof (Thread*) * numThreads); + threads.calloc (numThreads); for (int i = numThreads; --i >= 0;) threads[i] = new ThreadPoolThread (*this); @@ -129,8 +129,6 @@ ThreadPool::~ThreadPool() threads[i]->stopThread (500); delete threads[i]; } - - juce_free (threads); } void ThreadPool::addJob (ThreadPoolJob* const job) diff --git a/src/threads/juce_ThreadPool.h b/src/threads/juce_ThreadPool.h index bc81cfbd6e..bf421e0b8a 100644 --- a/src/threads/juce_ThreadPool.h +++ b/src/threads/juce_ThreadPool.h @@ -30,6 +30,7 @@ #include "juce_ScopedLock.h" #include "../text/juce_StringArray.h" #include "../containers/juce_VoidArray.h" +#include "../containers/juce_HeapBlock.h" class ThreadPool; class ThreadPoolThread; @@ -299,7 +300,7 @@ public: private: const int numThreads, threadStopTimeout; int priority; - Thread** threads; + HeapBlock threads; VoidArray jobs; CriticalSection lock; diff --git a/src/utilities/juce_UndoManager.h b/src/utilities/juce_UndoManager.h index 45739ae085..62743274cc 100644 --- a/src/utilities/juce_UndoManager.h +++ b/src/utilities/juce_UndoManager.h @@ -28,6 +28,7 @@ #include "../text/juce_String.h" #include "../containers/juce_OwnedArray.h" +#include "../containers/juce_Array.h" #include "../text/juce_StringArray.h" #include "../events/juce_ChangeBroadcaster.h" #include "juce_UndoableAction.h"