mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-11 23:54:18 +00:00
Added a maximum length to String::copyToUTF8(), tweaked the parameters to AudioFormatWriter::writeFromAudioReader(), altered the BWAV chunk code to store its text as UTF8, added a utility function WavAudioFormat::replaceMetadataInFile(). Sorted out some compile errors with plugin hosting code. Fixed a small glitch in ColourGradient, and added a method to TreeViewItems to allow some items to be made non-selectable.
This commit is contained in:
parent
058d5b9574
commit
0a551e2242
19 changed files with 862 additions and 100 deletions
|
|
@ -62,9 +62,7 @@ public:
|
|||
if (JUCEApplication::getInstance() != 0)
|
||||
{
|
||||
JUCEApplication::getInstance()->systemRequestedQuit();
|
||||
|
||||
if (! MessageManager::getInstance()->hasStopMessageBeenSent())
|
||||
return NSTerminateCancel;
|
||||
return NSTerminateCancel;
|
||||
}
|
||||
|
||||
return NSTerminateNow;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Version="9.00"
|
||||
Name="JUCE"
|
||||
ProjectGUID="{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}"
|
||||
RootNamespace="JUCE"
|
||||
TargetFrameworkVersion="131072"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
|
|
@ -207,6 +208,8 @@
|
|||
AdditionalOptions="/IMPLIB:".\..\..\..\bin\JUCE_debug.lib"
"
|
||||
OutputFile="$(OutDir)\$(ProjectName)_debug.dll"
|
||||
IgnoreDefaultLibraryNames="libcmt.lib"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
|
@ -228,9 +231,6 @@
|
|||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
|
|
@ -289,6 +289,8 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
IgnoreDefaultLibraryNames="libcmtd.lib"
|
||||
RandomizedBaseAddress="1"
|
||||
DataExecutionPrevention="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
|
@ -310,9 +312,6 @@
|
|||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#define JUCE_PLUGINHOST_VST 1
|
||||
#define JUCE_PLUGINHOST_AU 1
|
||||
#define JUCE_SUPPORT_CARBON 1
|
||||
//#define JUCE_ONLY_BUILD_CORE_LIBRARY 1
|
||||
//#define JUCE_FORCE_DEBUG 1
|
||||
//#define JUCE_LOG_ASSERTIONS 1
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jucedemo", "jucedemo.vcproj", "{050D65C2-17C4-4EE1-ABCE-BEA9DA83D77A}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26} = {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JUCE", "..\..\..\..\build\win32\vc8\JUCE.vcproj", "{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}"
|
||||
EndProject
|
||||
|
|
|
|||
|
|
@ -185,6 +185,16 @@
|
|||
#define JUCE_WEB_BROWSER 1
|
||||
#endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
/** Setting this allows the build to use old Carbon libraries that will be
|
||||
deprecated in newer versions of OSX. This is handy for some backwards-compatibility
|
||||
reasons.
|
||||
*/
|
||||
#ifndef JUCE_SUPPORT_CARBON
|
||||
#define JUCE_SUPPORT_CARBON 1
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
/* These flags let you avoid the direct inclusion of some 3rd-party libs in the
|
||||
codebase - you might need to use this if you're linking to some of these libraries
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -221,6 +221,14 @@
|
|||
#define JUCE_WEB_BROWSER 1
|
||||
#endif
|
||||
|
||||
/** Setting this allows the build to use old Carbon libraries that will be
|
||||
deprecated in newer versions of OSX. This is handy for some backwards-compatibility
|
||||
reasons.
|
||||
*/
|
||||
#ifndef JUCE_SUPPORT_CARBON
|
||||
#define JUCE_SUPPORT_CARBON 1
|
||||
#endif
|
||||
|
||||
/* These flags let you avoid the direct inclusion of some 3rd-party libs in the
|
||||
codebase - you might need to use this if you're linking to some of these libraries
|
||||
yourself.
|
||||
|
|
@ -2347,8 +2355,13 @@ public:
|
|||
@param destBuffer the place to copy it to; if this is a null pointer,
|
||||
the method just returns the number of bytes required
|
||||
(including the terminating null character).
|
||||
@param maxBufferSizeBytes the size of the destination buffer, in bytes. If the
|
||||
string won't fit, it'll put in as many as it can while
|
||||
still allowing for a terminating null char at the end,
|
||||
and will return the number of bytes that were actually
|
||||
used. If this value is < 0, no limit is used.
|
||||
*/
|
||||
int copyToUTF8 (uint8* const destBuffer) const throw();
|
||||
int copyToUTF8 (uint8* const destBuffer, const int maxBufferSizeBytes = 0x7fffffff) const throw();
|
||||
|
||||
/** Returns a pointer to a UTF-8 version of this string.
|
||||
|
||||
|
|
@ -36083,11 +36096,13 @@ public:
|
|||
This will take care of any floating-point conversion that's required to convert
|
||||
between the two formats. It won't deal with sample-rate conversion, though.
|
||||
|
||||
If numSamplesToRead < 0, it will write the entire length of the reader.
|
||||
|
||||
@returns false if it can't read or write properly during the operation
|
||||
*/
|
||||
bool writeFromAudioReader (AudioFormatReader& reader,
|
||||
int64 startSample,
|
||||
int numSamplesToRead);
|
||||
int64 numSamplesToRead);
|
||||
|
||||
/** Reads some samples from an AudioSource, and writes these to the output.
|
||||
|
||||
|
|
@ -37229,6 +37244,13 @@ public:
|
|||
const StringPairArray& metadataValues,
|
||||
int qualityOptionIndex);
|
||||
|
||||
/** Utility function to replace the metadata in a wav file with a new set of values.
|
||||
|
||||
If possible, this cheats by overwriting just the metadata region of the file, rather
|
||||
than by copying the whole file again.
|
||||
*/
|
||||
bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata);
|
||||
|
||||
juce_UseDebuggingNewOperator
|
||||
};
|
||||
|
||||
|
|
@ -43050,6 +43072,11 @@ public:
|
|||
*/
|
||||
virtual int getItemHeight() const { return 20; }
|
||||
|
||||
/** You can override this method to return false if you don't want to allow the
|
||||
user to select this item.
|
||||
*/
|
||||
virtual bool canBeSelected() const { return true; }
|
||||
|
||||
/** Creates a component that will be used to represent this item.
|
||||
|
||||
You don't have to implement this method - if it returns 0 then no component
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
#pragma warning (disable: 4309 4305)
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC && JUCE_SUPPORT_CARBON
|
||||
#if JUCE_MAC && JUCE_32BIT && JUCE_SUPPORT_CARBON
|
||||
BEGIN_JUCE_NAMESPACE
|
||||
#include "../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ AudioFormatWriter::~AudioFormatWriter()
|
|||
|
||||
bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
|
||||
int64 startSample,
|
||||
int numSamplesToRead)
|
||||
int64 numSamplesToRead)
|
||||
{
|
||||
const int bufferSize = 16384;
|
||||
const int maxChans = 128;
|
||||
|
|
@ -340,9 +340,12 @@ bool AudioFormatWriter::writeFromAudioReader (AudioFormatReader& reader,
|
|||
for (int i = maxChans; --i >= 0;)
|
||||
buffers[i] = 0;
|
||||
|
||||
if (numSamplesToRead < 0)
|
||||
numSamplesToRead = reader.lengthInSamples;
|
||||
|
||||
while (numSamplesToRead > 0)
|
||||
{
|
||||
const int numToDo = jmin (numSamplesToRead, bufferSize);
|
||||
const int numToDo = (int) jmin (numSamplesToRead, (int64) bufferSize);
|
||||
|
||||
for (int i = tempBuffer.getNumChannels(); --i >= 0;)
|
||||
buffers[i] = (int*) tempBuffer.getSampleData (i, 0);
|
||||
|
|
|
|||
|
|
@ -112,11 +112,13 @@ public:
|
|||
This will take care of any floating-point conversion that's required to convert
|
||||
between the two formats. It won't deal with sample-rate conversion, though.
|
||||
|
||||
If numSamplesToRead < 0, it will write the entire length of the reader.
|
||||
|
||||
@returns false if it can't read or write properly during the operation
|
||||
*/
|
||||
bool writeFromAudioReader (AudioFormatReader& reader,
|
||||
int64 startSample,
|
||||
int numSamplesToRead);
|
||||
int64 numSamplesToRead);
|
||||
|
||||
/** Reads some samples from an AudioSource, and writes these to the output.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "juce_WavAudioFormat.h"
|
||||
#include "../../../juce_core/io/streams/juce_BufferedInputStream.h"
|
||||
#include "../../../juce_core/text/juce_LocalisedStrings.h"
|
||||
#include "../../../juce_core/io/files/juce_FileInputStream.h"
|
||||
#include "../../../juce_core/io/files/juce_FileOutputStream.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -85,55 +87,55 @@ const StringPairArray WavAudioFormat::createBWAVMetadata (const String& descript
|
|||
|
||||
struct BWAVChunk
|
||||
{
|
||||
char description [256];
|
||||
char originator [32];
|
||||
char originatorRef [32];
|
||||
char originationDate [10];
|
||||
char originationTime [8];
|
||||
uint8 description [256];
|
||||
uint8 originator [32];
|
||||
uint8 originatorRef [32];
|
||||
uint8 originationDate [10];
|
||||
uint8 originationTime [8];
|
||||
uint32 timeRefLow;
|
||||
uint32 timeRefHigh;
|
||||
uint16 version;
|
||||
uint8 umid[64];
|
||||
uint8 reserved[190];
|
||||
char codingHistory[1];
|
||||
uint8 codingHistory[1];
|
||||
|
||||
void copyTo (StringPairArray& values) const
|
||||
{
|
||||
values.set (WavAudioFormat::bwavDescription, String (description, 256));
|
||||
values.set (WavAudioFormat::bwavOriginator, String (originator, 32));
|
||||
values.set (WavAudioFormat::bwavOriginatorRef, String (originatorRef, 32));
|
||||
values.set (WavAudioFormat::bwavOriginationDate, String (originationDate, 10));
|
||||
values.set (WavAudioFormat::bwavOriginationTime, String (originationTime, 8));
|
||||
values.set (WavAudioFormat::bwavDescription, String::fromUTF8 (description, 256));
|
||||
values.set (WavAudioFormat::bwavOriginator, String::fromUTF8 (originator, 32));
|
||||
values.set (WavAudioFormat::bwavOriginatorRef, String::fromUTF8 (originatorRef, 32));
|
||||
values.set (WavAudioFormat::bwavOriginationDate, String::fromUTF8 (originationDate, 10));
|
||||
values.set (WavAudioFormat::bwavOriginationTime, String::fromUTF8 (originationTime, 8));
|
||||
|
||||
const uint32 timeLow = swapIfBigEndian (timeRefLow);
|
||||
const uint32 timeHigh = swapIfBigEndian (timeRefHigh);
|
||||
const int64 time = (((int64)timeHigh) << 32) + timeLow;
|
||||
|
||||
values.set (WavAudioFormat::bwavTimeReference, String (time));
|
||||
values.set (WavAudioFormat::bwavCodingHistory, String (codingHistory));
|
||||
values.set (WavAudioFormat::bwavCodingHistory, String::fromUTF8 (codingHistory));
|
||||
}
|
||||
|
||||
static MemoryBlock createFrom (const StringPairArray& values)
|
||||
{
|
||||
const int sizeNeeded = sizeof (BWAVChunk) + values [WavAudioFormat::bwavCodingHistory].length();
|
||||
const int sizeNeeded = sizeof (BWAVChunk) + values [WavAudioFormat::bwavCodingHistory].copyToUTF8 (0) - 1;
|
||||
MemoryBlock data ((sizeNeeded + 3) & ~3);
|
||||
data.fillWith (0);
|
||||
|
||||
BWAVChunk* b = (BWAVChunk*) data.getData();
|
||||
|
||||
// although copyToBuffer may overrun by one byte, that's ok as long as these
|
||||
// operations get done in the right order
|
||||
values [WavAudioFormat::bwavDescription].copyToBuffer (b->description, 256);
|
||||
values [WavAudioFormat::bwavOriginator].copyToBuffer (b->originator, 32);
|
||||
values [WavAudioFormat::bwavOriginatorRef].copyToBuffer (b->originatorRef, 32);
|
||||
values [WavAudioFormat::bwavOriginationDate].copyToBuffer (b->originationDate, 10);
|
||||
values [WavAudioFormat::bwavOriginationTime].copyToBuffer (b->originationTime, 8);
|
||||
// Allow these calls to overwrite an extra byte at the end, which is fine as long
|
||||
// as they get called in the right order..
|
||||
values [WavAudioFormat::bwavDescription].copyToUTF8 (b->description, 257);
|
||||
values [WavAudioFormat::bwavOriginator].copyToUTF8 (b->originator, 33);
|
||||
values [WavAudioFormat::bwavOriginatorRef].copyToUTF8 (b->originatorRef, 33);
|
||||
values [WavAudioFormat::bwavOriginationDate].copyToUTF8 (b->originationDate, 11);
|
||||
values [WavAudioFormat::bwavOriginationTime].copyToUTF8 (b->originationTime, 9);
|
||||
|
||||
const int64 time = values [WavAudioFormat::bwavTimeReference].getLargeIntValue();
|
||||
b->timeRefLow = swapIfBigEndian ((uint32) (time & 0xffffffff));
|
||||
b->timeRefHigh = swapIfBigEndian ((uint32) (time >> 32));
|
||||
|
||||
values [WavAudioFormat::bwavCodingHistory].copyToBuffer (b->codingHistory, 256 * 1024);
|
||||
values [WavAudioFormat::bwavCodingHistory].copyToUTF8 (b->codingHistory);
|
||||
|
||||
if (b->description[0] != 0
|
||||
|| b->originator[0] != 0
|
||||
|
|
@ -169,10 +171,14 @@ class WavAudioFormatReader : public AudioFormatReader
|
|||
const WavAudioFormatReader& operator= (const WavAudioFormatReader&);
|
||||
|
||||
public:
|
||||
int64 bwavChunkStart, bwavSize;
|
||||
|
||||
//==============================================================================
|
||||
WavAudioFormatReader (InputStream* const in)
|
||||
: AudioFormatReader (in, wavFormatName),
|
||||
dataLength (0)
|
||||
dataLength (0),
|
||||
bwavChunkStart (0),
|
||||
bwavSize (0)
|
||||
{
|
||||
if (input->readInt() == chunkName ("RIFF"))
|
||||
{
|
||||
|
|
@ -220,6 +226,9 @@ public:
|
|||
}
|
||||
else if (chunkType == chunkName ("bext"))
|
||||
{
|
||||
bwavChunkStart = input->getPosition();
|
||||
bwavSize = length;
|
||||
|
||||
// Broadcast-wav extension chunk..
|
||||
BWAVChunk* const bwav = (BWAVChunk*) juce_calloc (jmax (length + 1, (int) sizeof (BWAVChunk)));
|
||||
|
||||
|
|
@ -752,4 +761,82 @@ AudioFormatWriter* WavAudioFormat::createWriterFor (OutputStream* out,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool juce_slowCopyOfWavFileWithNewMetadata (const File& file, const StringPairArray& metadata)
|
||||
{
|
||||
bool ok = false;
|
||||
WavAudioFormat wav;
|
||||
|
||||
const File dest (file.getNonexistentSibling());
|
||||
|
||||
OutputStream* outStream = dest.createOutputStream();
|
||||
|
||||
if (outStream != 0)
|
||||
{
|
||||
AudioFormatReader* reader = wav.createReaderFor (file.createInputStream(), true);
|
||||
|
||||
if (reader != 0)
|
||||
{
|
||||
AudioFormatWriter* writer = wav.createWriterFor (outStream, reader->sampleRate,
|
||||
reader->numChannels, reader->bitsPerSample,
|
||||
metadata, 0);
|
||||
|
||||
if (writer != 0)
|
||||
{
|
||||
ok = writer->writeFromAudioReader (*reader, 0, -1);
|
||||
|
||||
outStream = 0;
|
||||
delete writer;
|
||||
}
|
||||
|
||||
delete reader;
|
||||
}
|
||||
|
||||
delete outStream;
|
||||
}
|
||||
|
||||
if (ok)
|
||||
ok = dest.moveFileTo (file);
|
||||
|
||||
if (! ok)
|
||||
dest.deleteFile();
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool WavAudioFormat::replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata)
|
||||
{
|
||||
WavAudioFormatReader* reader = (WavAudioFormatReader*) createReaderFor (wavFile.createInputStream(), true);
|
||||
|
||||
if (reader != 0)
|
||||
{
|
||||
const int64 bwavPos = reader->bwavChunkStart;
|
||||
const int64 bwavSize = reader->bwavSize;
|
||||
delete reader;
|
||||
|
||||
if (bwavSize > 0)
|
||||
{
|
||||
MemoryBlock chunk = BWAVChunk::createFrom (newMetadata);
|
||||
|
||||
if (chunk.getSize() <= bwavSize)
|
||||
{
|
||||
// the new one will fit in the space available, so write it directly..
|
||||
const int64 oldSize = wavFile.getSize();
|
||||
|
||||
FileOutputStream* out = wavFile.createOutputStream();
|
||||
out->setPosition (bwavPos);
|
||||
out->write (chunk.getData(), chunk.getSize());
|
||||
out->setPosition (oldSize);
|
||||
delete out;
|
||||
|
||||
jassert (wavFile.getSize() == oldSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return juce_slowCopyOfWavFileWithNewMetadata (wavFile, newMetadata);
|
||||
}
|
||||
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -141,6 +141,13 @@ public:
|
|||
const StringPairArray& metadataValues,
|
||||
int qualityOptionIndex);
|
||||
|
||||
//==============================================================================
|
||||
/** Utility function to replace the metadata in a wav file with a new set of values.
|
||||
|
||||
If possible, this cheats by overwriting just the metadata region of the file, rather
|
||||
than by copying the whole file again.
|
||||
*/
|
||||
bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata);
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@
|
|||
#include <AudioUnit/AUCocoaUIView.h>
|
||||
#include <CoreAudioKit/AUGenericView.h>
|
||||
|
||||
#if JUCE_MAC && JUCE_32BIT
|
||||
#define JUCE_SUPPORT_CARBON 1
|
||||
#endif
|
||||
|
||||
#if JUCE_SUPPORT_CARBON
|
||||
#include <AudioToolbox/AudioUnitUtilities.h>
|
||||
#include <AudioUnit/AudioUnitCarbonView.h>
|
||||
|
|
@ -57,6 +53,9 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../../juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../../juce_appframework/gui/components/layout/juce_ComponentMovementWatcher.h"
|
||||
#include "../../../../juce_appframework/gui/components/special/juce_NSViewComponent.h"
|
||||
#if JUCE_MAC && JUCE_SUPPORT_CARBON
|
||||
#include "../../../../../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
#endif
|
||||
|
||||
#if JUCE_MAC
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,10 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../gui/components/layout/juce_ComponentMovementWatcher.h"
|
||||
#include "../../../application/juce_Application.h"
|
||||
#include "../../../../juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../../../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
|
||||
#if JUCE_MAC && JUCE_SUPPORT_CARBON
|
||||
#include "../../../../../build/macosx/platform_specific_code/juce_mac_CarbonViewWrapperComponent.h"
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
#undef PRAGMA_ALIGN_SUPPORTED
|
||||
|
|
|
|||
|
|
@ -572,6 +572,9 @@ void TreeView::resized()
|
|||
|
||||
void TreeView::moveSelectedRow (int delta)
|
||||
{
|
||||
if (delta == 0)
|
||||
return;
|
||||
|
||||
int rowSelected = 0;
|
||||
|
||||
TreeViewItem* const firstSelected = getSelectedItem (0);
|
||||
|
|
@ -580,13 +583,36 @@ void TreeView::moveSelectedRow (int delta)
|
|||
|
||||
rowSelected = jlimit (0, getNumRowsInTree() - 1, rowSelected + delta);
|
||||
|
||||
TreeViewItem* item = getItemOnRow (rowSelected);
|
||||
|
||||
if (item != 0)
|
||||
for (;;)
|
||||
{
|
||||
item->setSelected (true, true);
|
||||
TreeViewItem* item = getItemOnRow (rowSelected);
|
||||
|
||||
scrollToKeepItemVisible (item);
|
||||
if (item != 0)
|
||||
{
|
||||
if (! item->canBeSelected())
|
||||
{
|
||||
// if the row we want to highlight doesn't allow it, try skipping
|
||||
// to the next item..
|
||||
const int nextRowToTry = jlimit (0, getNumRowsInTree() - 1,
|
||||
rowSelected + (delta < 0 ? -1 : 1));
|
||||
|
||||
if (rowSelected != nextRowToTry)
|
||||
{
|
||||
rowSelected = nextRowToTry;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
item->setSelected (true, true);
|
||||
|
||||
scrollToKeepItemVisible (item);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -906,6 +932,9 @@ void TreeViewItem::deselectAllRecursively()
|
|||
void TreeViewItem::setSelected (const bool shouldBeSelected,
|
||||
const bool deselectOtherItemsFirst)
|
||||
{
|
||||
if (shouldBeSelected && ! canBeSelected())
|
||||
return;
|
||||
|
||||
if (deselectOtherItemsFirst)
|
||||
getTopLevelItem()->deselectAllRecursively();
|
||||
|
||||
|
|
|
|||
|
|
@ -238,6 +238,11 @@ public:
|
|||
*/
|
||||
virtual int getItemHeight() const { return 20; }
|
||||
|
||||
/** You can override this method to return false if you don't want to allow the
|
||||
user to select this item.
|
||||
*/
|
||||
virtual bool canBeSelected() const { return true; }
|
||||
|
||||
/** Creates a component that will be used to represent this item.
|
||||
|
||||
You don't have to implement this method - if it returns 0 then no component
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ PixelARGB* ColourGradient::createLookupTable (int& numEntries) const throw()
|
|||
|
||||
for (int j = 2; j < colours.size(); j += 2)
|
||||
{
|
||||
const int numToDo = ((colours.getUnchecked (j) * numEntries) >> 16) - index;
|
||||
const int numToDo = ((colours.getUnchecked (j) * (numEntries - 1)) >> 16) - index;
|
||||
const PixelARGB pix2 (colours.getUnchecked (j + 1));
|
||||
|
||||
for (int i = 0; i < numToDo; ++i)
|
||||
|
|
|
|||
|
|
@ -2086,8 +2086,10 @@ const char* String::toUTF8() const throw()
|
|||
}
|
||||
}
|
||||
|
||||
int String::copyToUTF8 (uint8* const buffer) const throw()
|
||||
int String::copyToUTF8 (uint8* const buffer, const int maxBufferSizeBytes) const throw()
|
||||
{
|
||||
jassert (maxBufferSizeBytes >= 0); // keep this value positive, or no characters will be copied!
|
||||
|
||||
#if JUCE_STRINGS_ARE_UNICODE
|
||||
int num = 0, index = 0;
|
||||
|
||||
|
|
@ -2119,10 +2121,18 @@ int String::copyToUTF8 (uint8* const buffer) const throw()
|
|||
|
||||
if (buffer != 0)
|
||||
{
|
||||
buffer [num++] = (uint8) ((0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
|
||||
if (num + numExtraBytes >= maxBufferSizeBytes)
|
||||
{
|
||||
buffer [num++] = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer [num++] = (uint8) ((0xff << (7 - numExtraBytes)) | (c >> (numExtraBytes * 6)));
|
||||
|
||||
while (--numExtraBytes >= 0)
|
||||
buffer [num++] = (uint8) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
|
||||
while (--numExtraBytes >= 0)
|
||||
buffer [num++] = (uint8) (0x80 | (0x3f & (c >> (numExtraBytes * 6))));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2132,7 +2142,15 @@ int String::copyToUTF8 (uint8* const buffer) const throw()
|
|||
else
|
||||
{
|
||||
if (buffer != 0)
|
||||
{
|
||||
if (num + 1 >= maxBufferSizeBytes)
|
||||
{
|
||||
buffer [num++] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer [num] = (uint8) c;
|
||||
}
|
||||
|
||||
++num;
|
||||
}
|
||||
|
|
@ -2144,10 +2162,10 @@ int String::copyToUTF8 (uint8* const buffer) const throw()
|
|||
return num;
|
||||
|
||||
#else
|
||||
const int numBytes = length() + 1;
|
||||
const int numBytes = jmin (maxBufferSizeBytes, length() + 1);
|
||||
|
||||
if (buffer != 0)
|
||||
copyToBuffer ((char*) buffer, numBytes);
|
||||
copyToBuffer ((char*) buffer, maxBufferSizeBytes);
|
||||
|
||||
return numBytes;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1003,8 +1003,13 @@ public:
|
|||
@param destBuffer the place to copy it to; if this is a null pointer,
|
||||
the method just returns the number of bytes required
|
||||
(including the terminating null character).
|
||||
@param maxBufferSizeBytes the size of the destination buffer, in bytes. If the
|
||||
string won't fit, it'll put in as many as it can while
|
||||
still allowing for a terminating null char at the end,
|
||||
and will return the number of bytes that were actually
|
||||
used. If this value is < 0, no limit is used.
|
||||
*/
|
||||
int copyToUTF8 (uint8* const destBuffer) const throw();
|
||||
int copyToUTF8 (uint8* const destBuffer, const int maxBufferSizeBytes = 0x7fffffff) const throw();
|
||||
|
||||
/** Returns a pointer to a UTF-8 version of this string.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue