| @@ -7,6 +7,8 @@ | |||
| objects = { | |||
| /* Begin PBXBuildFile section */ | |||
| 84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */; }; | |||
| 84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */; }; | |||
| 84052DE408D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */; }; | |||
| 84052DE508D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */; }; | |||
| 8406AA5A0C4BDF90003A0D6A /* juce_MidiOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */; }; | |||
| @@ -691,6 +693,8 @@ | |||
| /* End PBXBuildFile section */ | |||
| /* Begin PBXFileReference section */ | |||
| 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = juce_mac_AudioCDBurner.cpp; sourceTree = "<group>"; }; | |||
| 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = juce_mac_HTTPStream.h; sourceTree = "<group>"; }; | |||
| 84052DE208D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_ToneGeneratorAudioSource.cpp; sourceTree = "<group>"; }; | |||
| 84052DE308D095D200BEC0F0 /* juce_ToneGeneratorAudioSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = juce_ToneGeneratorAudioSource.h; sourceTree = "<group>"; }; | |||
| 8406AA590C4BDF90003A0D6A /* juce_MidiOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = juce_MidiOutput.cpp; sourceTree = "<group>"; }; | |||
| @@ -1538,10 +1542,12 @@ | |||
| 84A4881C08A22E2400752A2B /* mac specific code */ = { | |||
| isa = PBXGroup; | |||
| children = ( | |||
| 84022DFA0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp */, | |||
| 84A4881E08A22E2400752A2B /* juce_mac_CoreAudio.cpp */, | |||
| 84A4881F08A22E2400752A2B /* juce_mac_CoreMidi.cpp */, | |||
| 84A4882008A22E2400752A2B /* juce_mac_FileChooser.cpp */, | |||
| 84A4882108A22E2400752A2B /* juce_mac_Files.cpp */, | |||
| 84022DFB0DAE4CB9004CF59A /* juce_mac_HTTPStream.h */, | |||
| 84A06BE209CADB06006A43BD /* juce_mac_NamedPipe.cpp */, | |||
| 84A4882208A22E2400752A2B /* juce_mac_Fonts.cpp */, | |||
| 84A4882308A22E2400752A2B /* juce_mac_Messaging.cpp */, | |||
| @@ -2897,6 +2903,7 @@ | |||
| 8495BB950D806BDA001D9C0B /* juce_FileInputSource.h in Headers */, | |||
| 8495BB960D806BDA001D9C0B /* juce_InputSource.h in Headers */, | |||
| 84581EEB0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.h in Headers */, | |||
| 84022DFD0DAE4CB9004CF59A /* juce_mac_HTTPStream.h in Headers */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -3312,6 +3319,7 @@ | |||
| 8495BB8E0D8067B2001D9C0B /* juce_AudioThumbnailCache.cpp in Sources */, | |||
| 8495BB940D806BDA001D9C0B /* juce_FileInputSource.cpp in Sources */, | |||
| 84581EEA0D9148C500AE1A4C /* juce_QuickTimeAudioFormat.cpp in Sources */, | |||
| 84022DFC0DAE4CB9004CF59A /* juce_mac_AudioCDBurner.cpp in Sources */, | |||
| ); | |||
| runOnlyForDeploymentPostprocessing = 0; | |||
| }; | |||
| @@ -1,4 +1,4 @@ | |||
| ARCHS = ppc i386 | |||
| ARCHS = i386 | |||
| // For 10.2 (and later) compatibility, use these values: | |||
| //GCC_VERSION_ppc = 3.3 | |||
| @@ -8,10 +8,10 @@ ARCHS = ppc i386 | |||
| //SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.2.8.sdk | |||
| // For 10.3 (and later) compatibility, use these instead: | |||
| MACOSX_DEPLOYMENT_TARGET = 10.4 | |||
| MACOSX_DEPLOYMENT_TARGET_ppc = 10.3 | |||
| SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.4u.sdk | |||
| SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk | |||
| MACOSX_DEPLOYMENT_TARGET = 10.5 | |||
| // MACOSX_DEPLOYMENT_TARGET_ppc = 10.3 | |||
| SDKROOT = $(DEVELOPER_SDK_DIR)/MacOSX10.5.sdk | |||
| // SDKROOT_ppc = $(DEVELOPER_SDK_DIR)/MacOSX10.3.9.sdk | |||
| // For 10.4 (and later) compatibility, use these instead: | |||
| // MACOSX_DEPLOYMENT_TARGET = 10.4 | |||
| @@ -0,0 +1,88 @@ | |||
| /* | |||
| ============================================================================== | |||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||
| Copyright 2004-7 by Raw Material Software ltd. | |||
| ------------------------------------------------------------------------------ | |||
| JUCE can be redistributed and/or modified under the terms of the | |||
| GNU General Public License, as published by the Free Software Foundation; | |||
| either version 2 of the License, or (at your option) any later version. | |||
| 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. | |||
| You should have received a copy of the GNU General Public License | |||
| along with JUCE; if not, visit www.gnu.org/licenses or write to the | |||
| Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |||
| Boston, MA 02111-1307 USA | |||
| ------------------------------------------------------------------------------ | |||
| If you'd like to release a closed-source product which uses JUCE, commercial | |||
| licenses are also available: visit www.rawmaterialsoftware.com/juce for | |||
| more information. | |||
| ============================================================================== | |||
| */ | |||
| #include "../../../src/juce_core/basics/juce_StandardHeader.h" | |||
| #include <Carbon/Carbon.h> | |||
| BEGIN_JUCE_NAMESPACE | |||
| #include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDBurner.h" | |||
| //============================================================================== | |||
| AudioCDBurner::AudioCDBurner (const int deviceIndex) | |||
| : internal (0) | |||
| { | |||
| } | |||
| AudioCDBurner::~AudioCDBurner() | |||
| { | |||
| } | |||
| AudioCDBurner* AudioCDBurner::openDevice (const int deviceIndex) | |||
| { | |||
| return 0; | |||
| } | |||
| const StringArray AudioCDBurner::findAvailableDevices() | |||
| { | |||
| StringArray s; | |||
| return s; | |||
| } | |||
| bool AudioCDBurner::isDiskPresent() const | |||
| { | |||
| return false; | |||
| } | |||
| int AudioCDBurner::getNumAvailableAudioBlocks() const | |||
| { | |||
| return 0; | |||
| } | |||
| bool AudioCDBurner::addAudioTrack (AudioFormatReader& source, int numSamples) | |||
| { | |||
| return false; | |||
| } | |||
| bool AudioCDBurner::addAudioTrack (AudioSource& source, int numSamples) | |||
| { | |||
| return false; | |||
| } | |||
| const String AudioCDBurner::burn (BurnProgressListener* listener, | |||
| const bool ejectDiscAfterwards) | |||
| { | |||
| return String::empty; | |||
| } | |||
| END_JUCE_NAMESPACE | |||
| @@ -1974,6 +1974,8 @@ public: | |||
| isCompositingWindow = HIViewIsCompositingEnabled (viewRef); | |||
| #endif | |||
| SetAutomaticControlDragTrackingEnabledForWindow (newWindow, true); | |||
| MouseCheckTimer::getInstance()->resetMouseMoveChecker(); | |||
| } | |||
| } | |||
| @@ -1264,6 +1264,12 @@ private: | |||
| if (threadShouldExit()) | |||
| return; | |||
| // boost our priority while opening the devices to try to get better sync between them | |||
| const int oldThreadPri = GetThreadPriority (GetCurrentThread()); | |||
| const int oldProcPri = GetPriorityClass (GetCurrentProcess()); | |||
| SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); | |||
| SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS); | |||
| for (i = outChans.size(); --i >= 0;) | |||
| { | |||
| DSoundInternalOutChannel* const out = outChans.getUnchecked(i); | |||
| @@ -1278,18 +1284,21 @@ private: | |||
| in->open(); | |||
| } | |||
| if (threadShouldExit()) | |||
| return; | |||
| if (! threadShouldExit()) | |||
| { | |||
| sleep (5); | |||
| sleep (5); | |||
| for (i = 0; i < numOutputBuffers; ++i) | |||
| if (outChans[i] != 0) | |||
| outChans[i]->synchronisePosition(); | |||
| for (i = 0; i < numOutputBuffers; ++i) | |||
| if (outChans[i] != 0) | |||
| outChans[i]->synchronisePosition(); | |||
| for (i = 0; i < numInputBuffers; ++i) | |||
| if (inChans[i] != 0) | |||
| inChans[i]->synchronisePosition(); | |||
| } | |||
| for (i = 0; i < numInputBuffers; ++i) | |||
| if (inChans[i] != 0) | |||
| inChans[i]->synchronisePosition(); | |||
| SetThreadPriority (GetCurrentThread(), oldThreadPri); | |||
| SetPriorityClass (GetCurrentProcess(), oldProcPri); | |||
| } | |||
| public: | |||
| @@ -1707,6 +1716,12 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, | |||
| String error; | |||
| // boost our priority while opening the devices to try to get better sync between them | |||
| const int oldThreadPri = GetThreadPriority (GetCurrentThread()); | |||
| const int oldProcPri = GetPriorityClass (GetCurrentProcess()); | |||
| SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); | |||
| SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS); | |||
| for (i = 0; i < numOutputBuffers; ++i) | |||
| { | |||
| if (outChans[i] != 0) | |||
| @@ -1740,28 +1755,32 @@ const String DSoundAudioIODevice::openDevice (const BitArray& inputChannels, | |||
| } | |||
| } | |||
| if (error.isNotEmpty()) | |||
| if (error.isEmpty()) | |||
| { | |||
| log (error); | |||
| return error; | |||
| } | |||
| totalSamplesOut = 0; | |||
| totalSamplesOut = 0; | |||
| for (i = 0; i < numOutputBuffers; ++i) | |||
| if (outChans[i] != 0) | |||
| outChans[i]->synchronisePosition(); | |||
| startThread (9); | |||
| sleep (10); | |||
| for (i = 0; i < numInputBuffers; ++i) | |||
| if (inChans[i] != 0) | |||
| inChans[i]->synchronisePosition(); | |||
| for (i = 0; i < numOutputBuffers; ++i) | |||
| if (outChans[i] != 0) | |||
| outChans[i]->synchronisePosition(); | |||
| startThread (9); | |||
| sleep (10); | |||
| for (i = 0; i < numInputBuffers; ++i) | |||
| if (inChans[i] != 0) | |||
| inChans[i]->synchronisePosition(); | |||
| notify(); | |||
| } | |||
| else | |||
| { | |||
| log (error); | |||
| } | |||
| notify(); | |||
| SetThreadPriority (GetCurrentThread(), oldThreadPri); | |||
| SetPriorityClass (GetCurrentProcess(), oldProcPri); | |||
| return String::empty; | |||
| return error; | |||
| } | |||
| @@ -72,7 +72,8 @@ AudioDeviceManager::~AudioDeviceManager() | |||
| const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, | |||
| const int numOutputChannelsNeeded, | |||
| const XmlElement* const e, | |||
| const bool selectDefaultDeviceOnFailure) | |||
| const bool selectDefaultDeviceOnFailure, | |||
| const String& preferredDefaultDeviceName) | |||
| { | |||
| if (listNeedsScanning) | |||
| refreshDeviceList(); | |||
| @@ -105,7 +106,8 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, | |||
| setMidiInputEnabled (allMidiIns[i], enabledMidiIns.contains (allMidiIns[i])); | |||
| if (error.isNotEmpty() && selectDefaultDeviceOnFailure) | |||
| error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, false); | |||
| error = initialise (numInputChannelsNeeded, numOutputChannelsNeeded, 0, | |||
| false, preferredDefaultDeviceName); | |||
| setDefaultMidiOutput (e->getStringAttribute (T("defaultMidiOutput"))); | |||
| @@ -117,7 +119,24 @@ const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, | |||
| String defaultDevice; | |||
| if (availableDeviceTypes [0] != 0) | |||
| if (preferredDefaultDeviceName.isNotEmpty()) | |||
| { | |||
| for (int i = 0; i < availableDeviceTypes.size(); ++i) | |||
| { | |||
| const StringArray devs (availableDeviceTypes.getUnchecked(i)->getDeviceNames()); | |||
| for (int j = 0; j < devs.size(); ++j) | |||
| { | |||
| if (devs[j].matchesWildcard (preferredDefaultDeviceName, true)) | |||
| { | |||
| defaultDevice = devs[j]; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| if (defaultDevice.isEmpty() && availableDeviceTypes [0] != 0) | |||
| defaultDevice = availableDeviceTypes[0]->getDefaultDeviceName (numOutputChannelsNeeded == 0, | |||
| numInputChannelsNeeded, | |||
| numOutputChannelsNeeded); | |||
| @@ -109,12 +109,19 @@ public: | |||
| fails to open, then a default device will be used | |||
| instead. If false, then on failure, no device is | |||
| opened. | |||
| @param preferredDefaultDeviceName if this is not empty, and there's a device with this | |||
| name, then that will be used as the default device | |||
| (assuming that there wasn't one specified in the XML). | |||
| The string can actually be a simple wildcard, containing "*" | |||
| and "?" characters | |||
| @returns an error message if anything went wrong, or an empty string if it worked ok. | |||
| */ | |||
| const String initialise (const int numInputChannelsNeeded, | |||
| const int numOutputChannelsNeeded, | |||
| const XmlElement* const savedState, | |||
| const bool selectDefaultDeviceOnFailure); | |||
| const bool selectDefaultDeviceOnFailure, | |||
| const String& preferredDefaultDeviceName = String::empty); | |||
| /** Returns some XML representing the current state of the manager. | |||
| @@ -153,6 +153,23 @@ bool InterprocessConnection::isConnected() const | |||
| && isThreadRunning(); | |||
| } | |||
| const String InterprocessConnection::getConnectedHostName() const | |||
| { | |||
| if (pipe != 0) | |||
| { | |||
| return "localhost"; | |||
| } | |||
| else if (socket != 0) | |||
| { | |||
| if (! socket->isLocal()) | |||
| return socket->getHostName(); | |||
| return "localhost"; | |||
| } | |||
| return String::empty; | |||
| } | |||
| //============================================================================== | |||
| bool InterprocessConnection::sendMessage (const MemoryBlock& message) | |||
| { | |||
| @@ -132,6 +132,18 @@ public: | |||
| /** True if a socket or pipe is currently active. */ | |||
| bool isConnected() const; | |||
| /** Returns the socket that this connection is using (or null if it uses a pipe). */ | |||
| StreamingSocket* getSocket() const throw() { return socket; } | |||
| /** Returns the pipe that this connection is using (or null if it uses a socket). */ | |||
| NamedPipe* getPipe() const throw() { return pipe; } | |||
| /** Returns the name of the machine at the other end of this connection. | |||
| This will return an empty string if the other machine isn't known for | |||
| some reason. | |||
| */ | |||
| const String getConnectedHostName() const; | |||
| //============================================================================== | |||
| /** Tries to send a message to the other end of this connection. | |||
| @@ -122,6 +122,7 @@ Slider::Slider (const String& name) | |||
| editableText (true), | |||
| doubleClickToValue (false), | |||
| isVelocityBased (false), | |||
| userKeyOverridesVelocity (true), | |||
| rotaryStop (true), | |||
| incDecButtonsSideBySide (false), | |||
| sendChangeOnlyOnRelease (false), | |||
| @@ -227,7 +228,8 @@ void Slider::setVelocityBasedMode (const bool velBased) throw() | |||
| void Slider::setVelocityModeParameters (const double sensitivity, | |||
| const int threshold, | |||
| const double offset) throw() | |||
| const double offset, | |||
| const bool userCanPressKeyToSwapMode) throw() | |||
| { | |||
| jassert (threshold >= 0); | |||
| jassert (sensitivity > 0); | |||
| @@ -236,6 +238,7 @@ void Slider::setVelocityModeParameters (const double sensitivity, | |||
| velocityModeSensitivity = sensitivity; | |||
| velocityModeOffset = offset; | |||
| velocityModeThreshold = threshold; | |||
| userKeyOverridesVelocity = userCanPressKeyToSwapMode; | |||
| } | |||
| void Slider::setSkewFactor (const double factor) throw() | |||
| @@ -1188,7 +1191,9 @@ void Slider::mouseDrag (const MouseEvent& e) | |||
| return; | |||
| } | |||
| if (isVelocityBased == (e.mods.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier | ModifierKeys::altModifier)) | |||
| if ((isVelocityBased == (userKeyOverridesVelocity ? false | |||
| : (e.mods.testFlags (ModifierKeys::ctrlModifier | ModifierKeys::commandModifier | ModifierKeys::altModifier)))) | |||
| || ((maximum - minimum) / sliderRegionSize < interval)) | |||
| { | |||
| const int mousePos = (isHorizontal() || style == RotaryHorizontalDrag) ? e.x : e.y; | |||
| @@ -170,7 +170,8 @@ public: | |||
| */ | |||
| void setVelocityModeParameters (const double sensitivity = 1.0, | |||
| const int threshold = 1.0, | |||
| const double offset = 0.0) throw(); | |||
| const double offset = 0.0, | |||
| const bool userCanPressKeyToSwapMode = true) throw(); | |||
| //============================================================================== | |||
| /** Sets up a skew factor to alter the way values are distributed. | |||
| @@ -693,9 +694,10 @@ private: | |||
| IncDecButtonMode incDecButtonMode; | |||
| bool editableText : 1, doubleClickToValue : 1; | |||
| bool isVelocityBased : 1, rotaryStop : 1, incDecButtonsSideBySide : 1; | |||
| bool sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1; | |||
| bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1, scrollWheelEnabled : 1; | |||
| bool isVelocityBased : 1, userKeyOverridesVelocity : 1, rotaryStop : 1; | |||
| bool incDecButtonsSideBySide : 1, sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1; | |||
| bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1; | |||
| bool scrollWheelEnabled : 1; | |||
| Font font; | |||
| Label* valueBox; | |||
| Button* incButton; | |||
| @@ -448,6 +448,8 @@ public: | |||
| } | |||
| } | |||
| bool forceNewLine = false; | |||
| if (sectionIndex >= sections.size()) | |||
| { | |||
| moveToEndOfLastAtom(); | |||
| @@ -478,6 +480,8 @@ public: | |||
| // handle the case where the last atom in a section is actually part of the same | |||
| // word as the first atom of the next section... | |||
| float right = atomRight + lastAtom->width; | |||
| float lineHeight2 = lineHeight; | |||
| float maxDescent2 = maxDescent; | |||
| for (int section = sectionIndex + 1; section < sections.size(); ++section) | |||
| { | |||
| @@ -493,8 +497,20 @@ public: | |||
| right += nextAtom->width; | |||
| if (atom != 0 && SHOULD_WRAP (right, wordWrapWidth)) | |||
| return wrapCurrentAtom(); | |||
| lineHeight2 = jmax (lineHeight2, s->font.getHeight()); | |||
| maxDescent2 = jmax (maxDescent2, s->font.getDescent()); | |||
| if (SHOULD_WRAP (right, wordWrapWidth)) | |||
| { | |||
| lineHeight = lineHeight2; | |||
| maxDescent = maxDescent2; | |||
| forceNewLine = true; | |||
| break; | |||
| } | |||
| if (s->getNumAtoms() > 1) | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| @@ -516,7 +532,7 @@ public: | |||
| atomRight = atomX + atom->width; | |||
| ++atomIndex; | |||
| if (SHOULD_WRAP (atomRight, wordWrapWidth)) | |||
| if (SHOULD_WRAP (atomRight, wordWrapWidth) || forceNewLine) | |||
| { | |||
| if (atom->isWhitespace()) | |||
| { | |||
| @@ -85,6 +85,9 @@ BEGIN_JUCE_NAMESPACE | |||
| bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle); | |||
| static bool hasLoadedQT = false; | |||
| static bool isQTAvailable = false; | |||
| //============================================================================== | |||
| struct QTMovieCompInternal | |||
| @@ -148,6 +151,19 @@ QuickTimeMovieComponent::~QuickTimeMovieComponent() | |||
| internal = 0; | |||
| } | |||
| bool QuickTimeMovieComponent::isQuickTimeAvailable() throw() | |||
| { | |||
| if (! hasLoadedQT) | |||
| { | |||
| hasLoadedQT = true; | |||
| isQTAvailable = (InitializeQTML (0) == noErr) | |||
| && (EnterMovies() == noErr); | |||
| } | |||
| return isQTAvailable; | |||
| } | |||
| //============================================================================== | |||
| void QuickTimeMovieComponent::createControlIfNeeded() | |||
| { | |||
| @@ -364,8 +380,6 @@ void QuickTimeMovieComponent::paint (Graphics& g) | |||
| #include "../../../events/juce_MessageManager.h" | |||
| #include "../../graphics/geometry/juce_RectangleList.h" | |||
| static bool isQTAvailable = false; | |||
| static bool hasLoadedQT = false; | |||
| static VoidArray activeQTWindows (2); | |||
| struct MacClickEventData | |||
| @@ -436,6 +450,17 @@ QuickTimeMovieComponent::~QuickTimeMovieComponent() | |||
| } | |||
| } | |||
| bool QuickTimeMovieComponent::isQuickTimeAvailable() throw() | |||
| { | |||
| if (! hasLoadedQT) | |||
| { | |||
| hasLoadedQT = true; | |||
| isQTAvailable = EnterMovies() == noErr; | |||
| } | |||
| return isQTAvailable; | |||
| } | |||
| bool QuickTimeMovieComponent::loadMovie (InputStream* movieStream, | |||
| const bool controllerVisible_) | |||
| { | |||
| @@ -70,6 +70,10 @@ public: | |||
| /** Destructor. */ | |||
| ~QuickTimeMovieComponent(); | |||
| /** Returns true if QT is installed and working on this machine. | |||
| */ | |||
| static bool isQuickTimeAvailable() throw(); | |||
| //============================================================================== | |||
| /** Tries to load a QuickTime movie into the player. | |||