| @@ -682,6 +682,7 @@ | |||||
| 15C6FD019B274AA51B4E2D76 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_KeyPressMappingSet.h; path = ../../src/gui/components/keyboard/juce_KeyPressMappingSet.h; sourceTree = SOURCE_ROOT; }; | 15C6FD019B274AA51B4E2D76 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_KeyPressMappingSet.h; path = ../../src/gui/components/keyboard/juce_KeyPressMappingSet.h; sourceTree = SOURCE_ROOT; }; | ||||
| B1E8FF009812F29C2620E6BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModifierKeys.cpp; path = ../../src/gui/components/keyboard/juce_ModifierKeys.cpp; sourceTree = SOURCE_ROOT; }; | B1E8FF009812F29C2620E6BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModifierKeys.cpp; path = ../../src/gui/components/keyboard/juce_ModifierKeys.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| FAEEA3536AD17B2667A1BB94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModifierKeys.h; path = ../../src/gui/components/keyboard/juce_ModifierKeys.h; sourceTree = SOURCE_ROOT; }; | FAEEA3536AD17B2667A1BB94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModifierKeys.h; path = ../../src/gui/components/keyboard/juce_ModifierKeys.h; sourceTree = SOURCE_ROOT; }; | ||||
| D64DD9F41E4598606855DFCF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextEditorKeyMapper.h; path = ../../src/gui/components/keyboard/juce_TextEditorKeyMapper.h; sourceTree = SOURCE_ROOT; }; | |||||
| 7356F5E93CEA4D472D83D8E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextInputTarget.h; path = ../../src/gui/components/keyboard/juce_TextInputTarget.h; sourceTree = SOURCE_ROOT; }; | 7356F5E93CEA4D472D83D8E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextInputTarget.h; path = ../../src/gui/components/keyboard/juce_TextInputTarget.h; sourceTree = SOURCE_ROOT; }; | ||||
| 921B616E2229AEB6390D2B57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentAnimator.cpp; path = ../../src/gui/components/layout/juce_ComponentAnimator.cpp; sourceTree = SOURCE_ROOT; }; | 921B616E2229AEB6390D2B57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentAnimator.cpp; path = ../../src/gui/components/layout/juce_ComponentAnimator.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| FE1072B5FB77E8FEE1BEBDFE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentAnimator.h; path = ../../src/gui/components/layout/juce_ComponentAnimator.h; sourceTree = SOURCE_ROOT; }; | FE1072B5FB77E8FEE1BEBDFE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentAnimator.h; path = ../../src/gui/components/layout/juce_ComponentAnimator.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -1447,6 +1448,7 @@ | |||||
| 15C6FD019B274AA51B4E2D76, | 15C6FD019B274AA51B4E2D76, | ||||
| B1E8FF009812F29C2620E6BB, | B1E8FF009812F29C2620E6BB, | ||||
| FAEEA3536AD17B2667A1BB94, | FAEEA3536AD17B2667A1BB94, | ||||
| D64DD9F41E4598606855DFCF, | |||||
| 7356F5E93CEA4D472D83D8E5 ); name = keyboard; sourceTree = "<group>"; }; | 7356F5E93CEA4D472D83D8E5 ); name = keyboard; sourceTree = "<group>"; }; | ||||
| D75AAB3AB61247E962C00692 = { isa = PBXGroup; children = ( | D75AAB3AB61247E962C00692 = { isa = PBXGroup; children = ( | ||||
| 921B616E2229AEB6390D2B57, | 921B616E2229AEB6390D2B57, | ||||
| @@ -532,6 +532,7 @@ | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextEditorKeyMapper.h"/> | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | ||||
| </Filter> | </Filter> | ||||
| <Filter Name="layout"> | <Filter Name="layout"> | ||||
| @@ -532,6 +532,7 @@ | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextEditorKeyMapper.h"/> | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | ||||
| </Filter> | </Filter> | ||||
| <Filter Name="layout"> | <Filter Name="layout"> | ||||
| @@ -534,6 +534,7 @@ | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.cpp"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | ||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextEditorKeyMapper.h"/> | |||||
| <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | <File RelativePath="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | ||||
| </Filter> | </Filter> | ||||
| <Filter Name="layout"> | <Filter Name="layout"> | ||||
| @@ -626,6 +626,7 @@ | |||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_KeyPress.h"/> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_KeyPress.h"/> | ||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_KeyPressMappingSet.h"/> | ||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"/> | ||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextEditorKeyMapper.h"/> | |||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"/> | ||||
| <ClInclude Include="..\..\src\gui\components\layout\juce_ComponentAnimator.h"/> | <ClInclude Include="..\..\src\gui\components\layout\juce_ComponentAnimator.h"/> | ||||
| <ClInclude Include="..\..\src\gui\components\layout\juce_ComponentBoundsConstrainer.h"/> | <ClInclude Include="..\..\src\gui\components\layout\juce_ComponentBoundsConstrainer.h"/> | ||||
| @@ -1809,6 +1809,9 @@ | |||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_ModifierKeys.h"> | ||||
| <Filter>Juce\Source\gui\components\keyboard</Filter> | <Filter>Juce\Source\gui\components\keyboard</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextEditorKeyMapper.h"> | |||||
| <Filter>Juce\Source\gui\components\keyboard</Filter> | |||||
| </ClInclude> | |||||
| <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"> | <ClInclude Include="..\..\src\gui\components\keyboard\juce_TextInputTarget.h"> | ||||
| <Filter>Juce\Source\gui\components\keyboard</Filter> | <Filter>Juce\Source\gui\components\keyboard</Filter> | ||||
| </ClInclude> | </ClInclude> | ||||
| @@ -682,6 +682,7 @@ | |||||
| 15C6FD019B274AA51B4E2D76 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_KeyPressMappingSet.h; path = ../../src/gui/components/keyboard/juce_KeyPressMappingSet.h; sourceTree = SOURCE_ROOT; }; | 15C6FD019B274AA51B4E2D76 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_KeyPressMappingSet.h; path = ../../src/gui/components/keyboard/juce_KeyPressMappingSet.h; sourceTree = SOURCE_ROOT; }; | ||||
| B1E8FF009812F29C2620E6BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModifierKeys.cpp; path = ../../src/gui/components/keyboard/juce_ModifierKeys.cpp; sourceTree = SOURCE_ROOT; }; | B1E8FF009812F29C2620E6BB = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ModifierKeys.cpp; path = ../../src/gui/components/keyboard/juce_ModifierKeys.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| FAEEA3536AD17B2667A1BB94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModifierKeys.h; path = ../../src/gui/components/keyboard/juce_ModifierKeys.h; sourceTree = SOURCE_ROOT; }; | FAEEA3536AD17B2667A1BB94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ModifierKeys.h; path = ../../src/gui/components/keyboard/juce_ModifierKeys.h; sourceTree = SOURCE_ROOT; }; | ||||
| D64DD9F41E4598606855DFCF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextEditorKeyMapper.h; path = ../../src/gui/components/keyboard/juce_TextEditorKeyMapper.h; sourceTree = SOURCE_ROOT; }; | |||||
| 7356F5E93CEA4D472D83D8E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextInputTarget.h; path = ../../src/gui/components/keyboard/juce_TextInputTarget.h; sourceTree = SOURCE_ROOT; }; | 7356F5E93CEA4D472D83D8E5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_TextInputTarget.h; path = ../../src/gui/components/keyboard/juce_TextInputTarget.h; sourceTree = SOURCE_ROOT; }; | ||||
| 921B616E2229AEB6390D2B57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentAnimator.cpp; path = ../../src/gui/components/layout/juce_ComponentAnimator.cpp; sourceTree = SOURCE_ROOT; }; | 921B616E2229AEB6390D2B57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = juce_ComponentAnimator.cpp; path = ../../src/gui/components/layout/juce_ComponentAnimator.cpp; sourceTree = SOURCE_ROOT; }; | ||||
| FE1072B5FB77E8FEE1BEBDFE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentAnimator.h; path = ../../src/gui/components/layout/juce_ComponentAnimator.h; sourceTree = SOURCE_ROOT; }; | FE1072B5FB77E8FEE1BEBDFE = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = juce_ComponentAnimator.h; path = ../../src/gui/components/layout/juce_ComponentAnimator.h; sourceTree = SOURCE_ROOT; }; | ||||
| @@ -1447,6 +1448,7 @@ | |||||
| 15C6FD019B274AA51B4E2D76, | 15C6FD019B274AA51B4E2D76, | ||||
| B1E8FF009812F29C2620E6BB, | B1E8FF009812F29C2620E6BB, | ||||
| FAEEA3536AD17B2667A1BB94, | FAEEA3536AD17B2667A1BB94, | ||||
| D64DD9F41E4598606855DFCF, | |||||
| 7356F5E93CEA4D472D83D8E5 ); name = keyboard; sourceTree = "<group>"; }; | 7356F5E93CEA4D472D83D8E5 ); name = keyboard; sourceTree = "<group>"; }; | ||||
| D75AAB3AB61247E962C00692 = { isa = PBXGroup; children = ( | D75AAB3AB61247E962C00692 = { isa = PBXGroup; children = ( | ||||
| 921B616E2229AEB6390D2B57, | 921B616E2229AEB6390D2B57, | ||||
| @@ -713,6 +713,8 @@ | |||||
| file="src/gui/components/keyboard/juce_ModifierKeys.cpp"/> | file="src/gui/components/keyboard/juce_ModifierKeys.cpp"/> | ||||
| <FILE id="sEv20iWws" name="juce_ModifierKeys.h" compile="0" resource="0" | <FILE id="sEv20iWws" name="juce_ModifierKeys.h" compile="0" resource="0" | ||||
| file="src/gui/components/keyboard/juce_ModifierKeys.h"/> | file="src/gui/components/keyboard/juce_ModifierKeys.h"/> | ||||
| <FILE id="ohA4B9" name="juce_TextEditorKeyMapper.h" compile="0" resource="0" | |||||
| file="src/gui/components/keyboard/juce_TextEditorKeyMapper.h"/> | |||||
| <FILE id="xafOvZlQw" name="juce_TextInputTarget.h" compile="0" resource="0" | <FILE id="xafOvZlQw" name="juce_TextInputTarget.h" compile="0" resource="0" | ||||
| file="src/gui/components/keyboard/juce_TextInputTarget.h"/> | file="src/gui/components/keyboard/juce_TextInputTarget.h"/> | ||||
| </GROUP> | </GROUP> | ||||
| @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 89 | |||||
| #define JUCE_BUILDNUMBER 90 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -1647,8 +1647,8 @@ public: | |||||
| template <typename CharPointerType> | template <typename CharPointerType> | ||||
| static double readDoubleValue (CharPointerType& text) noexcept | static double readDoubleValue (CharPointerType& text) noexcept | ||||
| { | { | ||||
| double result[3] = { 0, 0, 0 }, accumulator[2] = { 0, 0 }; | |||||
| int exponentAdjustment[2] = { 0, 0 }, exponentAccumulator[2] = { -1, -1 }; | |||||
| double result[3] = { 0 }, accumulator[2] = { 0 }; | |||||
| int exponentAdjustment[2] = { 0 }, exponentAccumulator[2] = { -1, -1 }; | |||||
| int exponent = 0, decPointIndex = 0, digit = 0; | int exponent = 0, decPointIndex = 0, digit = 0; | ||||
| int lastDigit = 0, numSignificantDigits = 0; | int lastDigit = 0, numSignificantDigits = 0; | ||||
| bool isNegative = false, digitsFound = false; | bool isNegative = false, digitsFound = false; | ||||
| @@ -8734,16 +8734,16 @@ public: | |||||
| var (ReferenceCountedObject* object); | var (ReferenceCountedObject* object); | ||||
| var (MethodFunction method) noexcept; | var (MethodFunction method) noexcept; | ||||
| var& operator= (const var& valueToCopy); | |||||
| var& operator= (int value); | |||||
| var& operator= (int64 value); | |||||
| var& operator= (bool value); | |||||
| var& operator= (double value); | |||||
| var& operator= (const char* value); | |||||
| var& operator= (const wchar_t* value); | |||||
| var& operator= (const String& value); | |||||
| var& operator= (ReferenceCountedObject* object); | |||||
| var& operator= (MethodFunction method); | |||||
| const var& operator= (const var& valueToCopy); | |||||
| const var& operator= (int value); | |||||
| const var& operator= (int64 value); | |||||
| const var& operator= (bool value); | |||||
| const var& operator= (double value); | |||||
| const var& operator= (const char* value); | |||||
| const var& operator= (const wchar_t* value); | |||||
| const var& operator= (const String& value); | |||||
| const var& operator= (ReferenceCountedObject* object); | |||||
| const var& operator= (MethodFunction method); | |||||
| void swapWith (var& other) noexcept; | void swapWith (var& other) noexcept; | ||||
| @@ -18835,6 +18835,8 @@ private: | |||||
| bool negative; | bool negative; | ||||
| void ensureSize (int numVals); | void ensureSize (int numVals); | ||||
| void shiftLeft (int bits, int startBit); | |||||
| void shiftRight (int bits, int startBit); | |||||
| static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); | static const BigInteger simpleGCD (BigInteger* m, BigInteger* n); | ||||
| static inline int bitToIndex (const int bit) noexcept { return bit >> 5; } | static inline int bitToIndex (const int bit) noexcept { return bit >> 5; } | ||||
| @@ -19258,6 +19260,7 @@ private: | |||||
| void openHandle(); | void openHandle(); | ||||
| void closeHandle(); | void closeHandle(); | ||||
| void flushInternal(); | void flushInternal(); | ||||
| bool flushBuffer(); | |||||
| int64 setPositionInternal (int64 newPosition); | int64 setPositionInternal (int64 newPosition); | ||||
| int writeInternal (const void* data, int numBytes); | int writeInternal (const void* data, int numBytes); | ||||
| @@ -20835,6 +20838,7 @@ private: | |||||
| friend class ScopedPointer <GZIPCompressorHelper>; | friend class ScopedPointer <GZIPCompressorHelper>; | ||||
| ScopedPointer <GZIPCompressorHelper> helper; | ScopedPointer <GZIPCompressorHelper> helper; | ||||
| bool doNextBlock(); | bool doNextBlock(); | ||||
| void flushInternal(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPCompressorOutputStream); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GZIPCompressorOutputStream); | ||||
| }; | }; | ||||
| @@ -21077,6 +21081,8 @@ private: | |||||
| MemoryBlock internalBlock; | MemoryBlock internalBlock; | ||||
| size_t position, size; | size_t position, size; | ||||
| void trimExternalBlockSize(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MemoryOutputStream); | ||||
| }; | }; | ||||
| @@ -38124,9 +38130,14 @@ public: | |||||
| */ | */ | ||||
| virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; | virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; | ||||
| /** Called to indicate that the device has stopped. | |||||
| */ | |||||
| /** Called to indicate that the device has stopped. */ | |||||
| virtual void audioDeviceStopped() = 0; | virtual void audioDeviceStopped() = 0; | ||||
| /** This can be overridden to be told if the device generates an error while operating. | |||||
| Be aware that this could be called by any thread! And not all devices perform | |||||
| this callback. | |||||
| */ | |||||
| virtual void audioDeviceError (const String& errorMessage); | |||||
| }; | }; | ||||
| /** | /** | ||||
| @@ -38728,6 +38739,8 @@ private: | |||||
| int blockSize, readAheadBufferSize; | int blockSize, readAheadBufferSize; | ||||
| bool isPrepared, inputStreamEOF; | bool isPrepared, inputStreamEOF; | ||||
| void releaseMasterResources(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioTransportSource); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioTransportSource); | ||||
| }; | }; | ||||
| @@ -42920,6 +42933,27 @@ public: | |||||
| /** @internal */ | /** @internal */ | ||||
| void setTemporaryUnderlining (const Array <Range<int> >&); | void setTemporaryUnderlining (const Array <Range<int> >&); | ||||
| bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretUp (bool selecting); | |||||
| bool moveCaretDown (bool selecting); | |||||
| bool pageUp (bool selecting); | |||||
| bool pageDown (bool selecting); | |||||
| bool scrollDown(); | |||||
| bool scrollUp(); | |||||
| bool moveCaretToTop (bool selecting); | |||||
| bool moveCaretToStartOfLine (bool selecting); | |||||
| bool moveCaretToEnd (bool selecting); | |||||
| bool moveCaretToEndOfLine (bool selecting); | |||||
| bool deleteBackwards (bool moveInWholeWordSteps); | |||||
| bool deleteForwards (bool moveInWholeWordSteps); | |||||
| bool copyToClipboard(); | |||||
| bool cutToClipboard(); | |||||
| bool pasteFromClipboard(); | |||||
| bool selectAll(); | |||||
| bool undo(); | |||||
| bool redo(); | |||||
| /** This adds the items to the popup menu. | /** This adds the items to the popup menu. | ||||
| By default it adds the cut/copy/paste items, but you can override this if | By default it adds the cut/copy/paste items, but you can override this if | ||||
| @@ -43052,7 +43086,7 @@ private: | |||||
| int indexAtPosition (float x, float y); | int indexAtPosition (float x, float y); | ||||
| int findWordBreakAfter (int position) const; | int findWordBreakAfter (int position) const; | ||||
| int findWordBreakBefore (int position) const; | int findWordBreakBefore (int position) const; | ||||
| bool moveCaretWithTransation (int newPos, bool selecting); | |||||
| friend class TextHolderComponent; | friend class TextHolderComponent; | ||||
| friend class TextEditorViewport; | friend class TextEditorViewport; | ||||
| void drawContent (Graphics& g); | void drawContent (Graphics& g); | ||||
| @@ -43060,6 +43094,8 @@ private: | |||||
| float getWordWrapWidth() const; | float getWordWrapWidth() const; | ||||
| void timerCallbackInt(); | void timerCallbackInt(); | ||||
| void repaintText (const Range<int>& range); | void repaintText (const Range<int>& range); | ||||
| void scrollByLines (int deltaLines); | |||||
| bool undoOrRedo (bool shouldUndo); | |||||
| UndoManager* getUndoManager() noexcept; | UndoManager* getUndoManager() noexcept; | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditor); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditor); | ||||
| @@ -47364,6 +47400,7 @@ private: | |||||
| void scanFor (AudioPluginFormat* format); | void scanFor (AudioPluginFormat* format); | ||||
| static void optionsMenuStaticCallback (int result, PluginListComponent*); | static void optionsMenuStaticCallback (int result, PluginListComponent*); | ||||
| void optionsMenuCallback (int result); | void optionsMenuCallback (int result); | ||||
| void updateList(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PluginListComponent); | ||||
| }; | }; | ||||
| @@ -49522,6 +49559,8 @@ private: | |||||
| Path path; | Path path; | ||||
| int offset; | int offset; | ||||
| void updateShadowAndOffset(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ArrowButton); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ArrowButton); | ||||
| }; | }; | ||||
| @@ -52238,40 +52277,36 @@ public: | |||||
| */ | */ | ||||
| const CodeDocument::Position getPositionAt (int x, int y); | const CodeDocument::Position getPositionAt (int x, int y); | ||||
| void cursorLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| void cursorRight (bool moveInWholeWordSteps, bool selecting); | |||||
| void cursorDown (bool selecting); | |||||
| void cursorUp (bool selecting); | |||||
| bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretUp (bool selecting); | |||||
| bool moveCaretDown (bool selecting); | |||||
| bool scrollDown(); | |||||
| bool scrollUp(); | |||||
| bool pageUp (bool selecting); | |||||
| bool pageDown (bool selecting); | |||||
| bool moveCaretToTop (bool selecting); | |||||
| bool moveCaretToStartOfLine (bool selecting); | |||||
| bool moveCaretToEnd (bool selecting); | |||||
| bool moveCaretToEndOfLine (bool selecting); | |||||
| bool deleteBackwards (bool moveInWholeWordSteps); | |||||
| bool deleteForwards (bool moveInWholeWordSteps); | |||||
| bool copyToClipboard(); | |||||
| bool cutToClipboard(); | |||||
| bool pasteFromClipboard(); | |||||
| bool undo(); | |||||
| bool redo(); | |||||
| void pageDown (bool selecting); | |||||
| void pageUp (bool selecting); | |||||
| bool selectAll(); | |||||
| void deselectAll(); | |||||
| void scrollDown(); | |||||
| void scrollUp(); | |||||
| void scrollToLine (int newFirstLineOnScreen); | void scrollToLine (int newFirstLineOnScreen); | ||||
| void scrollBy (int deltaLines); | void scrollBy (int deltaLines); | ||||
| void scrollToColumn (int newFirstColumnOnScreen); | void scrollToColumn (int newFirstColumnOnScreen); | ||||
| void scrollToKeepCaretOnScreen(); | void scrollToKeepCaretOnScreen(); | ||||
| void goToStartOfDocument (bool selecting); | |||||
| void goToStartOfLine (bool selecting); | |||||
| void goToEndOfDocument (bool selecting); | |||||
| void goToEndOfLine (bool selecting); | |||||
| void deselectAll(); | |||||
| void selectAll(); | |||||
| void insertTextAtCaret (const String& textToInsert); | void insertTextAtCaret (const String& textToInsert); | ||||
| void insertTabAtCaret(); | void insertTabAtCaret(); | ||||
| void cut(); | |||||
| void copy(); | |||||
| void copyThenCut(); | |||||
| void paste(); | |||||
| void backspace (bool moveInWholeWordSteps); | |||||
| void deleteForward (bool moveInWholeWordSteps); | |||||
| void undo(); | |||||
| void redo(); | |||||
| const Range<int> getHighlightedRegion() const; | const Range<int> getHighlightedRegion() const; | ||||
| void setHighlightedRegion (const Range<int>& newRange); | void setHighlightedRegion (const Range<int>& newRange); | ||||
| @@ -52422,6 +52457,7 @@ private: | |||||
| void scrollToLineInternal (int line); | void scrollToLineInternal (int line); | ||||
| void scrollToColumnInternal (double column); | void scrollToColumnInternal (double column); | ||||
| void newTransaction(); | void newTransaction(); | ||||
| void cut(); | |||||
| int indexToColumn (int line, int index) const noexcept; | int indexToColumn (int line, int index) const noexcept; | ||||
| int columnToIndex (int line, int column) const noexcept; | int columnToIndex (int line, int column) const noexcept; | ||||
| @@ -53426,7 +53462,8 @@ private: | |||||
| double velocityModeSensitivity, velocityModeOffset, minMaxDiff; | double velocityModeSensitivity, velocityModeOffset, minMaxDiff; | ||||
| int velocityModeThreshold; | int velocityModeThreshold; | ||||
| float rotaryStart, rotaryEnd; | float rotaryStart, rotaryEnd; | ||||
| int numDecimalPlaces, mouseXWhenLastDragged, mouseYWhenLastDragged; | |||||
| int numDecimalPlaces; | |||||
| Point<int> mousePosWhenLastDragged; | |||||
| int mouseDragStartX, mouseDragStartY; | int mouseDragStartX, mouseDragStartY; | ||||
| int sliderRegionStart, sliderRegionSize; | int sliderRegionStart, sliderRegionSize; | ||||
| int sliderBeingDragged; | int sliderBeingDragged; | ||||
| @@ -55763,6 +55800,9 @@ protected: | |||||
| */ | */ | ||||
| virtual void getRoots (StringArray& rootNames, StringArray& rootPaths); | virtual void getRoots (StringArray& rootNames, StringArray& rootPaths); | ||||
| /** Updates the items in the dropdown list of recent paths with the values from getRoots(). */ | |||||
| void resetRecentPaths(); | |||||
| private: | private: | ||||
| ScopedPointer <DirectoryContentsList> fileList; | ScopedPointer <DirectoryContentsList> fileList; | ||||
| @@ -56995,6 +57035,7 @@ private: | |||||
| bool hasBeenResized; | bool hasBeenResized; | ||||
| #endif | #endif | ||||
| void initialise (bool addToDesktop); | |||||
| void updateLastPos(); | void updateLastPos(); | ||||
| void setContent (Component* newComp, bool takeOwnership, bool resizeToFit); | void setContent (Component* newComp, bool takeOwnership, bool resizeToFit); | ||||
| @@ -58863,6 +58904,340 @@ private: | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | ||||
| #endif | |||||
| #ifndef __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| /*** Start of inlined file: juce_TextEditorKeyMapper.h ***/ | |||||
| #ifndef __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| #define __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| /*** Start of inlined file: juce_Keypress.h ***/ | |||||
| #ifndef __JUCE_KEYPRESS_JUCEHEADER__ | |||||
| #define __JUCE_KEYPRESS_JUCEHEADER__ | |||||
| /** | |||||
| Represents a key press, including any modifier keys that are needed. | |||||
| E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc. | |||||
| @see Component, KeyListener, Button::addShortcut, KeyPressMappingManager | |||||
| */ | |||||
| class JUCE_API KeyPress | |||||
| { | |||||
| public: | |||||
| /** Creates an (invalid) KeyPress. | |||||
| @see isValid | |||||
| */ | |||||
| KeyPress() noexcept; | |||||
| /** Creates a KeyPress for a key and some modifiers. | |||||
| e.g. | |||||
| CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier) | |||||
| SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier) | |||||
| @param keyCode a code that represents the key - this value must be | |||||
| one of special constants listed in this class, or an | |||||
| 8-bit character code such as a letter (case is ignored), | |||||
| digit or a simple key like "," or ".". Note that this | |||||
| isn't the same as the textCharacter parameter, so for example | |||||
| a keyCode of 'a' and a shift-key modifier should have a | |||||
| textCharacter value of 'A'. | |||||
| @param modifiers the modifiers to associate with the keystroke | |||||
| @param textCharacter the character that would be printed if someone typed | |||||
| this keypress into a text editor. This value may be | |||||
| null if the keypress is a non-printing character | |||||
| @see getKeyCode, isKeyCode, getModifiers | |||||
| */ | |||||
| KeyPress (int keyCode, | |||||
| const ModifierKeys& modifiers, | |||||
| juce_wchar textCharacter) noexcept; | |||||
| /** Creates a keypress with a keyCode but no modifiers or text character. | |||||
| */ | |||||
| KeyPress (int keyCode) noexcept; | |||||
| /** Creates a copy of another KeyPress. */ | |||||
| KeyPress (const KeyPress& other) noexcept; | |||||
| /** Copies this KeyPress from another one. */ | |||||
| KeyPress& operator= (const KeyPress& other) noexcept; | |||||
| /** Compares two KeyPress objects. */ | |||||
| bool operator== (const KeyPress& other) const noexcept; | |||||
| /** Compares two KeyPress objects. */ | |||||
| bool operator!= (const KeyPress& other) const noexcept; | |||||
| /** Returns true if this is a valid KeyPress. | |||||
| A null keypress can be created by the default constructor, in case it's | |||||
| needed. | |||||
| */ | |||||
| bool isValid() const noexcept { return keyCode != 0; } | |||||
| /** Returns the key code itself. | |||||
| This will either be one of the special constants defined in this class, | |||||
| or an 8-bit character code. | |||||
| */ | |||||
| int getKeyCode() const noexcept { return keyCode; } | |||||
| /** Returns the key modifiers. | |||||
| @see ModifierKeys | |||||
| */ | |||||
| const ModifierKeys getModifiers() const noexcept { return mods; } | |||||
| /** Returns the character that is associated with this keypress. | |||||
| This is the character that you'd expect to see printed if you press this | |||||
| keypress in a text editor or similar component. | |||||
| */ | |||||
| juce_wchar getTextCharacter() const noexcept { return textCharacter; } | |||||
| /** Checks whether the KeyPress's key is the same as the one provided, without checking | |||||
| the modifiers. | |||||
| The values for key codes can either be one of the special constants defined in | |||||
| this class, or an 8-bit character code. | |||||
| @see getKeyCode | |||||
| */ | |||||
| bool isKeyCode (int keyCodeToCompare) const noexcept { return keyCode == keyCodeToCompare; } | |||||
| /** Converts a textual key description to a KeyPress. | |||||
| This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE". | |||||
| This isn't designed to cope with any kind of input, but should be given the | |||||
| strings that are created by the getTextDescription() method. | |||||
| If the string can't be parsed, the object returned will be invalid. | |||||
| @see getTextDescription | |||||
| */ | |||||
| static const KeyPress createFromDescription (const String& textVersion); | |||||
| /** Creates a textual description of the key combination. | |||||
| e.g. "CTRL + C" or "DELETE". | |||||
| To store a keypress in a file, use this method, along with createFromDescription() | |||||
| to retrieve it later. | |||||
| */ | |||||
| const String getTextDescription() const; | |||||
| /** Creates a textual description of the key combination, using unicode icon symbols if possible. | |||||
| On OSX, this uses the Apple symbols for command, option, shift, etc, instead of the textual | |||||
| modifier key descriptions that are returned by getTextDescription() | |||||
| */ | |||||
| const String getTextDescriptionWithIcons() const; | |||||
| /** Checks whether the user is currently holding down the keys that make up this | |||||
| KeyPress. | |||||
| Note that this will return false if any extra modifier keys are | |||||
| down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x | |||||
| then it will be false. | |||||
| */ | |||||
| bool isCurrentlyDown() const; | |||||
| /** Checks whether a particular key is held down, irrespective of modifiers. | |||||
| The values for key codes can either be one of the special constants defined in | |||||
| this class, or an 8-bit character code. | |||||
| */ | |||||
| static bool isKeyCurrentlyDown (int keyCode); | |||||
| // Key codes | |||||
| // | |||||
| // Note that the actual values of these are platform-specific and may change | |||||
| // without warning, so don't store them anywhere as constants. For persisting/retrieving | |||||
| // KeyPress objects, use getTextDescription() and createFromDescription() instead. | |||||
| // | |||||
| static const int spaceKey; /**< key-code for the space bar */ | |||||
| static const int escapeKey; /**< key-code for the escape key */ | |||||
| static const int returnKey; /**< key-code for the return key*/ | |||||
| static const int tabKey; /**< key-code for the tab key*/ | |||||
| static const int deleteKey; /**< key-code for the delete key (not backspace) */ | |||||
| static const int backspaceKey; /**< key-code for the backspace key */ | |||||
| static const int insertKey; /**< key-code for the insert key */ | |||||
| static const int upKey; /**< key-code for the cursor-up key */ | |||||
| static const int downKey; /**< key-code for the cursor-down key */ | |||||
| static const int leftKey; /**< key-code for the cursor-left key */ | |||||
| static const int rightKey; /**< key-code for the cursor-right key */ | |||||
| static const int pageUpKey; /**< key-code for the page-up key */ | |||||
| static const int pageDownKey; /**< key-code for the page-down key */ | |||||
| static const int homeKey; /**< key-code for the home key */ | |||||
| static const int endKey; /**< key-code for the end key */ | |||||
| static const int F1Key; /**< key-code for the F1 key */ | |||||
| static const int F2Key; /**< key-code for the F2 key */ | |||||
| static const int F3Key; /**< key-code for the F3 key */ | |||||
| static const int F4Key; /**< key-code for the F4 key */ | |||||
| static const int F5Key; /**< key-code for the F5 key */ | |||||
| static const int F6Key; /**< key-code for the F6 key */ | |||||
| static const int F7Key; /**< key-code for the F7 key */ | |||||
| static const int F8Key; /**< key-code for the F8 key */ | |||||
| static const int F9Key; /**< key-code for the F9 key */ | |||||
| static const int F10Key; /**< key-code for the F10 key */ | |||||
| static const int F11Key; /**< key-code for the F11 key */ | |||||
| static const int F12Key; /**< key-code for the F12 key */ | |||||
| static const int F13Key; /**< key-code for the F13 key */ | |||||
| static const int F14Key; /**< key-code for the F14 key */ | |||||
| static const int F15Key; /**< key-code for the F15 key */ | |||||
| static const int F16Key; /**< key-code for the F16 key */ | |||||
| static const int numberPad0; /**< key-code for the 0 on the numeric keypad. */ | |||||
| static const int numberPad1; /**< key-code for the 1 on the numeric keypad. */ | |||||
| static const int numberPad2; /**< key-code for the 2 on the numeric keypad. */ | |||||
| static const int numberPad3; /**< key-code for the 3 on the numeric keypad. */ | |||||
| static const int numberPad4; /**< key-code for the 4 on the numeric keypad. */ | |||||
| static const int numberPad5; /**< key-code for the 5 on the numeric keypad. */ | |||||
| static const int numberPad6; /**< key-code for the 6 on the numeric keypad. */ | |||||
| static const int numberPad7; /**< key-code for the 7 on the numeric keypad. */ | |||||
| static const int numberPad8; /**< key-code for the 8 on the numeric keypad. */ | |||||
| static const int numberPad9; /**< key-code for the 9 on the numeric keypad. */ | |||||
| static const int numberPadAdd; /**< key-code for the add sign on the numeric keypad. */ | |||||
| static const int numberPadSubtract; /**< key-code for the subtract sign on the numeric keypad. */ | |||||
| static const int numberPadMultiply; /**< key-code for the multiply sign on the numeric keypad. */ | |||||
| static const int numberPadDivide; /**< key-code for the divide sign on the numeric keypad. */ | |||||
| static const int numberPadSeparator; /**< key-code for the comma on the numeric keypad. */ | |||||
| static const int numberPadDecimalPoint; /**< key-code for the decimal point sign on the numeric keypad. */ | |||||
| static const int numberPadEquals; /**< key-code for the equals key on the numeric keypad. */ | |||||
| static const int numberPadDelete; /**< key-code for the delete key on the numeric keypad. */ | |||||
| static const int playKey; /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */ | |||||
| static const int stopKey; /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */ | |||||
| static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */ | |||||
| static const int rewindKey; /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */ | |||||
| private: | |||||
| int keyCode; | |||||
| ModifierKeys mods; | |||||
| juce_wchar textCharacter; | |||||
| JUCE_LEAK_DETECTOR (KeyPress); | |||||
| }; | |||||
| #endif // __JUCE_KEYPRESS_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_Keypress.h ***/ | |||||
| /** This class is used to invoke a range of text-editor navigation methods on | |||||
| an object, based upon a keypress event. | |||||
| It's currently used internally by the TextEditor and CodeEditorComponent. | |||||
| */ | |||||
| template <class CallbackClass> | |||||
| struct TextEditorKeyMapper | |||||
| { | |||||
| /** Checks the keypress and invokes one of a range of navigation functions that | |||||
| the target class must implement, based on the key event. | |||||
| */ | |||||
| static bool invokeKeyFunction (CallbackClass& target, const KeyPress& key) | |||||
| { | |||||
| const bool isShiftDown = key.getModifiers().isShiftDown(); | |||||
| const bool ctrlOrAltDown = key.getModifiers().isCtrlDown() || key.getModifiers().isAltDown(); | |||||
| if (key == KeyPress (KeyPress::downKey, ModifierKeys::ctrlModifier, 0) | |||||
| && target.scrollUp()) | |||||
| return true; | |||||
| if (key == KeyPress (KeyPress::upKey, ModifierKeys::ctrlModifier, 0) | |||||
| && target.scrollDown()) | |||||
| return true; | |||||
| #if JUCE_MAC | |||||
| if (key.getModifiers().isCommandDown()) | |||||
| { | |||||
| if (key.isKeyCode (KeyPress::upKey)) | |||||
| return target.moveCaretToTop (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::downKey)) | |||||
| return target.moveCaretToEnd (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::leftKey)) | |||||
| return target.moveCaretToStartOfLine (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::rightKey)) | |||||
| return target.moveCaretToEndOfLine (isShiftDown); | |||||
| } | |||||
| #endif | |||||
| if (key.isKeyCode (KeyPress::upKey)) | |||||
| return target.moveCaretUp (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::downKey)) | |||||
| return target.moveCaretDown (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::leftKey)) | |||||
| return target.moveCaretLeft (ctrlOrAltDown, isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::rightKey)) | |||||
| return target.moveCaretRight (ctrlOrAltDown, isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::pageUpKey)) | |||||
| return target.pageUp (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::pageDownKey)) | |||||
| return target.pageDown (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::homeKey)) | |||||
| return ctrlOrAltDown ? target.moveCaretToTop (isShiftDown) | |||||
| : target.moveCaretToStartOfLine (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::endKey)) | |||||
| return ctrlOrAltDown ? target.moveCaretToEnd (isShiftDown) | |||||
| : target.moveCaretToEndOfLine (isShiftDown); | |||||
| if (key == KeyPress ('c', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0)) | |||||
| return target.copyToClipboard(); | |||||
| if (key == KeyPress ('x', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::deleteKey, ModifierKeys::shiftModifier, 0)) | |||||
| return target.cutToClipboard(); | |||||
| if (key == KeyPress ('v', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0)) | |||||
| return target.pasteFromClipboard(); | |||||
| if (key.isKeyCode (KeyPress::backspaceKey)) | |||||
| return target.deleteBackwards (ctrlOrAltDown); | |||||
| if (key.isKeyCode (KeyPress::deleteKey)) | |||||
| return target.deleteForwards (ctrlOrAltDown); | |||||
| if (key == KeyPress ('a', ModifierKeys::commandModifier, 0)) | |||||
| return target.selectAll(); | |||||
| if (key == KeyPress ('z', ModifierKeys::commandModifier, 0)) | |||||
| return target.undo(); | |||||
| if (key == KeyPress ('y', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)) | |||||
| return target.redo(); | |||||
| return false; | |||||
| } | |||||
| }; | |||||
| #endif // __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| /*** End of inlined file: juce_TextEditorKeyMapper.h ***/ | |||||
| #endif | #endif | ||||
| #ifndef __JUCE_TEXTINPUTTARGET_JUCEHEADER__ | #ifndef __JUCE_TEXTINPUTTARGET_JUCEHEADER__ | ||||
| @@ -63088,6 +63463,8 @@ private: | |||||
| ScopedPointer<ComboBox> midiOutputSelector; | ScopedPointer<ComboBox> midiOutputSelector; | ||||
| ScopedPointer<Label> midiInputsLabel, midiOutputLabel; | ScopedPointer<Label> midiInputsLabel, midiOutputLabel; | ||||
| void updateAllControls(); | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceSelectorComponent); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AudioDeviceSelectorComponent); | ||||
| }; | }; | ||||
| @@ -53,6 +53,8 @@ bool AudioIODevice::showControlPanel() | |||||
| return false; | return false; | ||||
| } | } | ||||
| //============================================================================== | |||||
| void AudioIODeviceCallback::audioDeviceError (const String&) {} | |||||
| END_JUCE_NAMESPACE | END_JUCE_NAMESPACE | ||||
| @@ -107,9 +107,14 @@ public: | |||||
| */ | */ | ||||
| virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; | virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0; | ||||
| /** Called to indicate that the device has stopped. | |||||
| */ | |||||
| /** Called to indicate that the device has stopped. */ | |||||
| virtual void audioDeviceStopped() = 0; | virtual void audioDeviceStopped() = 0; | ||||
| /** This can be overridden to be told if the device generates an error while operating. | |||||
| Be aware that this could be called by any thread! And not all devices perform | |||||
| this callback. | |||||
| */ | |||||
| virtual void audioDeviceError (const String& errorMessage); | |||||
| }; | }; | ||||
| @@ -33,7 +33,7 @@ | |||||
| */ | */ | ||||
| #define JUCE_MAJOR_VERSION 1 | #define JUCE_MAJOR_VERSION 1 | ||||
| #define JUCE_MINOR_VERSION 53 | #define JUCE_MINOR_VERSION 53 | ||||
| #define JUCE_BUILDNUMBER 89 | |||||
| #define JUCE_BUILDNUMBER 90 | |||||
| /** Current Juce version number. | /** Current Juce version number. | ||||
| @@ -44,7 +44,7 @@ class InternalTimerThread : private Thread, | |||||
| private AsyncUpdater | private AsyncUpdater | ||||
| { | { | ||||
| public: | public: | ||||
| typedef SpinLock LockType; | |||||
| typedef CriticalSection LockType; // (mysteriously, using a SpinLock here causes problems on some XP machines..) | |||||
| InternalTimerThread() | InternalTimerThread() | ||||
| : Thread ("Juce Timer"), | : Thread ("Juce Timer"), | ||||
| @@ -146,7 +146,7 @@ public: | |||||
| /* This is needed as a memory barrier to make sure all processing of current timers is done | /* This is needed as a memory barrier to make sure all processing of current timers is done | ||||
| before the boolean is set. This set should never fail since if it was false in the first place, | before the boolean is set. This set should never fail since if it was false in the first place, | ||||
| we wouldn't get a message (so it can't be changed from false to true from under us), and if we | we wouldn't get a message (so it can't be changed from false to true from under us), and if we | ||||
| get a message then the value is true and the other thread can only set it to true again and | |||||
| get a message then the value is true and the other thread can only set it to true again and | |||||
| we will get another callback to set it to false. | we will get another callback to set it to false. | ||||
| */ | */ | ||||
| callbackNeeded.set (0); | callbackNeeded.set (0); | ||||
| @@ -29,6 +29,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "juce_CodeEditorComponent.h" | #include "juce_CodeEditorComponent.h" | ||||
| #include "../lookandfeel/juce_LookAndFeel.h" | #include "../lookandfeel/juce_LookAndFeel.h" | ||||
| #include "../keyboard/juce_TextEditorKeyMapper.h" | |||||
| #include "../../../utilities/juce_SystemClipboard.h" | #include "../../../utilities/juce_SystemClipboard.h" | ||||
| @@ -628,7 +629,7 @@ void CodeEditorComponent::cut() | |||||
| insertTextAtCaret (String::empty); | insertTextAtCaret (String::empty); | ||||
| } | } | ||||
| void CodeEditorComponent::copy() | |||||
| bool CodeEditorComponent::copyToClipboard() | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -636,16 +637,19 @@ void CodeEditorComponent::copy() | |||||
| if (selection.isNotEmpty()) | if (selection.isNotEmpty()) | ||||
| SystemClipboard::copyTextToClipboard (selection); | SystemClipboard::copyTextToClipboard (selection); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::copyThenCut() | |||||
| bool CodeEditorComponent::cutToClipboard() | |||||
| { | { | ||||
| copy(); | |||||
| copyToClipboard(); | |||||
| cut(); | cut(); | ||||
| newTransaction(); | newTransaction(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::paste() | |||||
| bool CodeEditorComponent::pasteFromClipboard() | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| const String clip (SystemClipboard::getTextFromClipboard()); | const String clip (SystemClipboard::getTextFromClipboard()); | ||||
| @@ -654,9 +658,10 @@ void CodeEditorComponent::paste() | |||||
| insertTextAtCaret (clip); | insertTextAtCaret (clip); | ||||
| newTransaction(); | newTransaction(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::cursorLeft (const bool moveInWholeWordSteps, const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretLeft (const bool moveInWholeWordSteps, const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -664,9 +669,11 @@ void CodeEditorComponent::cursorLeft (const bool moveInWholeWordSteps, const boo | |||||
| moveCaretTo (document.findWordBreakBefore (caretPos), selecting); | moveCaretTo (document.findWordBreakBefore (caretPos), selecting); | ||||
| else | else | ||||
| moveCaretTo (caretPos.movedBy (-1), selecting); | moveCaretTo (caretPos.movedBy (-1), selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::cursorRight (const bool moveInWholeWordSteps, const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretRight (const bool moveInWholeWordSteps, const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -674,6 +681,8 @@ void CodeEditorComponent::cursorRight (const bool moveInWholeWordSteps, const bo | |||||
| moveCaretTo (document.findWordBreakAfter (caretPos), selecting); | moveCaretTo (document.findWordBreakAfter (caretPos), selecting); | ||||
| else | else | ||||
| moveCaretTo (caretPos.movedBy (1), selecting); | moveCaretTo (caretPos.movedBy (1), selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::moveLineDelta (const int delta, const bool selecting) | void CodeEditorComponent::moveLineDelta (const int delta, const bool selecting) | ||||
| @@ -691,7 +700,7 @@ void CodeEditorComponent::moveLineDelta (const int delta, const bool selecting) | |||||
| columnToTryToMaintain = colToMaintain; | columnToTryToMaintain = colToMaintain; | ||||
| } | } | ||||
| void CodeEditorComponent::cursorDown (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretDown (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -699,9 +708,11 @@ void CodeEditorComponent::cursorDown (const bool selecting) | |||||
| moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting); | moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting); | ||||
| else | else | ||||
| moveLineDelta (1, selecting); | moveLineDelta (1, selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::cursorUp (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretUp (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -709,46 +720,53 @@ void CodeEditorComponent::cursorUp (const bool selecting) | |||||
| moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting); | moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting); | ||||
| else | else | ||||
| moveLineDelta (-1, selecting); | moveLineDelta (-1, selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::pageDown (const bool selecting) | |||||
| bool CodeEditorComponent::pageDown (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| scrollBy (jlimit (0, linesOnScreen, 1 + document.getNumLines() - firstLineOnScreen - linesOnScreen)); | scrollBy (jlimit (0, linesOnScreen, 1 + document.getNumLines() - firstLineOnScreen - linesOnScreen)); | ||||
| moveLineDelta (linesOnScreen, selecting); | moveLineDelta (linesOnScreen, selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::pageUp (const bool selecting) | |||||
| bool CodeEditorComponent::pageUp (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| scrollBy (-linesOnScreen); | scrollBy (-linesOnScreen); | ||||
| moveLineDelta (-linesOnScreen, selecting); | moveLineDelta (-linesOnScreen, selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::scrollUp() | |||||
| bool CodeEditorComponent::scrollUp() | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| scrollBy (1); | scrollBy (1); | ||||
| if (caretPos.getLineNumber() < firstLineOnScreen) | if (caretPos.getLineNumber() < firstLineOnScreen) | ||||
| moveLineDelta (1, false); | moveLineDelta (1, false); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::scrollDown() | |||||
| bool CodeEditorComponent::scrollDown() | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| scrollBy (-1); | scrollBy (-1); | ||||
| if (caretPos.getLineNumber() >= firstLineOnScreen + linesOnScreen) | if (caretPos.getLineNumber() >= firstLineOnScreen + linesOnScreen) | ||||
| moveLineDelta (-1, false); | moveLineDelta (-1, false); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::goToStartOfDocument (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretToTop (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting); | moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting); | ||||
| return true; | |||||
| } | } | ||||
| namespace CodeEditorHelpers | namespace CodeEditorHelpers | ||||
| @@ -771,7 +789,7 @@ namespace CodeEditorHelpers | |||||
| } | } | ||||
| } | } | ||||
| void CodeEditorComponent::goToStartOfLine (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretToStartOfLine (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| @@ -781,21 +799,24 @@ void CodeEditorComponent::goToStartOfLine (const bool selecting) | |||||
| index = 0; | index = 0; | ||||
| moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), index), selecting); | moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), index), selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::goToEndOfDocument (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretToEnd (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting); | moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::goToEndOfLine (const bool selecting) | |||||
| bool CodeEditorComponent::moveCaretToEndOfLine (const bool selecting) | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting); | moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::backspace (const bool moveInWholeWordSteps) | |||||
| bool CodeEditorComponent::deleteBackwards (const bool moveInWholeWordSteps) | |||||
| { | { | ||||
| if (moveInWholeWordSteps) | if (moveInWholeWordSteps) | ||||
| { | { | ||||
| @@ -809,9 +830,10 @@ void CodeEditorComponent::backspace (const bool moveInWholeWordSteps) | |||||
| } | } | ||||
| cut(); | cut(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::deleteForward (const bool moveInWholeWordSteps) | |||||
| bool CodeEditorComponent::deleteForwards (const bool moveInWholeWordSteps) | |||||
| { | { | ||||
| if (moveInWholeWordSteps) | if (moveInWholeWordSteps) | ||||
| { | { | ||||
| @@ -827,26 +849,30 @@ void CodeEditorComponent::deleteForward (const bool moveInWholeWordSteps) | |||||
| } | } | ||||
| cut(); | cut(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::selectAll() | |||||
| bool CodeEditorComponent::selectAll() | |||||
| { | { | ||||
| newTransaction(); | newTransaction(); | ||||
| moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false); | moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false); | ||||
| moveCaretTo (CodeDocument::Position (&document, 0, 0), true); | moveCaretTo (CodeDocument::Position (&document, 0, 0), true); | ||||
| return true; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| void CodeEditorComponent::undo() | |||||
| bool CodeEditorComponent::undo() | |||||
| { | { | ||||
| document.undo(); | document.undo(); | ||||
| scrollToKeepCaretOnScreen(); | scrollToKeepCaretOnScreen(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::redo() | |||||
| bool CodeEditorComponent::redo() | |||||
| { | { | ||||
| document.redo(); | document.redo(); | ||||
| scrollToKeepCaretOnScreen(); | scrollToKeepCaretOnScreen(); | ||||
| return true; | |||||
| } | } | ||||
| void CodeEditorComponent::newTransaction() | void CodeEditorComponent::newTransaction() | ||||
| @@ -881,114 +907,29 @@ const String CodeEditorComponent::getTextInRange (const Range<int>& range) const | |||||
| //============================================================================== | //============================================================================== | ||||
| bool CodeEditorComponent::keyPressed (const KeyPress& key) | bool CodeEditorComponent::keyPressed (const KeyPress& key) | ||||
| { | { | ||||
| const bool moveInWholeWordSteps = key.getModifiers().isCtrlDown() || key.getModifiers().isAltDown(); | |||||
| const bool shiftDown = key.getModifiers().isShiftDown(); | |||||
| if (key.isKeyCode (KeyPress::leftKey)) | |||||
| { | |||||
| cursorLeft (moveInWholeWordSteps, shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::rightKey)) | |||||
| { | |||||
| cursorRight (moveInWholeWordSteps, shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::upKey)) | |||||
| { | |||||
| if (key.getModifiers().isCtrlDown() && ! shiftDown) | |||||
| scrollDown(); | |||||
| #if JUCE_MAC | |||||
| else if (key.getModifiers().isCommandDown()) | |||||
| goToStartOfDocument (shiftDown); | |||||
| #endif | |||||
| else | |||||
| cursorUp (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::downKey)) | |||||
| { | |||||
| if (key.getModifiers().isCtrlDown() && ! shiftDown) | |||||
| scrollUp(); | |||||
| #if JUCE_MAC | |||||
| else if (key.getModifiers().isCommandDown()) | |||||
| goToEndOfDocument (shiftDown); | |||||
| #endif | |||||
| else | |||||
| cursorDown (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::pageDownKey)) | |||||
| { | |||||
| pageDown (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::pageUpKey)) | |||||
| { | |||||
| pageUp (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::homeKey)) | |||||
| { | |||||
| if (moveInWholeWordSteps) | |||||
| goToStartOfDocument (shiftDown); | |||||
| else | |||||
| goToStartOfLine (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::endKey)) | |||||
| if (! TextEditorKeyMapper<CodeEditorComponent>::invokeKeyFunction (*this, key)) | |||||
| { | { | ||||
| if (moveInWholeWordSteps) | |||||
| goToEndOfDocument (shiftDown); | |||||
| if (key == KeyPress::tabKey || key.getTextCharacter() == '\t') | |||||
| { | |||||
| insertTabAtCaret(); | |||||
| } | |||||
| else if (key == KeyPress::returnKey) | |||||
| { | |||||
| newTransaction(); | |||||
| insertTextAtCaret (document.getNewLineCharacters()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::escapeKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| } | |||||
| else if (key.getTextCharacter() >= ' ') | |||||
| { | |||||
| insertTextAtCaret (String::charToString (key.getTextCharacter())); | |||||
| } | |||||
| else | else | ||||
| goToEndOfLine (shiftDown); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::backspaceKey)) | |||||
| { | |||||
| backspace (moveInWholeWordSteps); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::deleteKey)) | |||||
| { | |||||
| deleteForward (moveInWholeWordSteps); | |||||
| } | |||||
| else if (key == KeyPress ('c', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| copy(); | |||||
| } | |||||
| else if (key == KeyPress ('x', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| copyThenCut(); | |||||
| } | |||||
| else if (key == KeyPress ('v', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| paste(); | |||||
| } | |||||
| else if (key == KeyPress ('z', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| undo(); | |||||
| } | |||||
| else if (key == KeyPress ('y', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)) | |||||
| { | |||||
| redo(); | |||||
| } | |||||
| else if (key == KeyPress ('a', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| selectAll(); | |||||
| } | |||||
| else if (key == KeyPress::tabKey || key.getTextCharacter() == '\t') | |||||
| { | |||||
| insertTabAtCaret(); | |||||
| } | |||||
| else if (key == KeyPress::returnKey) | |||||
| { | |||||
| newTransaction(); | |||||
| insertTextAtCaret (document.getNewLineCharacters()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::escapeKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| } | |||||
| else if (key.getTextCharacter() >= ' ') | |||||
| { | |||||
| insertTextAtCaret (String::charToString (key.getTextCharacter())); | |||||
| } | |||||
| else | |||||
| { | |||||
| return false; | |||||
| { | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -116,40 +116,36 @@ public: | |||||
| const CodeDocument::Position getPositionAt (int x, int y); | const CodeDocument::Position getPositionAt (int x, int y); | ||||
| //============================================================================== | //============================================================================== | ||||
| void cursorLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| void cursorRight (bool moveInWholeWordSteps, bool selecting); | |||||
| void cursorDown (bool selecting); | |||||
| void cursorUp (bool selecting); | |||||
| void pageDown (bool selecting); | |||||
| void pageUp (bool selecting); | |||||
| bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretUp (bool selecting); | |||||
| bool moveCaretDown (bool selecting); | |||||
| bool scrollDown(); | |||||
| bool scrollUp(); | |||||
| bool pageUp (bool selecting); | |||||
| bool pageDown (bool selecting); | |||||
| bool moveCaretToTop (bool selecting); | |||||
| bool moveCaretToStartOfLine (bool selecting); | |||||
| bool moveCaretToEnd (bool selecting); | |||||
| bool moveCaretToEndOfLine (bool selecting); | |||||
| bool deleteBackwards (bool moveInWholeWordSteps); | |||||
| bool deleteForwards (bool moveInWholeWordSteps); | |||||
| bool copyToClipboard(); | |||||
| bool cutToClipboard(); | |||||
| bool pasteFromClipboard(); | |||||
| bool undo(); | |||||
| bool redo(); | |||||
| bool selectAll(); | |||||
| void deselectAll(); | |||||
| void scrollDown(); | |||||
| void scrollUp(); | |||||
| void scrollToLine (int newFirstLineOnScreen); | void scrollToLine (int newFirstLineOnScreen); | ||||
| void scrollBy (int deltaLines); | void scrollBy (int deltaLines); | ||||
| void scrollToColumn (int newFirstColumnOnScreen); | void scrollToColumn (int newFirstColumnOnScreen); | ||||
| void scrollToKeepCaretOnScreen(); | void scrollToKeepCaretOnScreen(); | ||||
| void goToStartOfDocument (bool selecting); | |||||
| void goToStartOfLine (bool selecting); | |||||
| void goToEndOfDocument (bool selecting); | |||||
| void goToEndOfLine (bool selecting); | |||||
| void deselectAll(); | |||||
| void selectAll(); | |||||
| void insertTextAtCaret (const String& textToInsert); | void insertTextAtCaret (const String& textToInsert); | ||||
| void insertTabAtCaret(); | void insertTabAtCaret(); | ||||
| void cut(); | |||||
| void copy(); | |||||
| void copyThenCut(); | |||||
| void paste(); | |||||
| void backspace (bool moveInWholeWordSteps); | |||||
| void deleteForward (bool moveInWholeWordSteps); | |||||
| void undo(); | |||||
| void redo(); | |||||
| //============================================================================== | //============================================================================== | ||||
| const Range<int> getHighlightedRegion() const; | const Range<int> getHighlightedRegion() const; | ||||
| @@ -307,6 +303,7 @@ private: | |||||
| void scrollToLineInternal (int line); | void scrollToLineInternal (int line); | ||||
| void scrollToColumnInternal (double column); | void scrollToColumnInternal (double column); | ||||
| void newTransaction(); | void newTransaction(); | ||||
| void cut(); | |||||
| int indexToColumn (int line, int index) const noexcept; | int indexToColumn (int line, int index) const noexcept; | ||||
| int columnToIndex (int line, int column) const noexcept; | int columnToIndex (int line, int column) const noexcept; | ||||
| @@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE | |||||
| #include "../../../text/juce_LocalisedStrings.h" | #include "../../../text/juce_LocalisedStrings.h" | ||||
| #include "../../../io/streams/juce_MemoryOutputStream.h" | #include "../../../io/streams/juce_MemoryOutputStream.h" | ||||
| #include "../lookandfeel/juce_LookAndFeel.h" | #include "../lookandfeel/juce_LookAndFeel.h" | ||||
| #include "../keyboard/juce_TextEditorKeyMapper.h" | |||||
| //============================================================================== | //============================================================================== | ||||
| @@ -1032,20 +1033,28 @@ void TextEditor::newTransaction() | |||||
| undoManager.beginNewTransaction(); | undoManager.beginNewTransaction(); | ||||
| } | } | ||||
| void TextEditor::doUndoRedo (const bool isRedo) | |||||
| bool TextEditor::undoOrRedo (const bool shouldUndo) | |||||
| { | { | ||||
| if (! isReadOnly()) | if (! isReadOnly()) | ||||
| { | { | ||||
| if (isRedo ? undoManager.redo() | |||||
| : undoManager.undo()) | |||||
| newTransaction(); | |||||
| if (shouldUndo ? undoManager.undo() | |||||
| : undoManager.redo()) | |||||
| { | { | ||||
| scrollToMakeSureCursorIsVisible(); | scrollToMakeSureCursorIsVisible(); | ||||
| repaint(); | repaint(); | ||||
| textChanged(); | textChanged(); | ||||
| return true; | |||||
| } | } | ||||
| } | } | ||||
| return false; | |||||
| } | } | ||||
| bool TextEditor::undo() { return undoOrRedo (true); } | |||||
| bool TextEditor::redo() { return undoOrRedo (false); } | |||||
| //============================================================================== | //============================================================================== | ||||
| void TextEditor::setMultiLine (const bool shouldBeMultiLine, | void TextEditor::setMultiLine (const bool shouldBeMultiLine, | ||||
| const bool shouldWordWrap) | const bool shouldWordWrap) | ||||
| @@ -1885,163 +1894,199 @@ void TextEditor::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, flo | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| bool TextEditor::keyPressed (const KeyPress& key) | |||||
| bool TextEditor::moveCaretWithTransation (const int newPos, const bool selecting) | |||||
| { | { | ||||
| if (isReadOnly() && key != KeyPress ('c', ModifierKeys::commandModifier, 0)) | |||||
| return false; | |||||
| newTransaction(); | |||||
| moveCaretTo (newPos, selecting); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::moveCaretLeft (bool moveInWholeWordSteps, bool selecting) | |||||
| { | |||||
| int pos = getCaretPosition(); | |||||
| if (moveInWholeWordSteps) | |||||
| pos = findWordBreakBefore (pos); | |||||
| else | |||||
| --pos; | |||||
| return moveCaretWithTransation (pos, selecting); | |||||
| } | |||||
| bool TextEditor::moveCaretRight (bool moveInWholeWordSteps, bool selecting) | |||||
| { | |||||
| int pos = getCaretPosition(); | |||||
| if (moveInWholeWordSteps) | |||||
| pos = findWordBreakAfter (pos); | |||||
| else | |||||
| ++pos; | |||||
| return moveCaretWithTransation (pos, selecting); | |||||
| } | |||||
| bool TextEditor::moveCaretUp (bool selecting) | |||||
| { | |||||
| if (! isMultiLine()) | |||||
| return moveCaretToStartOfLine (selecting); | |||||
| const bool moveInWholeWordSteps = key.getModifiers().isCtrlDown() || key.getModifiers().isAltDown(); | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | ||||
| return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getY() - 1.0f), selecting); | |||||
| } | |||||
| if (key.isKeyCode (KeyPress::leftKey) | |||||
| || key.isKeyCode (KeyPress::upKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| bool TextEditor::moveCaretDown (bool selecting) | |||||
| { | |||||
| if (! isMultiLine()) | |||||
| return moveCaretToEndOfLine (selecting); | |||||
| int newPos; | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | |||||
| return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getBottom() + 1.0f), selecting); | |||||
| } | |||||
| if (isMultiLine() && key.isKeyCode (KeyPress::upKey)) | |||||
| newPos = indexAtPosition (caretPos.getX(), caretPos.getY() - 1.0f); | |||||
| else if (moveInWholeWordSteps) | |||||
| newPos = findWordBreakBefore (getCaretPosition()); | |||||
| else | |||||
| newPos = getCaretPosition() - 1; | |||||
| bool TextEditor::pageUp (bool selecting) | |||||
| { | |||||
| if (! isMultiLine()) | |||||
| return moveCaretToStartOfLine (selecting); | |||||
| moveCaretTo (newPos, key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::rightKey) | |||||
| || key.isKeyCode (KeyPress::downKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | |||||
| return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), selecting); | |||||
| } | |||||
| int newPos; | |||||
| bool TextEditor::pageDown (bool selecting) | |||||
| { | |||||
| if (! isMultiLine()) | |||||
| return moveCaretToEndOfLine (selecting); | |||||
| if (isMultiLine() && key.isKeyCode (KeyPress::downKey)) | |||||
| newPos = indexAtPosition (caretPos.getX(), caretPos.getBottom() + 1.0f); | |||||
| else if (moveInWholeWordSteps) | |||||
| newPos = findWordBreakAfter (getCaretPosition()); | |||||
| else | |||||
| newPos = getCaretPosition() + 1; | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | |||||
| return moveCaretWithTransation (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), selecting); | |||||
| } | |||||
| moveCaretTo (newPos, key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::pageDownKey) && isMultiLine()) | |||||
| { | |||||
| newTransaction(); | |||||
| void TextEditor::scrollByLines (int deltaLines) | |||||
| { | |||||
| ScrollBar* scrollbar = viewport->getVerticalScrollBar(); | |||||
| moveCaretTo (indexAtPosition (caretPos.getX(), caretPos.getBottom() + viewport->getViewHeight()), | |||||
| key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::pageUpKey) && isMultiLine()) | |||||
| { | |||||
| newTransaction(); | |||||
| if (scrollbar != nullptr) | |||||
| scrollbar->moveScrollbarInSteps (deltaLines); | |||||
| } | |||||
| moveCaretTo (indexAtPosition (caretPos.getX(), caretPos.getY() - viewport->getViewHeight()), | |||||
| key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::homeKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| bool TextEditor::scrollDown() | |||||
| { | |||||
| scrollByLines (-1); | |||||
| return true; | |||||
| } | |||||
| if (isMultiLine() && ! moveInWholeWordSteps) | |||||
| moveCaretTo (indexAtPosition (0.0f, caretPos.getY()), | |||||
| key.getModifiers().isShiftDown()); | |||||
| else | |||||
| moveCaretTo (0, key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::endKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| bool TextEditor::scrollUp() | |||||
| { | |||||
| scrollByLines (1); | |||||
| return true; | |||||
| } | |||||
| if (isMultiLine() && ! moveInWholeWordSteps) | |||||
| moveCaretTo (indexAtPosition ((float) textHolder->getWidth(), caretPos.getY()), | |||||
| key.getModifiers().isShiftDown()); | |||||
| else | |||||
| moveCaretTo (getTotalNumChars(), key.getModifiers().isShiftDown()); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::backspaceKey)) | |||||
| bool TextEditor::moveCaretToTop (bool selecting) | |||||
| { | |||||
| return moveCaretWithTransation (0, selecting); | |||||
| } | |||||
| bool TextEditor::moveCaretToStartOfLine (bool selecting) | |||||
| { | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | |||||
| return moveCaretWithTransation (indexAtPosition (0.0f, caretPos.getY()), selecting); | |||||
| } | |||||
| bool TextEditor::moveCaretToEnd (bool selecting) | |||||
| { | |||||
| return moveCaretWithTransation (getTotalNumChars(), selecting); | |||||
| } | |||||
| bool TextEditor::moveCaretToEndOfLine (bool selecting) | |||||
| { | |||||
| const Rectangle<float> caretPos (getCaretRectangle().toFloat()); | |||||
| return moveCaretWithTransation (indexAtPosition ((float) textHolder->getWidth(), caretPos.getY()), selecting); | |||||
| } | |||||
| bool TextEditor::deleteBackwards (bool moveInWholeWordSteps) | |||||
| { | |||||
| if (moveInWholeWordSteps) | |||||
| moveCaretTo (findWordBreakBefore (getCaretPosition()), true); | |||||
| else if (selection.isEmpty() && selection.getStart() > 0) | |||||
| selection.setStart (selection.getEnd() - 1); | |||||
| cut(); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::deleteForwards (bool /*moveInWholeWordSteps*/) | |||||
| { | |||||
| if (selection.isEmpty() && selection.getStart() < getTotalNumChars()) | |||||
| selection.setEnd (selection.getStart() + 1); | |||||
| cut(); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::copyToClipboard() | |||||
| { | |||||
| newTransaction(); | |||||
| copy(); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::cutToClipboard() | |||||
| { | |||||
| newTransaction(); | |||||
| copy(); | |||||
| cut(); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::pasteFromClipboard() | |||||
| { | |||||
| newTransaction(); | |||||
| paste(); | |||||
| return true; | |||||
| } | |||||
| bool TextEditor::selectAll() | |||||
| { | |||||
| newTransaction(); | |||||
| moveCaretTo (getTotalNumChars(), false); | |||||
| moveCaretTo (0, true); | |||||
| return true; | |||||
| } | |||||
| //============================================================================== | |||||
| bool TextEditor::keyPressed (const KeyPress& key) | |||||
| { | |||||
| if (isReadOnly() && key != KeyPress ('c', ModifierKeys::commandModifier, 0)) | |||||
| return false; | |||||
| if (! TextEditorKeyMapper<TextEditor>::invokeKeyFunction (*this, key)) | |||||
| { | { | ||||
| if (moveInWholeWordSteps) | |||||
| if (key == KeyPress::returnKey) | |||||
| { | { | ||||
| moveCaretTo (findWordBreakBefore (getCaretPosition()), true); | |||||
| newTransaction(); | |||||
| if (returnKeyStartsNewLine) | |||||
| insertTextAtCaret ("\n"); | |||||
| else | |||||
| returnPressed(); | |||||
| } | } | ||||
| else | |||||
| else if (key.isKeyCode (KeyPress::escapeKey)) | |||||
| { | { | ||||
| if (selection.isEmpty() && selection.getStart() > 0) | |||||
| selection.setStart (selection.getEnd() - 1); | |||||
| newTransaction(); | |||||
| moveCaretTo (getCaretPosition(), false); | |||||
| escapePressed(); | |||||
| } | } | ||||
| else if (key.getTextCharacter() >= ' ' | |||||
| || (tabKeyUsed && (key.getTextCharacter() == '\t'))) | |||||
| { | |||||
| insertTextAtCaret (String::charToString (key.getTextCharacter())); | |||||
| cut(); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::deleteKey)) | |||||
| { | |||||
| if (key.getModifiers().isShiftDown()) | |||||
| copy(); | |||||
| if (selection.isEmpty() && selection.getStart() < getTotalNumChars()) | |||||
| selection.setEnd (selection.getStart() + 1); | |||||
| cut(); | |||||
| } | |||||
| else if (key == KeyPress ('c', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| copy(); | |||||
| } | |||||
| else if (key == KeyPress ('x', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| copy(); | |||||
| cut(); | |||||
| } | |||||
| else if (key == KeyPress ('v', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| paste(); | |||||
| } | |||||
| else if (key == KeyPress ('z', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| doUndoRedo (false); | |||||
| } | |||||
| else if (key == KeyPress ('y', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| doUndoRedo (true); | |||||
| } | |||||
| else if (key == KeyPress ('a', ModifierKeys::commandModifier, 0)) | |||||
| { | |||||
| newTransaction(); | |||||
| moveCaretTo (getTotalNumChars(), false); | |||||
| moveCaretTo (0, true); | |||||
| } | |||||
| else if (key == KeyPress::returnKey) | |||||
| { | |||||
| newTransaction(); | |||||
| if (returnKeyStartsNewLine) | |||||
| insertTextAtCaret ("\n"); | |||||
| lastTransactionTime = Time::getApproximateMillisecondCounter(); | |||||
| } | |||||
| else | else | ||||
| returnPressed(); | |||||
| } | |||||
| else if (key.isKeyCode (KeyPress::escapeKey)) | |||||
| { | |||||
| newTransaction(); | |||||
| moveCaretTo (getCaretPosition(), false); | |||||
| escapePressed(); | |||||
| } | |||||
| else if (key.getTextCharacter() >= ' ' | |||||
| || (tabKeyUsed && (key.getTextCharacter() == '\t'))) | |||||
| { | |||||
| insertTextAtCaret (String::charToString (key.getTextCharacter())); | |||||
| lastTransactionTime = Time::getApproximateMillisecondCounter(); | |||||
| } | |||||
| else | |||||
| { | |||||
| return false; | |||||
| { | |||||
| return false; | |||||
| } | |||||
| } | } | ||||
| return true; | return true; | ||||
| @@ -2052,10 +2097,10 @@ bool TextEditor::keyStateChanged (const bool isKeyDown) | |||||
| if (! isKeyDown) | if (! isKeyDown) | ||||
| return false; | return false; | ||||
| #if JUCE_WINDOWS | |||||
| #if JUCE_WINDOWS | |||||
| if (KeyPress (KeyPress::F4Key, ModifierKeys::altModifier, 0).isCurrentlyDown()) | if (KeyPress (KeyPress::F4Key, ModifierKeys::altModifier, 0).isCurrentlyDown()) | ||||
| return false; // We need to explicitly allow alt-F4 to pass through on Windows | return false; // We need to explicitly allow alt-F4 to pass through on Windows | ||||
| #endif | |||||
| #endif | |||||
| // (overridden to avoid forwarding key events to the parent) | // (overridden to avoid forwarding key events to the parent) | ||||
| return ! ModifierKeys::getCurrentModifiers().isCommandDown(); | return ! ModifierKeys::getCurrentModifiers().isCommandDown(); | ||||
| @@ -2091,38 +2136,14 @@ void TextEditor::performPopupMenuAction (const int menuItemID) | |||||
| { | { | ||||
| switch (menuItemID) | switch (menuItemID) | ||||
| { | { | ||||
| case baseMenuItemID + 1: | |||||
| copy(); | |||||
| cut(); | |||||
| break; | |||||
| case baseMenuItemID + 2: | |||||
| copy(); | |||||
| break; | |||||
| case baseMenuItemID + 3: | |||||
| paste(); | |||||
| break; | |||||
| case baseMenuItemID + 4: | |||||
| cut(); | |||||
| break; | |||||
| case baseMenuItemID + 5: | |||||
| moveCaretTo (getTotalNumChars(), false); | |||||
| moveCaretTo (0, true); | |||||
| break; | |||||
| case baseMenuItemID + 6: | |||||
| doUndoRedo (false); | |||||
| break; | |||||
| case baseMenuItemID + 7: | |||||
| doUndoRedo (true); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| case baseMenuItemID + 1: cutToClipboard(); break; | |||||
| case baseMenuItemID + 2: copyToClipboard(); break; | |||||
| case baseMenuItemID + 3: pasteFromClipboard(); break; | |||||
| case baseMenuItemID + 4: cut(); break; | |||||
| case baseMenuItemID + 5: selectAll(); break; | |||||
| case baseMenuItemID + 6: undo(); break; | |||||
| case baseMenuItemID + 7: redo(); break; | |||||
| default: break; | |||||
| } | } | ||||
| } | } | ||||
| @@ -534,6 +534,27 @@ public: | |||||
| /** @internal */ | /** @internal */ | ||||
| void setTemporaryUnderlining (const Array <Range<int> >&); | void setTemporaryUnderlining (const Array <Range<int> >&); | ||||
| bool moveCaretLeft (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretRight (bool moveInWholeWordSteps, bool selecting); | |||||
| bool moveCaretUp (bool selecting); | |||||
| bool moveCaretDown (bool selecting); | |||||
| bool pageUp (bool selecting); | |||||
| bool pageDown (bool selecting); | |||||
| bool scrollDown(); | |||||
| bool scrollUp(); | |||||
| bool moveCaretToTop (bool selecting); | |||||
| bool moveCaretToStartOfLine (bool selecting); | |||||
| bool moveCaretToEnd (bool selecting); | |||||
| bool moveCaretToEndOfLine (bool selecting); | |||||
| bool deleteBackwards (bool moveInWholeWordSteps); | |||||
| bool deleteForwards (bool moveInWholeWordSteps); | |||||
| bool copyToClipboard(); | |||||
| bool cutToClipboard(); | |||||
| bool pasteFromClipboard(); | |||||
| bool selectAll(); | |||||
| bool undo(); | |||||
| bool redo(); | |||||
| //============================================================================== | //============================================================================== | ||||
| /** This adds the items to the popup menu. | /** This adds the items to the popup menu. | ||||
| @@ -668,7 +689,7 @@ private: | |||||
| int indexAtPosition (float x, float y); | int indexAtPosition (float x, float y); | ||||
| int findWordBreakAfter (int position) const; | int findWordBreakAfter (int position) const; | ||||
| int findWordBreakBefore (int position) const; | int findWordBreakBefore (int position) const; | ||||
| bool moveCaretWithTransation (int newPos, bool selecting); | |||||
| friend class TextHolderComponent; | friend class TextHolderComponent; | ||||
| friend class TextEditorViewport; | friend class TextEditorViewport; | ||||
| void drawContent (Graphics& g); | void drawContent (Graphics& g); | ||||
| @@ -676,6 +697,8 @@ private: | |||||
| float getWordWrapWidth() const; | float getWordWrapWidth() const; | ||||
| void timerCallbackInt(); | void timerCallbackInt(); | ||||
| void repaintText (const Range<int>& range); | void repaintText (const Range<int>& range); | ||||
| void scrollByLines (int deltaLines); | |||||
| bool undoOrRedo (bool shouldUndo); | |||||
| UndoManager* getUndoManager() noexcept; | UndoManager* getUndoManager() noexcept; | ||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditor); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextEditor); | ||||
| @@ -0,0 +1,132 @@ | |||||
| /* | |||||
| ============================================================================== | |||||
| This file is part of the JUCE library - "Jules' Utility Class Extensions" | |||||
| Copyright 2004-11 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_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| #define __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| #include "juce_Keypress.h" | |||||
| //============================================================================== | |||||
| /** This class is used to invoke a range of text-editor navigation methods on | |||||
| an object, based upon a keypress event. | |||||
| It's currently used internally by the TextEditor and CodeEditorComponent. | |||||
| */ | |||||
| template <class CallbackClass> | |||||
| struct TextEditorKeyMapper | |||||
| { | |||||
| /** Checks the keypress and invokes one of a range of navigation functions that | |||||
| the target class must implement, based on the key event. | |||||
| */ | |||||
| static bool invokeKeyFunction (CallbackClass& target, const KeyPress& key) | |||||
| { | |||||
| const bool isShiftDown = key.getModifiers().isShiftDown(); | |||||
| const bool ctrlOrAltDown = key.getModifiers().isCtrlDown() || key.getModifiers().isAltDown(); | |||||
| if (key == KeyPress (KeyPress::downKey, ModifierKeys::ctrlModifier, 0) | |||||
| && target.scrollUp()) | |||||
| return true; | |||||
| if (key == KeyPress (KeyPress::upKey, ModifierKeys::ctrlModifier, 0) | |||||
| && target.scrollDown()) | |||||
| return true; | |||||
| #if JUCE_MAC | |||||
| if (key.getModifiers().isCommandDown()) | |||||
| { | |||||
| if (key.isKeyCode (KeyPress::upKey)) | |||||
| return target.moveCaretToTop (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::downKey)) | |||||
| return target.moveCaretToEnd (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::leftKey)) | |||||
| return target.moveCaretToStartOfLine (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::rightKey)) | |||||
| return target.moveCaretToEndOfLine (isShiftDown); | |||||
| } | |||||
| #endif | |||||
| if (key.isKeyCode (KeyPress::upKey)) | |||||
| return target.moveCaretUp (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::downKey)) | |||||
| return target.moveCaretDown (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::leftKey)) | |||||
| return target.moveCaretLeft (ctrlOrAltDown, isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::rightKey)) | |||||
| return target.moveCaretRight (ctrlOrAltDown, isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::pageUpKey)) | |||||
| return target.pageUp (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::pageDownKey)) | |||||
| return target.pageDown (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::homeKey)) | |||||
| return ctrlOrAltDown ? target.moveCaretToTop (isShiftDown) | |||||
| : target.moveCaretToStartOfLine (isShiftDown); | |||||
| if (key.isKeyCode (KeyPress::endKey)) | |||||
| return ctrlOrAltDown ? target.moveCaretToEnd (isShiftDown) | |||||
| : target.moveCaretToEndOfLine (isShiftDown); | |||||
| if (key == KeyPress ('c', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::ctrlModifier, 0)) | |||||
| return target.copyToClipboard(); | |||||
| if (key == KeyPress ('x', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::deleteKey, ModifierKeys::shiftModifier, 0)) | |||||
| return target.cutToClipboard(); | |||||
| if (key == KeyPress ('v', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress (KeyPress::insertKey, ModifierKeys::shiftModifier, 0)) | |||||
| return target.pasteFromClipboard(); | |||||
| if (key.isKeyCode (KeyPress::backspaceKey)) | |||||
| return target.deleteBackwards (ctrlOrAltDown); | |||||
| if (key.isKeyCode (KeyPress::deleteKey)) | |||||
| return target.deleteForwards (ctrlOrAltDown); | |||||
| if (key == KeyPress ('a', ModifierKeys::commandModifier, 0)) | |||||
| return target.selectAll(); | |||||
| if (key == KeyPress ('z', ModifierKeys::commandModifier, 0)) | |||||
| return target.undo(); | |||||
| if (key == KeyPress ('y', ModifierKeys::commandModifier, 0) | |||||
| || key == KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0)) | |||||
| return target.redo(); | |||||
| return false; | |||||
| } | |||||
| }; | |||||
| #endif // __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| @@ -233,7 +233,7 @@ private: | |||||
| sp = stack; | sp = stack; | ||||
| } | } | ||||
| int readLZWByte (const int inputCodeSize) | |||||
| int readLZWByte() | |||||
| { | { | ||||
| if (fresh) | if (fresh) | ||||
| { | { | ||||
| @@ -367,12 +367,13 @@ private: | |||||
| bool readImage (const int interlace, const int transparent) | bool readImage (const int interlace, const int transparent) | ||||
| { | { | ||||
| unsigned char c; | |||||
| if (input.read (&c, 1) != 1) | |||||
| return false; | |||||
| { | |||||
| unsigned char c; | |||||
| if (input.read (&c, 1) != 1) | |||||
| return false; | |||||
| initialise (c); | |||||
| initialise (c); | |||||
| } | |||||
| if (transparent >= 0) | if (transparent >= 0) | ||||
| { | { | ||||
| @@ -389,7 +390,7 @@ private: | |||||
| uint8* p = destData.data; | uint8* p = destData.data; | ||||
| const bool hasAlpha = image.hasAlphaChannel(); | const bool hasAlpha = image.hasAlphaChannel(); | ||||
| while ((index = readLZWByte (c)) >= 0) | |||||
| while ((index = readLZWByte()) >= 0) | |||||
| { | { | ||||
| const uint8* const paletteEntry = palette [index]; | const uint8* const paletteEntry = palette [index]; | ||||
| @@ -74,7 +74,7 @@ bool FileOutputStream::flushBuffer() | |||||
| if (bytesInBuffer > 0) | if (bytesInBuffer > 0) | ||||
| { | { | ||||
| ok = writeInternal (buffer, bytesInBuffer); | |||||
| ok = (writeInternal (buffer, bytesInBuffer) == bytesInBuffer); | |||||
| bytesInBuffer = 0; | bytesInBuffer = 0; | ||||
| } | } | ||||
| @@ -425,6 +425,9 @@ | |||||
| #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | #ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__ | ||||
| #include "gui/components/keyboard/juce_ModifierKeys.h" | #include "gui/components/keyboard/juce_ModifierKeys.h" | ||||
| #endif | #endif | ||||
| #ifndef __JUCE_TEXTEDITORKEYMAPPER_JUCEHEADER__ | |||||
| #include "gui/components/keyboard/juce_TextEditorKeyMapper.h" | |||||
| #endif | |||||
| #ifndef __JUCE_TEXTINPUTTARGET_JUCEHEADER__ | #ifndef __JUCE_TEXTINPUTTARGET_JUCEHEADER__ | ||||
| #include "gui/components/keyboard/juce_TextInputTarget.h" | #include "gui/components/keyboard/juce_TextInputTarget.h" | ||||
| #endif | #endif | ||||
| @@ -29,35 +29,12 @@ | |||||
| //============================================================================== | //============================================================================== | ||||
| #ifndef JUCE_COREAUDIO_ERROR_LOGGING_ENABLED | |||||
| #define JUCE_COREAUDIO_ERROR_LOGGING_ENABLED 1 | |||||
| #endif | |||||
| //============================================================================== | |||||
| #undef log | |||||
| #if JUCE_COREAUDIO_LOGGING_ENABLED | |||||
| #define log(a) Logger::writeToLog (a) | |||||
| #else | |||||
| #define log(a) | |||||
| #endif | |||||
| #undef OK | |||||
| #if JUCE_COREAUDIO_ERROR_LOGGING_ENABLED | |||||
| static bool logAnyErrors_CoreAudio (const OSStatus err, const int lineNum) | |||||
| { | |||||
| if (err == noErr) | |||||
| return true; | |||||
| Logger::writeToLog ("CoreAudio error: " + String (lineNum) + " - " + String::toHexString ((int) err)); | |||||
| return false; | |||||
| } | |||||
| #define OK(a) logAnyErrors_CoreAudio (a, __LINE__) | |||||
| #if JUCE_COREAUDIO_LOGGING_ENABLED //|| ! defined (JUCE_COREAUDIO_LOGGING_ENABLED) | |||||
| #define JUCE_COREAUDIOLOG(a) Logger::writeToLog (a) | |||||
| #else | #else | ||||
| #define OK(a) (a == noErr) | |||||
| #define JUCE_COREAUDIOLOG(a) | |||||
| #endif | #endif | ||||
| //============================================================================== | //============================================================================== | ||||
| class CoreAudioInternal : public Timer | class CoreAudioInternal : public Timer | ||||
| { | { | ||||
| @@ -296,7 +273,7 @@ public: | |||||
| rates << sampleRate; | rates << sampleRate; | ||||
| } | } | ||||
| log ("sr: " + rates); | |||||
| JUCE_COREAUDIOLOG ("sr: " + rates); | |||||
| inputLatency = 0; | inputLatency = 0; | ||||
| outputLatency = 0; | outputLatency = 0; | ||||
| @@ -313,7 +290,7 @@ public: | |||||
| if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr) | if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr) | ||||
| outputLatency = (int) lat; | outputLatency = (int) lat; | ||||
| log ("lat: " + String (inputLatency) + " " + String (outputLatency)); | |||||
| JUCE_COREAUDIOLOG ("lat: " + String (inputLatency) + " " + String (outputLatency)); | |||||
| inChanNames.clear(); | inChanNames.clear(); | ||||
| outChanNames.clear(); | outChanNames.clear(); | ||||
| @@ -422,7 +399,7 @@ public: | |||||
| int bufferSizeSamples) | int bufferSizeSamples) | ||||
| { | { | ||||
| String error; | String error; | ||||
| log ("CoreAudio reopen"); | |||||
| JUCE_COREAUDIOLOG ("CoreAudio reopen"); | |||||
| callbacksAllowed = false; | callbacksAllowed = false; | ||||
| stopTimer(); | stopTimer(); | ||||
| @@ -496,11 +473,11 @@ public: | |||||
| if (deviceID != 0) | if (deviceID != 0) | ||||
| { | { | ||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, this))) | if (OK (AudioDeviceAddIOProc (deviceID, audioIOProc, this))) | ||||
| #else | |||||
| #else | |||||
| if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, this, &audioProcID))) | if (OK (AudioDeviceCreateIOProcID (deviceID, audioIOProc, this, &audioProcID))) | ||||
| #endif | |||||
| #endif | |||||
| { | { | ||||
| if (OK (AudioDeviceStart (deviceID, audioIOProc))) | if (OK (AudioDeviceStart (deviceID, audioIOProc))) | ||||
| { | { | ||||
| @@ -508,12 +485,12 @@ public: | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); | OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); | ||||
| #else | |||||
| #else | |||||
| OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); | OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); | ||||
| audioProcID = 0; | audioProcID = 0; | ||||
| #endif | |||||
| #endif | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -525,10 +502,7 @@ public: | |||||
| callback = cb; | callback = cb; | ||||
| } | } | ||||
| if (inputDevice != nullptr) | |||||
| return started && inputDevice->start (cb); | |||||
| else | |||||
| return started; | |||||
| return started && (inputDevice == nullptr || inputDevice->start (cb)); | |||||
| } | } | ||||
| void stop (bool leaveInterruptRunning) | void stop (bool leaveInterruptRunning) | ||||
| @@ -544,12 +518,13 @@ public: | |||||
| { | { | ||||
| OK (AudioDeviceStop (deviceID, audioIOProc)); | OK (AudioDeviceStop (deviceID, audioIOProc)); | ||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | |||||
| OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); | OK (AudioDeviceRemoveIOProc (deviceID, audioIOProc)); | ||||
| #else | |||||
| #else | |||||
| OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); | OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID)); | ||||
| audioProcID = 0; | audioProcID = 0; | ||||
| #endif | |||||
| #endif | |||||
| started = false; | started = false; | ||||
| { const ScopedLock sl (callbackLock); } | { const ScopedLock sl (callbackLock); } | ||||
| @@ -580,15 +555,8 @@ public: | |||||
| inputDevice->stop (leaveInterruptRunning); | inputDevice->stop (leaveInterruptRunning); | ||||
| } | } | ||||
| double getSampleRate() const | |||||
| { | |||||
| return sampleRate; | |||||
| } | |||||
| int getBufferSize() const | |||||
| { | |||||
| return bufferSize; | |||||
| } | |||||
| double getSampleRate() const { return sampleRate; } | |||||
| int getBufferSize() const { return bufferSize; } | |||||
| void audioCallback (const AudioBufferList* inInputData, | void audioCallback (const AudioBufferList* inInputData, | ||||
| AudioBufferList* outOutputData) | AudioBufferList* outOutputData) | ||||
| @@ -695,7 +663,7 @@ public: | |||||
| void timerCallback() | void timerCallback() | ||||
| { | { | ||||
| stopTimer(); | stopTimer(); | ||||
| log ("CoreAudio device changed callback"); | |||||
| JUCE_COREAUDIOLOG ("CoreAudio device changed callback"); | |||||
| const double oldSampleRate = sampleRate; | const double oldSampleRate = sampleRate; | ||||
| const int oldBufferSize = bufferSize; | const int oldBufferSize = bufferSize; | ||||
| @@ -759,9 +727,9 @@ public: | |||||
| Array <double> sampleRates; | Array <double> sampleRates; | ||||
| Array <int> bufferSizes; | Array <int> bufferSizes; | ||||
| AudioIODeviceCallback* callback; | AudioIODeviceCallback* callback; | ||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 | |||||
| #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 | |||||
| AudioDeviceIOProcID audioProcID; | AudioDeviceIOProcID audioProcID; | ||||
| #endif | |||||
| #endif | |||||
| ScopedPointer<CoreAudioInternal> inputDevice; | ScopedPointer<CoreAudioInternal> inputDevice; | ||||
| bool isSlaveDevice; | bool isSlaveDevice; | ||||
| @@ -836,17 +804,31 @@ private: | |||||
| UInt32 size = 0; | UInt32 size = 0; | ||||
| if (deviceID != 0 | if (deviceID != 0 | ||||
| && OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) | |||||
| && AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size) == noErr) | |||||
| { | { | ||||
| types.calloc (size, 1); | types.calloc (size, 1); | ||||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, types))) | |||||
| if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, types) == noErr) | |||||
| return size / (int) sizeof (OSType); | return size / (int) sizeof (OSType); | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| bool OK (const OSStatus errorCode) const | |||||
| { | |||||
| if (errorCode == noErr) | |||||
| return true; | |||||
| const String errorMessage ("CoreAudio error: " + String::toHexString ((int) errorCode)); | |||||
| JUCE_COREAUDIOLOG (errorMessage); | |||||
| if (callback != nullptr) | |||||
| callback->audioDeviceError (errorMessage); | |||||
| return false; | |||||
| } | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioInternal); | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioInternal); | ||||
| }; | }; | ||||
| @@ -888,6 +870,7 @@ public: | |||||
| } | } | ||||
| internal = device; | internal = device; | ||||
| jassert (device != nullptr); | |||||
| AudioObjectPropertyAddress pa; | AudioObjectPropertyAddress pa; | ||||
| pa.mSelector = kAudioObjectPropertySelectorWildcard; | pa.mSelector = kAudioObjectPropertySelectorWildcard; | ||||
| @@ -922,25 +905,17 @@ public: | |||||
| return internal->inChanNames; | return internal->inChanNames; | ||||
| } | } | ||||
| int getNumSampleRates() | |||||
| { | |||||
| return internal->sampleRates.size(); | |||||
| } | |||||
| bool isOpen() { return isOpen_; } | |||||
| double getSampleRate (int index) | |||||
| { | |||||
| return internal->sampleRates [index]; | |||||
| } | |||||
| int getNumSampleRates() { return internal->sampleRates.size(); } | |||||
| double getSampleRate (int index) { return internal->sampleRates [index]; } | |||||
| double getCurrentSampleRate() { return internal->getSampleRate(); } | |||||
| int getNumBufferSizesAvailable() | |||||
| { | |||||
| return internal->bufferSizes.size(); | |||||
| } | |||||
| int getCurrentBitDepth() { return 32; } // no way to find out, so just assume it's high.. | |||||
| int getBufferSizeSamples (int index) | |||||
| { | |||||
| return internal->bufferSizes [index]; | |||||
| } | |||||
| int getNumBufferSizesAvailable() { return internal->bufferSizes.size(); } | |||||
| int getBufferSizeSamples (int index) { return internal->bufferSizes [index]; } | |||||
| int getCurrentBufferSizeSamples() { return internal->getBufferSize(); } | |||||
| int getDefaultBufferSize() | int getDefaultBufferSize() | ||||
| { | { | ||||
| @@ -972,51 +947,23 @@ public: | |||||
| internal->stop (false); | internal->stop (false); | ||||
| } | } | ||||
| bool isOpen() | |||||
| { | |||||
| return isOpen_; | |||||
| } | |||||
| int getCurrentBufferSizeSamples() | |||||
| { | |||||
| return internal != nullptr ? internal->getBufferSize() : 512; | |||||
| } | |||||
| double getCurrentSampleRate() | |||||
| { | |||||
| return internal != nullptr ? internal->getSampleRate() : 0; | |||||
| } | |||||
| int getCurrentBitDepth() | |||||
| { | |||||
| return 32; // no way to find out, so just assume it's high.. | |||||
| } | |||||
| const BigInteger getActiveOutputChannels() const | const BigInteger getActiveOutputChannels() const | ||||
| { | { | ||||
| return internal != nullptr ? internal->activeOutputChans : BigInteger(); | |||||
| return internal->activeOutputChans; | |||||
| } | } | ||||
| const BigInteger getActiveInputChannels() const | const BigInteger getActiveInputChannels() const | ||||
| { | { | ||||
| BigInteger chans; | |||||
| BigInteger chans (internal->activeInputChans); | |||||
| if (internal != nullptr) | |||||
| { | |||||
| chans = internal->activeInputChans; | |||||
| if (internal->inputDevice != 0) | |||||
| chans |= internal->inputDevice->activeInputChans; | |||||
| } | |||||
| if (internal->inputDevice != nullptr) | |||||
| chans |= internal->inputDevice->activeInputChans; | |||||
| return chans; | return chans; | ||||
| } | } | ||||
| int getOutputLatencyInSamples() | int getOutputLatencyInSamples() | ||||
| { | { | ||||
| if (internal == nullptr) | |||||
| return 0; | |||||
| // this seems like a good guess at getting the latency right - comparing | // this seems like a good guess at getting the latency right - comparing | ||||
| // this with a round-trip measurement, it gets it to within a few millisecs | // this with a round-trip measurement, it gets it to within a few millisecs | ||||
| // for the built-in mac soundcard | // for the built-in mac soundcard | ||||
| @@ -1025,15 +972,12 @@ public: | |||||
| int getInputLatencyInSamples() | int getInputLatencyInSamples() | ||||
| { | { | ||||
| if (internal == nullptr) | |||||
| return 0; | |||||
| return internal->inputLatency + internal->getBufferSize() * 2; | return internal->inputLatency + internal->getBufferSize() * 2; | ||||
| } | } | ||||
| void start (AudioIODeviceCallback* callback) | void start (AudioIODeviceCallback* callback) | ||||
| { | { | ||||
| if (internal != nullptr && ! isStarted) | |||||
| if (! isStarted) | |||||
| { | { | ||||
| if (callback != nullptr) | if (callback != nullptr) | ||||
| callback->audioDeviceAboutToStart (this); | callback->audioDeviceAboutToStart (this); | ||||
| @@ -1045,7 +989,7 @@ public: | |||||
| void stop() | void stop() | ||||
| { | { | ||||
| if (isStarted && internal != nullptr) | |||||
| if (isStarted) | |||||
| { | { | ||||
| AudioIODeviceCallback* const lastCallback = internal->callback; | AudioIODeviceCallback* const lastCallback = internal->callback; | ||||
| @@ -1110,10 +1054,6 @@ public: | |||||
| { | { | ||||
| } | } | ||||
| ~CoreAudioIODeviceType() | |||||
| { | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void scanForDevices() | void scanForDevices() | ||||
| { | { | ||||
| @@ -1131,12 +1071,12 @@ public: | |||||
| pa.mScope = kAudioObjectPropertyScopeWildcard; | pa.mScope = kAudioObjectPropertyScopeWildcard; | ||||
| pa.mElement = kAudioObjectPropertyElementMaster; | pa.mElement = kAudioObjectPropertyElementMaster; | ||||
| if (OK (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size))) | |||||
| if (AudioObjectGetPropertyDataSize (kAudioObjectSystemObject, &pa, 0, 0, &size) == noErr) | |||||
| { | { | ||||
| HeapBlock <AudioDeviceID> devs; | HeapBlock <AudioDeviceID> devs; | ||||
| devs.calloc (size, 1); | devs.calloc (size, 1); | ||||
| if (OK (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, devs))) | |||||
| if (AudioObjectGetPropertyData (kAudioObjectSystemObject, &pa, 0, 0, &size, devs) == noErr) | |||||
| { | { | ||||
| const int num = size / (int) sizeof (AudioDeviceID); | const int num = size / (int) sizeof (AudioDeviceID); | ||||
| for (int i = 0; i < num; ++i) | for (int i = 0; i < num; ++i) | ||||
| @@ -1145,7 +1085,7 @@ public: | |||||
| size = sizeof (name); | size = sizeof (name); | ||||
| pa.mSelector = kAudioDevicePropertyDeviceName; | pa.mSelector = kAudioDevicePropertyDeviceName; | ||||
| if (OK (AudioObjectGetPropertyData (devs[i], &pa, 0, 0, &size, name))) | |||||
| if (AudioObjectGetPropertyData (devs[i], &pa, 0, 0, &size, name) == noErr) | |||||
| { | { | ||||
| const String nameString (String::fromUTF8 (name, (int) strlen (name))); | const String nameString (String::fromUTF8 (name, (int) strlen (name))); | ||||
| const int numIns = getNumChannels (devs[i], true); | const int numIns = getNumChannels (devs[i], true); | ||||
| @@ -1175,10 +1115,8 @@ public: | |||||
| { | { | ||||
| jassert (hasScanned); // need to call scanForDevices() before doing this | jassert (hasScanned); // need to call scanForDevices() before doing this | ||||
| if (wantInputNames) | |||||
| return inputDeviceNames; | |||||
| else | |||||
| return outputDeviceNames; | |||||
| return wantInputNames ? inputDeviceNames | |||||
| : outputDeviceNames; | |||||
| } | } | ||||
| int getDefaultDeviceIndex (bool forInput) const | int getDefaultDeviceIndex (bool forInput) const | ||||
| @@ -1268,12 +1206,12 @@ private: | |||||
| pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; | pa.mScope = input ? kAudioDevicePropertyScopeInput : kAudioDevicePropertyScopeOutput; | ||||
| pa.mElement = kAudioObjectPropertyElementMaster; | pa.mElement = kAudioObjectPropertyElementMaster; | ||||
| if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size))) | |||||
| if (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size) == noErr) | |||||
| { | { | ||||
| HeapBlock <AudioBufferList> bufList; | HeapBlock <AudioBufferList> bufList; | ||||
| bufList.calloc (size, 1); | bufList.calloc (size, 1); | ||||
| if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList))) | |||||
| if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList) == noErr) | |||||
| { | { | ||||
| const int numStreams = bufList->mNumberBuffers; | const int numStreams = bufList->mNumberBuffers; | ||||
| @@ -1297,6 +1235,6 @@ AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() | |||||
| return new CoreAudioIODeviceType(); | return new CoreAudioIODeviceType(); | ||||
| } | } | ||||
| #undef log | |||||
| #undef JUCE_COREAUDIOLOG | |||||
| #endif | #endif | ||||