Browse Source

Update to latest juce

tags/1.9.4
falkTX 11 years ago
parent
commit
72b4094d8e
79 changed files with 5627 additions and 3681 deletions
  1. +13
    -0
      data/copy-juce-carla
  2. +6
    -6
      source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp
  3. +1
    -1
      source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp
  4. +125
    -126
      source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp
  5. +1
    -1
      source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp
  6. +1
    -1
      source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp
  7. +48
    -34
      source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp
  8. +5
    -5
      source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm
  9. +3
    -3
      source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp
  10. +1
    -4
      source/modules/juce_audio_processors/juce_audio_processors.cpp
  11. +2
    -2
      source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp
  12. +15
    -5
      source/modules/juce_core/javascript/juce_Javascript.cpp
  13. +1
    -1
      source/modules/juce_core/memory/juce_MemoryBlock.cpp
  14. +1
    -1
      source/modules/juce_core/native/juce_mac_Network.mm
  15. +7
    -2
      source/modules/juce_core/native/juce_posix_SharedCode.h
  16. +1
    -1
      source/modules/juce_core/streams/juce_InputStream.cpp
  17. +1
    -1
      source/modules/juce_core/system/juce_StandardHeader.h
  18. +24
    -23
      source/modules/juce_core/text/juce_String.cpp
  19. +3
    -0
      source/modules/juce_core/text/juce_String.h
  20. +19
    -1
      source/modules/juce_core/xml/juce_XmlElement.cpp
  21. +20
    -2
      source/modules/juce_core/xml/juce_XmlElement.h
  22. +3
    -2
      source/modules/juce_data_structures/values/juce_ValueTree.cpp
  23. +1
    -1
      source/modules/juce_events/messages/juce_Initialisation.h
  24. +14
    -2
      source/modules/juce_events/native/juce_mac_MessageManager.mm
  25. +10
    -0
      source/modules/juce_graphics/fonts/juce_Font.cpp
  26. +31
    -33
      source/modules/juce_graphics/geometry/juce_PathIterator.cpp
  27. +23
    -11
      source/modules/juce_graphics/geometry/juce_Rectangle.h
  28. +19
    -3
      source/modules/juce_graphics/native/juce_RenderingHelpers.h
  29. +1
    -1
      source/modules/juce_graphics/native/juce_mac_Fonts.mm
  30. +2
    -1
      source/modules/juce_gui_basics/buttons/juce_Button.cpp
  31. +27
    -0
      source/modules/juce_gui_basics/buttons/juce_Button.h
  32. +11
    -0
      source/modules/juce_gui_basics/buttons/juce_ImageButton.h
  33. +12
    -14
      source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp
  34. +7
    -2
      source/modules/juce_gui_basics/buttons/juce_ShapeButton.h
  35. +1
    -1
      source/modules/juce_gui_basics/components/juce_Desktop.cpp
  36. +1
    -0
      source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp
  37. +36
    -0
      source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h
  38. +10
    -0
      source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h
  39. +3
    -0
      source/modules/juce_gui_basics/juce_gui_basics.cpp
  40. +5
    -1
      source/modules/juce_gui_basics/juce_gui_basics.h
  41. +10
    -0
      source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h
  42. +5
    -18
      source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp
  43. +10
    -0
      source/modules/juce_gui_basics/layout/juce_GroupComponent.h
  44. +67
    -0
      source/modules/juce_gui_basics/layout/juce_ScrollBar.h
  45. +10
    -0
      source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h
  46. +19
    -0
      source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp
  47. +24
    -0
      source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h
  48. +5
    -2774
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp
  49. +83
    -519
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h
  50. +567
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp
  51. +101
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h
  52. +2947
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
  53. +347
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h
  54. +361
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp
  55. +79
    -0
      source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h
  56. +56
    -0
      source/modules/juce_gui_basics/menus/juce_PopupMenu.h
  57. +13
    -0
      source/modules/juce_gui_basics/misc/juce_BubbleComponent.h
  58. +34
    -19
      source/modules/juce_gui_basics/native/juce_android_Windowing.cpp
  59. +1
    -0
      source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm
  60. +10
    -2
      source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm
  61. +1
    -1
      source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm
  62. +23
    -16
      source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp
  63. +12
    -0
      source/modules/juce_gui_basics/properties/juce_PropertyComponent.h
  64. +19
    -0
      source/modules/juce_gui_basics/widgets/juce_ComboBox.h
  65. +12
    -0
      source/modules/juce_gui_basics/widgets/juce_Label.h
  66. +18
    -0
      source/modules/juce_gui_basics/widgets/juce_ProgressBar.h
  67. +51
    -0
      source/modules/juce_gui_basics/widgets/juce_Slider.h
  68. +13
    -0
      source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h
  69. +14
    -0
      source/modules/juce_gui_basics/widgets/juce_TextEditor.h
  70. +18
    -0
      source/modules/juce_gui_basics/widgets/juce_Toolbar.h
  71. +34
    -21
      source/modules/juce_gui_basics/widgets/juce_TreeView.cpp
  72. +50
    -10
      source/modules/juce_gui_basics/widgets/juce_TreeView.h
  73. +26
    -0
      source/modules/juce_gui_basics/windows/juce_AlertWindow.h
  74. +12
    -4
      source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp
  75. +9
    -0
      source/modules/juce_gui_basics/windows/juce_CallOutBox.h
  76. +0
    -4
      source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp
  77. +24
    -0
      source/modules/juce_gui_basics/windows/juce_DocumentWindow.h
  78. +16
    -1
      source/modules/juce_gui_basics/windows/juce_ResizableWindow.h
  79. +11
    -0
      source/modules/juce_gui_basics/windows/juce_TooltipWindow.h

+ 13
- 0
data/copy-juce-carla View File

@@ -0,0 +1,13 @@
#!/bin/bash

JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/distrho/libs/juce-2.0/source/modules"
CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/Carla/source/modules"

MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics")

for M in $MODULES; do
echo $M;
cp -r -v $JUCE_MODULES_DIR/$M/* $CARLA_MODULES_DIR/$M/
done

find $CARLA_MODULES_DIR -name juce_module_info -delete

+ 6
- 6
source/modules/juce_audio_basics/midi/juce_MidiBuffer.cpp View File

@@ -96,7 +96,7 @@ MidiBuffer::MidiBuffer (const MidiMessage& message) noexcept
void MidiBuffer::swapWith (MidiBuffer& other) noexcept { data.swapWith (other.data); }
void MidiBuffer::clear() noexcept { data.clearQuick(); }
void MidiBuffer::ensureSize (size_t minimumNumBytes) { data.ensureStorageAllocated (minimumNumBytes); }
void MidiBuffer::ensureSize (size_t minimumNumBytes) { data.ensureStorageAllocated ((int) minimumNumBytes); }
bool MidiBuffer::isEmpty() const noexcept { return data.size() == 0; }
void MidiBuffer::clear (const int startSample, const int numSamples)
@@ -104,7 +104,7 @@ void MidiBuffer::clear (const int startSample, const int numSamples)
uint8* const start = MidiBufferHelpers::findEventAfter (data.begin(), data.end(), startSample - 1);
uint8* const end = MidiBufferHelpers::findEventAfter (start, data.end(), startSample + numSamples - 1);
data.removeRange (start - data.begin(), end - data.begin());
data.removeRange ((int) (start - data.begin()), (int) (end - data.begin()));
}
void MidiBuffer::addEvent (const MidiMessage& m, const int sampleNumber)
@@ -121,7 +121,7 @@ void MidiBuffer::addEvent (const void* const newData, const int maxBytes, const
const size_t newItemSize = (size_t) numBytes + sizeof (int32) + sizeof (uint16);
const int offset = (int) (MidiBufferHelpers::findEventAfter (data.begin(), data.end(), sampleNumber) - data.begin());
data.insertMultiple (offset, 0, newItemSize);
data.insertMultiple (offset, 0, (int) newItemSize);
uint8* const d = data.begin() + offset;
*reinterpret_cast<int32*> (d) = sampleNumber;
@@ -221,9 +221,9 @@ bool MidiBuffer::Iterator::getNextEvent (MidiMessage& result, int& samplePositio
return false;
samplePosition = MidiBufferHelpers::getEventTime (data);
const int numBytes = MidiBufferHelpers::getEventDataSize (data);
result = MidiMessage (data + sizeof (int32) + sizeof (uint16), numBytes, samplePosition);
data += sizeof (int32) + sizeof (uint16) + numBytes;
const int itemSize = MidiBufferHelpers::getEventDataSize (data);
result = MidiMessage (data + sizeof (int32) + sizeof (uint16), itemSize, samplePosition);
data += sizeof (int32) + sizeof (uint16) + itemSize;
return true;
}

+ 1
- 1
source/modules/juce_audio_devices/native/juce_linux_ALSA.cpp View File

@@ -1210,7 +1210,7 @@ private:
static String hintToString (const void* hints, const char* type)
{
char* const hint = snd_device_name_get_hint (hints, type);
const String s (hint);
const String s (String::fromUTF8 (hint));
::free (hint);
return s;
}


+ 125
- 126
source/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp View File

@@ -155,9 +155,7 @@ public:
bufferSize (512),
numInputChans (0),
numOutputChans (0),
callbacksAllowed (true),
numInputChannelInfos (0),
numOutputChannelInfos (0)
callbacksAllowed (true)
{
jassert (deviceID != 0);
@@ -199,9 +197,17 @@ public:
tempOutputBuffers[i] = audioBuffer + count++ * tempBufSize;
}
struct CallbackDetailsForChannel
{
int streamNum;
int dataOffsetSamples;
int dataStrideSamples;
};
// returns the number of actual available channels
void fillInChannelInfo (const bool input)
StringArray getChannelInfo (const bool input, Array<CallbackDetailsForChannel>& newChannelInfo) const
{
StringArray newNames;
int chanNum = 0;
UInt32 size;
@@ -212,7 +218,7 @@ public:
if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size)))
{
HeapBlock <AudioBufferList> bufList;
HeapBlock<AudioBufferList> bufList;
bufList.calloc (size, 1);
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, bufList)))
@@ -237,82 +243,35 @@ public:
name = String::fromUTF8 (channelName, (int) nameSize);
}
if (input)
if ((input ? activeInputChans : activeOutputChans) [chanNum])
{
if (activeInputChans[chanNum])
{
inputChannelInfo [numInputChannelInfos].streamNum = i;
inputChannelInfo [numInputChannelInfos].dataOffsetSamples = (int) j;
inputChannelInfo [numInputChannelInfos].dataStrideSamples = (int) b.mNumberChannels;
++numInputChannelInfos;
}
if (name.isEmpty())
name << "Input " << (chanNum + 1);
inChanNames.add (name);
}
else
{
if (activeOutputChans[chanNum])
{
outputChannelInfo [numOutputChannelInfos].streamNum = i;
outputChannelInfo [numOutputChannelInfos].dataOffsetSamples = (int) j;
outputChannelInfo [numOutputChannelInfos].dataStrideSamples = (int) b.mNumberChannels;
++numOutputChannelInfos;
}
if (name.isEmpty())
name << "Output " << (chanNum + 1);
outChanNames.add (name);
CallbackDetailsForChannel info = { i, (int) j, (int) b.mNumberChannels };
newChannelInfo.add (info);
}
if (name.isEmpty())
name << (input ? "Input " : "Output ") << (chanNum + 1);
newNames.add (name);
++chanNum;
}
}
}
}
return newNames;
}
void updateDetailsFromDevice()
Array<double> getSampleRatesFromDevice() const
{
stopTimer();
if (deviceID == 0)
return;
const ScopedLock sl (callbackLock);
Array<double> newSampleRates;
String rates;
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
UInt32 isAlive;
UInt32 size = sizeof (isAlive);
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &isAlive))
&& isAlive == 0)
return;
Float64 sr;
size = sizeof (sr);
pa.mSelector = kAudioDevicePropertyNominalSampleRate;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &sr)))
sampleRate = sr;
UInt32 framesPerBuf;
size = sizeof (framesPerBuf);
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &framesPerBuf)))
{
bufferSize = (int) framesPerBuf;
allocateTempBuffers();
}
bufferSizes.clear();
pa.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
pa.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
UInt32 size = 0;
if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size)))
{
@@ -321,33 +280,42 @@ public:
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges)))
{
bufferSizes.add ((int) (ranges[0].mMinimum + 15) & ~15);
static const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
for (int i = 32; i < 2048; i += 32)
for (int i = 0; i < numElementsInArray (possibleRates); ++i)
{
for (int j = size / (int) sizeof (AudioValueRange); --j >= 0;)
{
if (i >= ranges[j].mMinimum && i <= ranges[j].mMaximum)
if (possibleRates[i] >= ranges[j].mMinimum - 2 && possibleRates[i] <= ranges[j].mMaximum + 2)
{
bufferSizes.addIfNotAlreadyThere (i);
newSampleRates.add (possibleRates[i]);
rates << possibleRates[i] << ' ';
break;
}
}
}
if (bufferSize > 0)
bufferSizes.addIfNotAlreadyThere (bufferSize);
}
}
if (bufferSizes.size() == 0 && bufferSize > 0)
bufferSizes.add (bufferSize);
if (newSampleRates.size() == 0 && sampleRate > 0)
{
newSampleRates.add (sampleRate);
rates << sampleRate;
}
JUCE_COREAUDIOLOG ("rates: " + rates);
return newSampleRates;
}
sampleRates.clear();
const double possibleRates[] = { 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0 };
String rates;
Array<int> getBufferSizesFromDevice() const
{
Array<int> newBufferSizes;
pa.mSelector = kAudioDevicePropertyAvailableNominalSampleRates;
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyBufferFrameSizeRange;
UInt32 size = 0;
if (OK (AudioObjectGetPropertyDataSize (deviceID, &pa, 0, 0, &size)))
{
@@ -356,59 +324,98 @@ public:
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, ranges)))
{
for (int i = 0; i < numElementsInArray (possibleRates); ++i)
{
bool ok = false;
newBufferSizes.add ((int) (ranges[0].mMinimum + 15) & ~15);
for (int i = 32; i < 2048; i += 32)
{
for (int j = size / (int) sizeof (AudioValueRange); --j >= 0;)
if (possibleRates[i] >= ranges[j].mMinimum - 2 && possibleRates[i] <= ranges[j].mMaximum + 2)
ok = true;
if (ok)
{
sampleRates.add (possibleRates[i]);
rates << possibleRates[i] << ' ';
if (i >= ranges[j].mMinimum && i <= ranges[j].mMaximum)
{
newBufferSizes.addIfNotAlreadyThere (i);
break;
}
}
}
if (bufferSize > 0)
newBufferSizes.addIfNotAlreadyThere (bufferSize);
}
}
if (sampleRates.size() == 0 && sampleRate > 0)
{
sampleRates.add (sampleRate);
rates << sampleRate;
}
if (newBufferSizes.size() == 0 && bufferSize > 0)
newBufferSizes.add (bufferSize);
JUCE_COREAUDIOLOG ("sr: " + rates);
return newBufferSizes;
}
inputLatency = 0;
outputLatency = 0;
UInt32 lat;
size = sizeof (lat);
int getLatencyFromDevice (AudioObjectPropertyScope scope) const
{
UInt32 lat = 0;
UInt32 size = sizeof (lat);
AudioObjectPropertyAddress pa;
pa.mElement = kAudioObjectPropertyElementMaster;
pa.mSelector = kAudioDevicePropertyLatency;
pa.mScope = kAudioDevicePropertyScopeInput;
if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr)
inputLatency = (int) lat;
pa.mScope = scope;
AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat);
return (int) lat;
}
pa.mScope = kAudioDevicePropertyScopeOutput;
size = sizeof (lat);
void updateDetailsFromDevice()
{
stopTimer();
if (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &lat) == noErr)
outputLatency = (int) lat;
if (deviceID == 0)
return;
// this collects all the new details from the device without any locking, then
// locks + swaps them afterwards.
AudioObjectPropertyAddress pa;
pa.mScope = kAudioObjectPropertyScopeWildcard;
pa.mElement = kAudioObjectPropertyElementMaster;
UInt32 isAlive;
UInt32 size = sizeof (isAlive);
pa.mSelector = kAudioDevicePropertyDeviceIsAlive;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &isAlive)) && isAlive == 0)
return;
Float64 sr;
size = sizeof (sr);
pa.mSelector = kAudioDevicePropertyNominalSampleRate;
if (OK (AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &sr)))
sampleRate = sr;
UInt32 framesPerBuf = bufferSize;
size = sizeof (framesPerBuf);
pa.mSelector = kAudioDevicePropertyBufferFrameSize;
AudioObjectGetPropertyData (deviceID, &pa, 0, 0, &size, &framesPerBuf);
Array<int> newBufferSizes (getBufferSizesFromDevice());
Array<double> newSampleRates (getSampleRatesFromDevice());
inputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeInput);
outputLatency = getLatencyFromDevice (kAudioDevicePropertyScopeOutput);
JUCE_COREAUDIOLOG ("lat: " + String (inputLatency) + " " + String (outputLatency));
inChanNames.clear();
outChanNames.clear();
Array<CallbackDetailsForChannel> newInChans, newOutChans;
StringArray newInNames (getChannelInfo (true, newInChans));
StringArray newOutNames (getChannelInfo (false, newOutChans));
// after getting the new values, lock + apply them
const ScopedLock sl (callbackLock);
bufferSize = (int) framesPerBuf;
allocateTempBuffers();
inputChannelInfo.calloc ((size_t) numInputChans + 2);
numInputChannelInfos = 0;
sampleRates.swapWith (newSampleRates);
bufferSizes.swapWith (newBufferSizes);
outputChannelInfo.calloc ((size_t) numOutputChans + 2);
numOutputChannelInfos = 0;
inChanNames.swapWith (newInNames);
outChanNames.swapWith (newOutNames);
fillInChannelInfo (true);
fillInChannelInfo (false);
inputChannelInfo.swapWith (newInChans);
outputChannelInfo.swapWith (newOutChans);
}
//==============================================================================
@@ -675,7 +682,7 @@ public:
{
for (int i = numInputChans; --i >= 0;)
{
const CallbackDetailsForChannel& info = inputChannelInfo[i];
const CallbackDetailsForChannel& info = inputChannelInfo.getReference(i);
float* dest = tempInputBuffers [i];
const float* src = ((const float*) inInputData->mBuffers[info.streamNum].mData)
+ info.dataOffsetSamples;
@@ -720,7 +727,7 @@ public:
for (int i = numOutputChans; --i >= 0;)
{
const CallbackDetailsForChannel& info = outputChannelInfo[i];
const CallbackDetailsForChannel& info = outputChannelInfo.getReference(i);
const float* src = tempOutputBuffers [i];
float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData)
+ info.dataOffsetSamples;
@@ -739,9 +746,9 @@ public:
}
else
{
for (int i = jmin (numOutputChans, numOutputChannelInfos); --i >= 0;)
for (int i = jmin (numOutputChans, outputChannelInfo.size()); --i >= 0;)
{
const CallbackDetailsForChannel& info = outputChannelInfo[i];
const CallbackDetailsForChannel& info = outputChannelInfo.getReference(i);
float* dest = ((float*) outOutputData->mBuffers[info.streamNum].mData)
+ info.dataOffsetSamples;
const int stride = info.dataStrideSamples;
@@ -803,15 +810,7 @@ private:
int numInputChans, numOutputChans;
bool callbacksAllowed;
struct CallbackDetailsForChannel
{
int streamNum;
int dataOffsetSamples;
int dataStrideSamples;
};
int numInputChannelInfos, numOutputChannelInfos;
HeapBlock <CallbackDetailsForChannel> inputChannelInfo, outputChannelInfo;
Array<CallbackDetailsForChannel> inputChannelInfo, outputChannelInfo;
HeapBlock <float*> tempInputBuffers, tempOutputBuffers;
//==============================================================================


+ 1
- 1
source/modules/juce_audio_formats/codecs/juce_FlacAudioFormat.cpp View File

@@ -380,7 +380,7 @@ public:
samplesToWrite = const_cast<const int**> (channels.getData());
}
return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, (size_t) numSamples) != 0;
return FLAC__stream_encoder_process (encoder, (const FLAC__int32**) samplesToWrite, (unsigned) numSamples) != 0;
}
bool writeData (const void* const data, const int size) const


+ 1
- 1
source/modules/juce_audio_formats/codecs/juce_OggVorbisAudioFormat.cpp View File

@@ -186,7 +186,7 @@ public:
{
float** dataIn = nullptr;
const int samps = OggVorbisNamespace::ov_read_float (&ovFile, &dataIn, numToRead, &bitStream);
const long samps = OggVorbisNamespace::ov_read_float (&ovFile, &dataIn, numToRead, &bitStream);
if (samps <= 0)
break;


+ 48
- 34
source/modules/juce_audio_formats/format/juce_AudioFormatReader.cpp View File

@@ -100,6 +100,18 @@ bool AudioFormatReader::read (int* const* destSamples,
return true;
}
static void readChannels (AudioFormatReader& reader,
int** const chans, AudioSampleBuffer* const buffer,
const int startSample, const int numSamples,
const int64 readerStartSample, const int numTargetChannels)
{
for (int j = 0; j < numTargetChannels; ++j)
chans[j] = reinterpret_cast<int*> (buffer->getSampleData (j, startSample));
chans[numTargetChannels] = nullptr;
reader.read (chans, numTargetChannels, readerStartSample, numSamples, true);
}
void AudioFormatReader::read (AudioSampleBuffer* buffer,
int startSample,
int numSamples,
@@ -113,49 +125,51 @@ void AudioFormatReader::read (AudioSampleBuffer* buffer,
if (numSamples > 0)
{
const int numTargetChannels = buffer->getNumChannels();
int* chans[3];
if (useReaderLeftChan == useReaderRightChan)
if (numTargetChannels <= 2)
{
chans[0] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample));
chans[1] = (numChannels > 1 && numTargetChannels > 1) ? reinterpret_cast<int*> (buffer->getSampleData (1, startSample)) : nullptr;
}
else if (useReaderLeftChan || (numChannels == 1))
{
chans[0] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample));
chans[1] = nullptr;
}
else if (useReaderRightChan)
{
chans[0] = nullptr;
chans[1] = reinterpret_cast<int*> (buffer->getSampleData (0, startSample));
}
int* const dest0 = reinterpret_cast<int*> (buffer->getSampleData (0, startSample));
int* const dest1 = reinterpret_cast<int*> (numTargetChannels > 1 ? buffer->getSampleData (1, startSample) : nullptr);
int* chans[3];
chans[2] = nullptr;
if (useReaderLeftChan == useReaderRightChan)
{
chans[0] = dest0;
chans[1] = numChannels > 1 ? dest1 : nullptr;
}
else if (useReaderLeftChan || (numChannels == 1))
{
chans[0] = dest0;
chans[1] = nullptr;
}
else if (useReaderRightChan)
{
chans[0] = nullptr;
chans[1] = dest0;
}
read (chans, 2, readerStartSample, numSamples, true);
chans[2] = nullptr;
read (chans, 2, readerStartSample, numSamples, true);
if (! usesFloatingPointData)
// if the target's stereo and the source is mono, dupe the first channel..
if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr))
memcpy (dest1, dest0, sizeof (float) * (size_t) numSamples);
}
else if (numTargetChannels <= 64)
{
for (int j = 0; j < 2; ++j)
{
if (float* const d = reinterpret_cast <float*> (chans[j]))
{
const float multiplier = 1.0f / 0x7fffffff;
for (int i = 0; i < numSamples; ++i)
d[i] = *reinterpret_cast<int*> (d + i) * multiplier;
}
}
int* chans[65];
readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
}
if (numTargetChannels > 1 && (chans[0] == nullptr || chans[1] == nullptr))
else
{
// if this is a stereo buffer and the source was mono, dupe the first channel..
memcpy (buffer->getSampleData (1, startSample),
buffer->getSampleData (0, startSample),
sizeof (float) * (size_t) numSamples);
HeapBlock<int*> chans (numTargetChannels);
readChannels (*this, chans, buffer, startSample, numSamples, readerStartSample, numTargetChannels);
}
if (! usesFloatingPointData)
for (int j = 0; j < numTargetChannels; ++j)
if (float* const d = buffer->getSampleData (j, startSample))
FloatVectorOperations::convertFixedToFloat (d, reinterpret_cast<const int*> (d), 1.0f / 0x7fffffff, numSamples);
}
}


+ 5
- 5
source/modules/juce_audio_processors/format_types/juce_AudioUnitPluginFormat.mm View File

@@ -733,7 +733,7 @@ public:
return s;
}
void changeProgramName (int index, const String& newName) override
void changeProgramName (int /*index*/, const String& /*newName*/) override
{
jassertfalse; // xxx not implemented!
}
@@ -1005,8 +1005,8 @@ private:
}
//==============================================================================
OSStatus renderGetInput (AudioUnitRenderActionFlags* ioActionFlags,
const AudioTimeStamp* inTimeStamp,
OSStatus renderGetInput (AudioUnitRenderActionFlags*,
const AudioTimeStamp*,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList* ioData) const
@@ -1147,7 +1147,7 @@ private:
->renderGetInput (ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, ioData);
}
static OSStatus renderMidiOutputCallback (void* hostRef, const AudioTimeStamp* timeStamp, UInt32 midiOutNum,
static OSStatus renderMidiOutputCallback (void* hostRef, const AudioTimeStamp*, UInt32 /*midiOutNum*/,
const struct MIDIPacketList* pktlist)
{
return static_cast<AudioUnitPluginInstance*> (hostRef)->renderMidiOutput (pktlist);
@@ -1331,7 +1331,7 @@ public:
startTimer (jmin (713, getTimerInterval() + 51));
}
void childBoundsChanged (Component* child) override
void childBoundsChanged (Component*) override
{
setSize (wrapper.getWidth(), wrapper.getHeight());
startTimer (70);


+ 3
- 3
source/modules/juce_audio_processors/format_types/juce_VSTPluginFormat.cpp View File

@@ -1675,8 +1675,8 @@ private:
void setHostTimeFrameRate (long frameRateIndex, double frameRate, double currentTime) noexcept
{
vstHostTime.flags |= kVstSmpteValid;
vstHostTime.smpteFrameRate = frameRateIndex;
vstHostTime.smpteOffset = (long) (currentTime * 80.0 * frameRate + 0.5);
vstHostTime.smpteFrameRate = (VstInt32) frameRateIndex;
vstHostTime.smpteOffset = (VstInt32) (currentTime * 80.0 * frameRate + 0.5);
}
bool restoreProgramSettings (const fxProgram* const prog)
@@ -2510,7 +2510,7 @@ private:
deleteWindow();
}
HIViewRef attachView (WindowRef windowRef, HIViewRef rootView) override
HIViewRef attachView (WindowRef windowRef, HIViewRef /*rootView*/) override
{
owner.openPluginWindow (windowRef);
return 0;


+ 1
- 4
source/modules/juce_audio_processors/juce_audio_processors.cpp View File

@@ -37,10 +37,7 @@
#include "../juce_core/native/juce_BasicNativeHeaders.h"
#include "juce_audio_processors.h"
#if JUCE_MODULE_AVAILABLE_juce_gui_extra
#include "../juce_gui_extra/juce_gui_extra.h"
#endif
#include "../juce_gui_extra/juce_gui_extra.h"
//==============================================================================
#if JUCE_MAC


+ 2
- 2
source/modules/juce_audio_processors/scanning/juce_KnownPluginList.cpp View File

@@ -287,8 +287,8 @@ XmlElement* KnownPluginList::createXml() const
{
XmlElement* const e = new XmlElement ("KNOWNPLUGINS");
for (int i = 0; i < types.size(); ++i)
e->addChildElement (types.getUnchecked(i)->createXml());
for (int i = types.size(); --i >= 0;)
e->prependChildElement (types.getUnchecked(i)->createXml());
for (int i = 0; i < blacklist.size(); ++i)
e->createNewChildElement ("BLACKLISTED")->setAttribute ("id", blacklist[i]);


+ 15
- 5
source/modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -56,6 +56,11 @@ namespace TokenTypes
JUCE_DECLARE_JS_TOKEN (identifier, "$identifier")
}
#if JUCE_MSVC
#pragma warning (push)
#pragma warning (disable: 4702)
#endif
//==============================================================================
struct JavascriptEngine::RootObject : public DynamicObject
{
@@ -853,8 +858,8 @@ struct JavascriptEngine::RootObject : public DynamicObject
bool matchToken (TokenType name, const size_t len) noexcept
{
if (p.compareUpTo (String::CharPointerType (name), len) != 0) return false;
p += len; return true;
if (p.compareUpTo (CharPointer_ASCII (name), (int) len) != 0) return false;
p += (int) len; return true;
}
void skipWhitespaceAndComments()
@@ -1211,6 +1216,9 @@ struct JavascriptEngine::RootObject : public DynamicObject
return parseSuffixes (s.release());
}
if (matchIf (TokenTypes::plusplus)) return parsePostIncDec<AdditionOp> (input);
if (matchIf (TokenTypes::minusminus)) return parsePostIncDec<SubtractionOp> (input);
return input.release();
}
@@ -1339,8 +1347,6 @@ struct JavascriptEngine::RootObject : public DynamicObject
{
if (matchIf (TokenTypes::plus)) { ExpPtr b (parseMultiplyDivide()); a = new AdditionOp (location, a, b); }
else if (matchIf (TokenTypes::minus)) { ExpPtr b (parseMultiplyDivide()); a = new SubtractionOp (location, a, b); }
else if (matchIf (TokenTypes::plusplus)) a = parsePostIncDec<AdditionOp> (a);
else if (matchIf (TokenTypes::minusminus)) a = parsePostIncDec<SubtractionOp> (a);
else break;
}
@@ -1429,7 +1435,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
}
static Identifier getClassName() { static const Identifier i ("Object"); return i; }
static var dump (Args a) { DBG (JSON::toString (a.thisObject)); return var::undefined(); }
static var dump (Args a) { DBG (JSON::toString (a.thisObject)); (void) a; return var::undefined(); }
static var clone (Args a) { return a.thisObject.clone(); }
};
@@ -1681,3 +1687,7 @@ var JavascriptEngine::callFunction (Identifier function, const var::NativeFuncti
return var::undefined();
}
#if JUCE_MSVC
#pragma warning (pop)
#endif

+ 1
- 1
source/modules/juce_core/memory/juce_MemoryBlock.cpp View File

@@ -265,7 +265,7 @@ void MemoryBlock::copyTo (void* const dst, int offset, size_t num) const noexcep
String MemoryBlock::toString() const
{
return String::fromUTF8 (data, size);
return String::fromUTF8 (data, (int) size);
}
//==============================================================================


+ 1
- 1
source/modules/juce_core/native/juce_mac_Network.mm View File

@@ -220,7 +220,7 @@ public:
initialised = true;
}
void didSendBodyData (int /*totalBytesWritten*/, int /*totalBytesExpected*/)
void didSendBodyData (NSInteger /*totalBytesWritten*/, NSInteger /*totalBytesExpected*/)
{
}


+ 7
- 2
source/modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -114,8 +114,13 @@ bool WaitableEvent::wait (const int timeOutMillisecs) const noexcept
void WaitableEvent::signal() const noexcept
{
pthread_mutex_lock (&mutex);
triggered = true;
pthread_cond_broadcast (&condition);
if (! triggered)
{
triggered = true;
pthread_cond_broadcast (&condition);
}
pthread_mutex_unlock (&mutex);
}


+ 1
- 1
source/modules/juce_core/streams/juce_InputStream.cpp View File

@@ -175,7 +175,7 @@ String InputStream::readString()
}
}
return String::fromUTF8 (data, i);
return String::fromUTF8 (data, (int) i);
}
String InputStream::readNextLine()


+ 1
- 1
source/modules/juce_core/system/juce_StandardHeader.h View File

@@ -36,7 +36,7 @@
*/
#define JUCE_MAJOR_VERSION 2
#define JUCE_MINOR_VERSION 1
#define JUCE_BUILDNUMBER 6
#define JUCE_BUILDNUMBER 7
/** Current Juce version number.


+ 24
- 23
source/modules/juce_core/text/juce_String.cpp View File

@@ -524,41 +524,42 @@ juce_wchar String::operator[] (int index) const noexcept
return text [index];
}
int String::hashCode() const noexcept
template <typename Type>
struct HashGenerator
{
int result = 0;
template <typename CharPointer>
static Type calculate (CharPointer t) noexcept
{
Type result = Type();
for (CharPointerType t (text); ! t.isEmpty();)
result = 31 * result + (int) t.getAndAdvance();
while (! t.isEmpty())
result = multiplier * result + t.getAndAdvance();
return result;
}
return result;
}
int64 String::hashCode64() const noexcept
{
int64 result = 0;
enum { multiplier = sizeof (Type) > 4 ? 101 : 31 };
};
for (CharPointerType t (text); ! t.isEmpty();)
result = 101 * result + t.getAndAdvance();
return result;
}
int String::hashCode() const noexcept { return HashGenerator<int> ::calculate (text); }
int64 String::hashCode64() const noexcept { return HashGenerator<int64> ::calculate (text); }
std::size_t String::hash() const noexcept { return HashGenerator<std::size_t>::calculate (text); }
//==============================================================================
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const String& s2) noexcept { return s1.compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const char* const s2) noexcept { return s1.compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const wchar_t* const s2) noexcept { return s1.compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF8 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF16 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF32 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const String& s2) noexcept { return s1.compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const char* const s2) noexcept { return s1.compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const wchar_t* const s2) noexcept { return s1.compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const char* s2) noexcept { return s1.compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const char* s2) noexcept { return s1.compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const wchar_t* s2) noexcept { return s1.compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const wchar_t* s2) noexcept { return s1.compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF8 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF8 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF16 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF16 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator== (const String& s1, const CharPointer_UTF32 s2) noexcept { return s1.getCharPointer().compare (s2) == 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, const CharPointer_UTF32 s2) noexcept { return s1.getCharPointer().compare (s2) != 0; }
JUCE_API bool JUCE_CALLTYPE operator!= (const String& s1, StringRef s2) noexcept { return s1.getCharPointer().compare (s2.text) != 0; }
JUCE_API bool JUCE_CALLTYPE operator> (const String& s1, const String& s2) noexcept { return s1.compare (s2) > 0; }
JUCE_API bool JUCE_CALLTYPE operator< (const String& s1, const String& s2) noexcept { return s1.compare (s2) < 0; }
JUCE_API bool JUCE_CALLTYPE operator>= (const String& s1, const String& s2) noexcept { return s1.compare (s2) >= 0; }


+ 3
- 0
source/modules/juce_core/text/juce_String.h View File

@@ -180,6 +180,9 @@ public:
/** Generates a probably-unique 64-bit hashcode from this string. */
int64 hashCode64() const noexcept;
/** Generates a probably-unique hashcode from this string. */
std::size_t hash() const noexcept;
/** Returns the number of characters in the string. */
int length() const noexcept;


+ 19
- 1
source/modules/juce_core/xml/juce_XmlElement.cpp View File

@@ -585,18 +585,36 @@ XmlElement* XmlElement::getChildByAttribute (StringRef attributeName, StringRef
void XmlElement::addChildElement (XmlElement* const newNode) noexcept
{
if (newNode != nullptr)
{
// The element being added must not be a child of another node!
jassert (newNode->nextListItem == nullptr);
firstChildElement.append (newNode);
}
}
void XmlElement::insertChildElement (XmlElement* const newNode, int indexToInsertAt) noexcept
{
if (newNode != nullptr)
{
removeChildElement (newNode, false);
// The element being added must not be a child of another node!
jassert (newNode->nextListItem == nullptr);
firstChildElement.insertAtIndex (indexToInsertAt, newNode);
}
}
void XmlElement::prependChildElement (XmlElement* newNode) noexcept
{
if (newNode != nullptr)
{
// The element being added must not be a child of another node!
jassert (newNode->nextListItem == nullptr);
firstChildElement.insertNext (newNode);
}
}
XmlElement* XmlElement::createNewChildElement (const String& childTagName)
{
XmlElement* const newElement = new XmlElement (childTagName);


+ 20
- 2
source/modules/juce_core/xml/juce_XmlElement.h View File

@@ -504,6 +504,10 @@ public:
make sure the object that you pass in will not be deleted by anything else,
and make sure it's not already the child of another element.
Note that due to the XmlElement using a singly-linked-list, prependChildElement()
is an O(1) operation, but addChildElement() is an O(N) operation - so if
you're adding large number of elements, you may prefer to do so in reverse order!
@see getFirstChildElement, getNextElement, getNumChildElements,
getChildElement, removeChildElement
*/
@@ -515,14 +519,28 @@ public:
make sure the object that you pass in will not be deleted by anything else,
and make sure it's not already the child of another element.
@param newChildNode the element to add
@param newChildElement the element to add
@param indexToInsertAt the index at which to insert the new element - if this is
below zero, it will be added to the end of the list
@see addChildElement, insertChildElement
*/
void insertChildElement (XmlElement* newChildNode,
void insertChildElement (XmlElement* newChildElement,
int indexToInsertAt) noexcept;
/** Inserts an element at the beginning of this element's list of children.
Child elements are deleted automatically when their parent is deleted, so
make sure the object that you pass in will not be deleted by anything else,
and make sure it's not already the child of another element.
Note that due to the XmlElement using a singly-linked-list, prependChildElement()
is an O(1) operation, but addChildElement() is an O(N) operation - so if
you're adding large number of elements, you may prefer to do so in reverse order!
@see addChildElement, insertChildElement
*/
void prependChildElement (XmlElement* newChildElement) noexcept;
/** Creates a new element with the given name and returns it, after adding it
as a child element.


+ 3
- 2
source/modules/juce_data_structures/values/juce_ValueTree.cpp View File

@@ -412,8 +412,9 @@ public:
XmlElement* const xml = new XmlElement (type.toString());
properties.copyToXmlAttributes (*xml);
for (int i = 0; i < children.size(); ++i)
xml->addChildElement (children.getObjectPointerUnchecked(i)->createXml());
// (NB: it's faster to add nodes to XML elements in reverse order)
for (int i = children.size(); --i >= 0;)
xml->prependChildElement (children.getObjectPointerUnchecked(i)->createXml());
return xml;
}


+ 1
- 1
source/modules/juce_events/messages/juce_Initialisation.h View File

@@ -89,7 +89,7 @@ public:
#else
#if JUCE_WINDOWS
#if defined (WINAPI) || defined (_WINDOWS_)
#if defined (WINAPI) || defined (_WINDOWS_) || defined(JUCE_MINGW)
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (HINSTANCE, HINSTANCE, const LPSTR, int)
#elif defined (_UNICODE)
#define JUCE_MAIN_FUNCTION int __stdcall WinMain (void*, void*, const wchar_t*, int)


+ 14
- 2
source/modules/juce_events/native/juce_mac_MessageManager.mm View File

@@ -333,6 +333,18 @@ void MessageManager::broadcastMessage (const String& message)
void repostCurrentNSEvent();
void repostCurrentNSEvent()
{
NSEvent* e = [NSApp currentEvent];
[[NSOperationQueue mainQueue] addOperationWithBlock: ^{ [NSApp postEvent: e atStart: YES]; }];
struct EventReposter : public CallbackMessage
{
EventReposter() : e ([[NSApp currentEvent] retain]) {}
~EventReposter() { [e release]; }
void messageCallback() override
{
[NSApp postEvent: e atStart: YES];
}
NSEvent* e;
};
(new EventReposter())->post();
}

+ 10
- 0
source/modules/juce_graphics/fonts/juce_Font.cpp View File

@@ -155,9 +155,19 @@ void Typeface::setTypefaceCacheSize (int numFontsToCache)
TypefaceCache::getInstance()->setSize (numFontsToCache);
}
#if JUCE_MODULE_AVAILABLE_juce_opengl
extern void clearOpenGLGlyphCache();
#endif
void Typeface::clearTypefaceCache()
{
TypefaceCache::getInstance()->clear();
RenderingHelpers::SoftwareRendererSavedState::clearGlyphCache();
#if JUCE_MODULE_AVAILABLE_juce_opengl
clearOpenGLGlyphCache();
#endif
}
//==============================================================================


+ 31
- 33
source/modules/juce_graphics/geometry/juce_PathIterator.cpp View File

@@ -69,48 +69,45 @@ bool PathFlatteningIterator::next()
float y3 = 0;
float x4 = 0;
float y4 = 0;
float type;
for (;;)
{
float type;
if (stackPos == stackBase)
{
if (index >= path.numElements)
{
return false;
}
else
type = points [index++];
if (type != Path::closeSubPathMarker)
{
type = points [index++];
x2 = points [index++];
y2 = points [index++];
if (type == Path::quadMarker)
{
x3 = points [index++];
y3 = points [index++];
if (! isIdentityTransform)
transform.transformPoints (x2, y2, x3, y3);
}
else if (type == Path::cubicMarker)
{
x3 = points [index++];
y3 = points [index++];
x4 = points [index++];
y4 = points [index++];
if (type != Path::closeSubPathMarker)
if (! isIdentityTransform)
transform.transformPoints (x2, y2, x3, y3, x4, y4);
}
else
{
x2 = points [index++];
y2 = points [index++];
if (type == Path::quadMarker)
{
x3 = points [index++];
y3 = points [index++];
if (! isIdentityTransform)
transform.transformPoints (x2, y2, x3, y3);
}
else if (type == Path::cubicMarker)
{
x3 = points [index++];
y3 = points [index++];
x4 = points [index++];
y4 = points [index++];
if (! isIdentityTransform)
transform.transformPoints (x2, y2, x3, y3, x4, y4);
}
else
{
if (! isIdentityTransform)
transform.transformPoint (x2, y2);
}
if (! isIdentityTransform)
transform.transformPoint (x2, y2);
}
}
}
@@ -150,7 +147,8 @@ bool PathFlatteningIterator::next()
return true;
}
else if (type == Path::quadMarker)
if (type == Path::quadMarker)
{
const size_t offset = (size_t) (stackPos - stackBase);


+ 23
- 11
source/modules/juce_graphics/geometry/juce_Rectangle.h View File

@@ -190,61 +190,73 @@ public:
Rectangle withZeroOrigin() const noexcept { return Rectangle (w, h); }
/** Returns a rectangle which has the same position and height as this one, but with a different width. */
Rectangle withWidth (const ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
Rectangle withWidth (ValueType newWidth) const noexcept { return Rectangle (pos.x, pos.y, newWidth, h); }
/** Returns a rectangle which has the same position and width as this one, but with a different height. */
Rectangle withHeight (const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
Rectangle withHeight (ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, w, newHeight); }
/** Returns a rectangle with the same position as this one, but a new size. */
Rectangle withSize (const ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
Rectangle withSize (ValueType newWidth, const ValueType newHeight) const noexcept { return Rectangle (pos.x, pos.y, newWidth, newHeight); }
/** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
@see withLeft
*/
void setLeft (const ValueType newLeft) noexcept { w = jmax (ValueType(), pos.x + w - newLeft); pos.x = newLeft; }
void setLeft (ValueType newLeft) noexcept { w = jmax (ValueType(), pos.x + w - newLeft); pos.x = newLeft; }
/** Returns a new rectangle with a different x position, but the same right-hand edge as this one.
If the new x is beyond the right of the current right-hand edge, the width will be set to zero.
@see setLeft
*/
Rectangle withLeft (const ValueType newLeft) const noexcept { return Rectangle (newLeft, pos.y, jmax (ValueType(), pos.x + w - newLeft), h); }
Rectangle withLeft (ValueType newLeft) const noexcept { return Rectangle (newLeft, pos.y, jmax (ValueType(), pos.x + w - newLeft), h); }
/** Moves the y position, adjusting the height so that the bottom edge remains in the same place.
If the y is moved to be below the current bottom edge, the height will be set to zero.
@see withTop
*/
void setTop (const ValueType newTop) noexcept { h = jmax (ValueType(), pos.y + h - newTop); pos.y = newTop; }
void setTop (ValueType newTop) noexcept { h = jmax (ValueType(), pos.y + h - newTop); pos.y = newTop; }
/** Returns a new rectangle with a different y position, but the same bottom edge as this one.
If the new y is beyond the bottom of the current rectangle, the height will be set to zero.
@see setTop
*/
Rectangle withTop (const ValueType newTop) const noexcept { return Rectangle (pos.x, newTop, w, jmax (ValueType(), pos.y + h - newTop)); }
Rectangle withTop (ValueType newTop) const noexcept { return Rectangle (pos.x, newTop, w, jmax (ValueType(), pos.y + h - newTop)); }
/** Adjusts the width so that the right-hand edge of the rectangle has this new value.
If the new right is below the current X value, the X will be pushed down to match it.
@see getRight, withRight
*/
void setRight (const ValueType newRight) noexcept { pos.x = jmin (pos.x, newRight); w = newRight - pos.x; }
void setRight (ValueType newRight) noexcept { pos.x = jmin (pos.x, newRight); w = newRight - pos.x; }
/** Returns a new rectangle with a different right-hand edge position, but the same left-hand edge as this one.
If the new right edge is below the current left-hand edge, the width will be set to zero.
@see setRight
*/
Rectangle withRight (const ValueType newRight) const noexcept { return Rectangle (jmin (pos.x, newRight), pos.y, jmax (ValueType(), newRight - pos.x), h); }
Rectangle withRight (ValueType newRight) const noexcept { return Rectangle (jmin (pos.x, newRight), pos.y, jmax (ValueType(), newRight - pos.x), h); }
/** Adjusts the height so that the bottom edge of the rectangle has this new value.
If the new bottom is lower than the current Y value, the Y will be pushed down to match it.
@see getBottom, withBottom
*/
void setBottom (const ValueType newBottom) noexcept { pos.y = jmin (pos.y, newBottom); h = newBottom - pos.y; }
void setBottom (ValueType newBottom) noexcept { pos.y = jmin (pos.y, newBottom); h = newBottom - pos.y; }
/** Returns a new rectangle with a different bottom edge position, but the same top edge as this one.
If the new y is beyond the bottom of the current rectangle, the height will be set to zero.
@see setBottom
*/
Rectangle withBottom (const ValueType newBottom) const noexcept { return Rectangle (pos.x, jmin (pos.y, newBottom), w, jmax (ValueType(), newBottom - pos.y)); }
Rectangle withBottom (ValueType newBottom) const noexcept { return Rectangle (pos.x, jmin (pos.y, newBottom), w, jmax (ValueType(), newBottom - pos.y)); }
/** Returns a version of this rectangle with the given amount removed from its left-hand edge. */
Rectangle withTrimmedLeft (ValueType amountToRemove) const noexcept { return withLeft (pos.x + amountToRemove); }
/** Returns a version of this rectangle with the given amount removed from its right-hand edge. */
Rectangle withTrimmedRight (ValueType amountToRemove) const noexcept { return withWidth (w - amountToRemove); }
/** Returns a version of this rectangle with the given amount removed from its top edge. */
Rectangle withTrimmedTop (ValueType amountToRemove) const noexcept { return withTop (pos.y + amountToRemove); }
/** Returns a version of this rectangle with the given amount removed from its bottom edge. */
Rectangle withTrimmedBottom (ValueType amountToRemove) const noexcept { return withHeight (h - amountToRemove); }
//==============================================================================
/** Moves the rectangle's position by adding amount to its x and y coordinates. */


+ 19
- 3
source/modules/juce_graphics/native/juce_RenderingHelpers.h View File

@@ -142,7 +142,7 @@ class GlyphCache : private DeletedAtShutdown
public:
GlyphCache()
{
addNewGlyphSlots (120);
reset();
}
~GlyphCache()
@@ -207,6 +207,15 @@ public:
glyph->draw (target, pos);
}
void reset()
{
const ScopedWriteLock swl (lock);
glyphs.clear();
addNewGlyphSlots (120);
hits.set (0);
misses.set (0);
}
private:
friend struct ContainerDeletePolicy<CachedGlyphType>;
OwnedArray<CachedGlyphType> glyphs;
@@ -215,6 +224,8 @@ private:
void addNewGlyphSlots (int num)
{
glyphs.ensureStorageAllocated (glyphs.size() + num);
while (--num >= 0)
glyphs.add (new CachedGlyphType());
}
@@ -2419,6 +2430,13 @@ public:
}
}
typedef GlyphCache<CachedGlyphEdgeTable <SoftwareRendererSavedState>, SoftwareRendererSavedState> GlyphCacheType;
static void clearGlyphCache()
{
GlyphCacheType::getInstance().reset();
}
//==============================================================================
void drawGlyph (int glyphNumber, const AffineTransform& trans)
{
@@ -2426,8 +2444,6 @@ public:
{
if (trans.isOnlyTranslation() && ! transform.isRotated)
{
typedef GlyphCache <CachedGlyphEdgeTable <SoftwareRendererSavedState>, SoftwareRendererSavedState> GlyphCacheType;
GlyphCacheType& cache = GlyphCacheType::getInstance();
Point<float> pos (trans.getTranslationX(), trans.getTranslationY());


+ 1
- 1
source/modules/juce_graphics/native/juce_mac_Fonts.mm View File

@@ -340,7 +340,7 @@ namespace CoreTextTypeLayout
CFArrayRef lines = CTFrameGetLines (frame);
const CFIndex numLines = CFArrayGetCount (lines);
glyphLayout.ensureStorageAllocated (numLines);
glyphLayout.ensureStorageAllocated ((int) numLines);
for (CFIndex i = 0; i < numLines; ++i)
{


+ 2
- 1
source/modules/juce_gui_basics/buttons/juce_Button.cpp View File

@@ -309,7 +309,8 @@ void Button::internalClickCallback (const ModifierKeys& modifiers)
{
if (clickTogglesState)
setToggleState (radioGroupId != 0 || ! lastToggleState, sendNotification);
else
if (radioGroupId != 0 || ! clickTogglesState)
sendClickMessage (modifiers);
}


+ 27
- 0
source/modules/juce_gui_basics/buttons/juce_Button.h View File

@@ -355,6 +355,33 @@ public:
// This method's parameters have changed - see the new version.
JUCE_DEPRECATED (void setToggleState (bool, bool));
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
button-drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawButtonBackground (Graphics&, Button& button, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) = 0;
virtual Font getTextButtonFont (TextButton& button) = 0;
/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) = 0;
/** Draws the contents of a standard ToggleButton. */
virtual void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) = 0;
virtual void changeToggleButtonWidthToFitText (ToggleButton&) = 0;
virtual void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) = 0;
virtual void drawDrawableButton (Graphics&, DrawableButton&, bool isMouseOverButton, bool isButtonDown) = 0;
};
protected:
//==============================================================================
/** This method is called when the button has been clicked.


+ 11
- 0
source/modules/juce_gui_basics/buttons/juce_ImageButton.h View File

@@ -124,6 +124,17 @@ public:
*/
Image getDownImage() const;
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawImageButton (Graphics&, Image*,
int imageX, int imageY, int imageW, int imageH,
const Colour& overlayColour, float imageOpacity, ImageButton&) = 0;
};
protected:
//==============================================================================
/** @internal */


+ 12
- 14
source/modules/juce_gui_basics/buttons/juce_ShapeButton.cpp View File

@@ -24,34 +24,32 @@
ShapeButton::ShapeButton (const String& t, Colour n, Colour o, Colour d)
: Button (t),
normalColour (n),
overColour (o),
downColour (d),
normalColour (n), overColour (o), downColour (d),
maintainShapeProportions (false),
outlineWidth (0.0f)
{
}
ShapeButton::~ShapeButton()
{
}
ShapeButton::~ShapeButton() {}
void ShapeButton::setColours (Colour newNormalColour,
Colour newOverColour,
Colour newDownColour)
void ShapeButton::setColours (Colour newNormalColour, Colour newOverColour, Colour newDownColour)
{
normalColour = newNormalColour;
overColour = newOverColour;
downColour = newDownColour;
}
void ShapeButton::setOutline (Colour newOutlineColour,
const float newOutlineWidth)
void ShapeButton::setOutline (Colour newOutlineColour, const float newOutlineWidth)
{
outlineColour = newOutlineColour;
outlineWidth = newOutlineWidth;
}
void ShapeButton::setBorderSize (BorderSize<int> newBorder)
{
border = newBorder;
}
void ShapeButton::setShape (const Path& newShape,
const bool resizeNowToFitThisShape,
const bool maintainShapeProportions_,
@@ -73,8 +71,8 @@ void ShapeButton::setShape (const Path& newShape,
shape.applyTransform (AffineTransform::translation (-newBounds.getX(),
-newBounds.getY()));
setSize (1 + (int) (newBounds.getWidth() + outlineWidth),
1 + (int) (newBounds.getHeight() + outlineWidth));
setSize (1 + (int) (newBounds.getWidth() + outlineWidth) + border.getLeftAndRight(),
1 + (int) (newBounds.getHeight() + outlineWidth) + border.getTopAndBottom());
}
repaint();
@@ -88,7 +86,7 @@ void ShapeButton::paintButton (Graphics& g, bool isMouseOverButton, bool isButto
isButtonDown = false;
}
Rectangle<float> r (getLocalBounds().toFloat().reduced (outlineWidth * 0.5f));
Rectangle<float> r (border.subtractedFrom (getLocalBounds()).toFloat().reduced (outlineWidth * 0.5f));
if (getComponentEffect() != nullptr)
r = r.reduced (2.0f);


+ 7
- 2
source/modules/juce_gui_basics/buttons/juce_ShapeButton.h View File

@@ -80,8 +80,12 @@ public:
@param outlineColour the colour to use
@param outlineStrokeWidth the thickness of line to draw
*/
void setOutline (Colour outlineColour,
float outlineStrokeWidth);
void setOutline (Colour outlineColour, float outlineStrokeWidth);
/** This lets you specify a border to be left around the edge of the button when
drawing the shape.
*/
void setBorderSize (BorderSize<int> border);
/** @internal */
void paintButton (Graphics&, bool isMouseOverButton, bool isButtonDown) override;
@@ -91,6 +95,7 @@ private:
Colour normalColour, overColour, downColour, outlineColour;
DropShadowEffect shadow;
Path shape;
BorderSize<int> border;
bool maintainShapeProportions;
float outlineWidth;


+ 1
- 1
source/modules/juce_gui_basics/components/juce_Desktop.cpp View File

@@ -89,7 +89,7 @@ LookAndFeel& Desktop::getDefaultLookAndFeel() noexcept
if (currentLookAndFeel == nullptr)
{
if (defaultLookAndFeel == nullptr)
defaultLookAndFeel = new LookAndFeel();
defaultLookAndFeel = new LookAndFeel_V2();
currentLookAndFeel = defaultLookAndFeel;
}


+ 1
- 0
source/modules/juce_gui_basics/filebrowser/juce_DirectoryContentsList.cpp View File

@@ -56,6 +56,7 @@ void DirectoryContentsList::setDirectory (const File& directory,
{
clear();
root = directory;
changed();
// (this forces a refresh when setTypeFlags() is called, rather than triggering two refreshes)
fileTypeFlags &= ~(File::findDirectories | File::findFiles);


+ 36
- 0
source/modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.h View File

@@ -177,6 +177,42 @@ public:
*/
static void getDefaultRoots (StringArray& rootNames, StringArray& rootPaths);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
various file-browser layout and drawing methods.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
// These return a pointer to an internally cached drawable - make sure you don't keep
// a copy of this pointer anywhere, as it may become invalid in the future.
virtual const Drawable* getDefaultFolderImage() = 0;
virtual const Drawable* getDefaultDocumentFileImage() = 0;
virtual AttributedString createFileChooserHeaderText (const String& title,
const String& instructions) = 0;
virtual void drawFileBrowserRow (Graphics&, int width, int height,
const String& filename,
Image* optionalIcon,
const String& fileSizeDescription,
const String& fileTimeDescription,
bool isDirectory,
bool isItemSelected,
int itemIndex,
DirectoryContentsDisplayComponent&) = 0;
virtual Button* createFileBrowserGoUpButton() = 0;
virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp,
DirectoryContentsDisplayComponent* fileListComponent,
FilePreviewComponent* previewComp,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton) = 0;
};
//==============================================================================
/** @internal */
void resized() override;


+ 10
- 0
source/modules/juce_gui_basics/filebrowser/juce_FilenameComponent.h View File

@@ -180,6 +180,16 @@ public:
/** Gives the component a tooltip. */
void setTooltip (const String& newTooltip) override;
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual Button* createFilenameComponentBrowseButton (const String& text) = 0;
virtual void layoutFilenameComponent (FilenameComponent&, ComboBox* filenameBox, Button* browseButton) = 0;
};
//==============================================================================
/** @internal */
void paintOverChildren (Graphics&) override;


+ 3
- 0
source/modules/juce_gui_basics/juce_gui_basics.cpp View File

@@ -198,6 +198,9 @@ extern bool juce_areThereAnyAlwaysOnTopWindows();
#include "layout/juce_TabbedComponent.cpp"
#include "layout/juce_Viewport.cpp"
#include "lookandfeel/juce_LookAndFeel.cpp"
#include "lookandfeel/juce_LookAndFeel_V2.cpp"
#include "lookandfeel/juce_LookAndFeel_V1.cpp"
#include "lookandfeel/juce_LookAndFeel_V3.cpp"
#include "menus/juce_MenuBarComponent.cpp"
#include "menus/juce_MenuBarModel.cpp"
#include "menus/juce_PopupMenu.cpp"


+ 5
- 1
source/modules/juce_gui_basics/juce_gui_basics.h View File

@@ -113,6 +113,7 @@ class CaretComponent;
class BubbleComponent;
class KeyPressMappingSet;
class ApplicationCommandManagerListener;
class DrawableButton;
#include "mouse/juce_MouseCursor.h"
#include "mouse/juce_MouseListener.h"
@@ -215,7 +216,6 @@ class ApplicationCommandManagerListener;
#include "windows/juce_ThreadWithProgressWindow.h"
#include "windows/juce_TooltipWindow.h"
#include "layout/juce_MultiDocumentPanel.h"
#include "lookandfeel/juce_LookAndFeel.h"
#include "filebrowser/juce_FileFilter.h"
#include "filebrowser/juce_WildcardFileFilter.h"
#include "filebrowser/juce_FileBrowserListener.h"
@@ -239,6 +239,10 @@ class ApplicationCommandManagerListener;
#include "properties/juce_TextPropertyComponent.h"
#include "application/juce_Application.h"
#include "misc/juce_BubbleComponent.h"
#include "lookandfeel/juce_LookAndFeel.h"
#include "lookandfeel/juce_LookAndFeel_V2.h"
#include "lookandfeel/juce_LookAndFeel_V1.h"
#include "lookandfeel/juce_LookAndFeel_V3.h"
}


+ 10
- 0
source/modules/juce_gui_basics/layout/juce_ConcertinaPanel.h View File

@@ -93,6 +93,16 @@ public:
/** Sets the height of the header section for one of the panels. */
void setPanelHeaderSize (Component* panelComponent, int headerSize);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
bool isMouseOver, bool isMouseDown, ConcertinaPanel&, Component&) = 0;
};
private:
void resized() override;


+ 5
- 18
source/modules/juce_gui_basics/layout/juce_GroupComponent.cpp View File

@@ -31,11 +31,8 @@ GroupComponent::GroupComponent (const String& name,
setInterceptsMouseClicks (false, true);
}
GroupComponent::~GroupComponent()
{
}
GroupComponent::~GroupComponent() {}
//==============================================================================
void GroupComponent::setText (const String& newText)
{
if (text != newText)
@@ -50,7 +47,6 @@ String GroupComponent::getText() const
return text;
}
//==============================================================================
void GroupComponent::setTextLabelPosition (Justification newJustification)
{
if (justification != newJustification)
@@ -62,18 +58,9 @@ void GroupComponent::setTextLabelPosition (Justification newJustification)
void GroupComponent::paint (Graphics& g)
{
getLookAndFeel()
.drawGroupComponentOutline (g, getWidth(), getHeight(),
text, justification,
*this);
getLookAndFeel().drawGroupComponentOutline (g, getWidth(), getHeight(),
text, justification, *this);
}
void GroupComponent::enablementChanged()
{
repaint();
}
void GroupComponent::colourChanged()
{
repaint();
}
void GroupComponent::enablementChanged() { repaint(); }
void GroupComponent::colourChanged() { repaint(); }

+ 10
- 0
source/modules/juce_gui_basics/layout/juce_GroupComponent.h View File

@@ -82,6 +82,16 @@ public:
textColourId = 0x1005410 /**< The colour to use to draw the text label. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawGroupComponentOutline (Graphics&, int w, int h, const String& text,
const Justification&, GroupComponent&) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 67
- 0
source/modules/juce_gui_basics/layout/juce_ScrollBar.h View File

@@ -292,6 +292,73 @@ public:
/** Deregisters a previously-registered listener. */
void removeListener (Listener* listener);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
scrollbar-drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual bool areScrollbarButtonsVisible() = 0;
/** Draws one of the buttons on a scrollbar.
@param g the context to draw into
@param scrollbar the bar itself
@param width the width of the button
@param height the height of the button
@param buttonDirection the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
@param isMouseOverButton whether the mouse is currently over the button (also true if it's held down)
@param isButtonDown whether the mouse button's held down
*/
virtual void drawScrollbarButton (Graphics& g,
ScrollBar& scrollbar,
int width, int height,
int buttonDirection,
bool isScrollbarVertical,
bool isMouseOverButton,
bool isButtonDown) = 0;
/** Draws the thumb area of a scrollbar.
@param g the context to draw into
@param scrollbar the bar itself
@param x the x position of the left edge of the thumb area to draw in
@param y the y position of the top edge of the thumb area to draw in
@param width the width of the thumb area to draw in
@param height the height of the thumb area to draw in
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
@param thumbStartPosition for vertical bars, the y coordinate of the top of the
thumb, or its x position for horizontal bars
@param thumbSize for vertical bars, the height of the thumb, or its width for
horizontal bars. This may be 0 if the thumb shouldn't be drawn.
@param isMouseOver whether the mouse is over the thumb area, also true if the mouse is
currently dragging the thumb
@param isMouseDown whether the mouse is currently dragging the scrollbar
*/
virtual void drawScrollbar (Graphics& g, ScrollBar& scrollbar,
int x, int y, int width, int height,
bool isScrollbarVertical,
int thumbStartPosition,
int thumbSize,
bool isMouseOver,
bool isMouseDown) = 0;
/** Returns the component effect to use for a scrollbar */
virtual ImageEffectFilter* getScrollbarEffect() = 0;
/** Returns the minimum length in pixels to use for a scrollbar thumb. */
virtual int getMinimumScrollbarThumbSize (ScrollBar&) = 0;
/** Returns the default thickness to use for a scrollbar. */
virtual int getDefaultScrollbarWidth() = 0;
/** Returns the length in pixels to use for a scrollbar button. */
virtual int getScrollbarButtonSize (ScrollBar&) = 0;
};
//==============================================================================
/** @internal */
bool keyPressed (const KeyPress&) override;


+ 10
- 0
source/modules/juce_gui_basics/layout/juce_StretchableLayoutResizerBar.h View File

@@ -72,6 +72,16 @@ public:
*/
virtual void hasBeenMoved();
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawStretchableLayoutResizerBar (Graphics&, int w, int h,
bool isVerticalBar, bool isMouseOver, bool isMouseDragging) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 19
- 0
source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp View File

@@ -93,7 +93,26 @@ void TabBarButton::calcAreas (Rectangle<int>& extraComp, Rectangle<int>& textAre
}
if (extraComponent != nullptr)
{
extraComp = lf.getTabButtonExtraComponentBounds (*this, textArea, *extraComponent);
const TabbedButtonBar::Orientation orientation = owner.getOrientation();
if (orientation == TabbedButtonBar::TabsAtLeft || orientation == TabbedButtonBar::TabsAtRight)
{
if (extraComp.getCentreY() > textArea.getCentreY())
textArea.setBottom (jmin (textArea.getBottom(), extraComp.getY()));
else
textArea.setTop (jmax (textArea.getY(), extraComp.getBottom()));
}
else
{
if (extraComp.getCentreX() > textArea.getCentreX())
textArea.setRight (jmin (textArea.getRight(), extraComp.getX()));
else
textArea.setLeft (jmax (textArea.getX(), extraComp.getRight()));
}
}
}
Rectangle<int> TabBarButton::getTextArea() const


+ 24
- 0
source/modules/juce_gui_basics/layout/juce_TabbedButtonBar.h View File

@@ -293,6 +293,30 @@ public:
colour. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
window drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual int getTabButtonSpaceAroundImage() = 0;
virtual int getTabButtonOverlap (int tabDepth) = 0;
virtual int getTabButtonBestWidth (TabBarButton&, int tabDepth) = 0;
virtual Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton&, Rectangle<int>& textArea, Component& extraComp) = 0;
virtual void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) = 0;
virtual void drawTabButtonText (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) = 0;
virtual void drawTabbedButtonBarBackground (TabbedButtonBar&, Graphics&) = 0;
virtual void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int w, int h) = 0;
virtual void createTabButtonShape (TabBarButton&, Path& path, bool isMouseOver, bool isMouseDown) = 0;
virtual void fillTabButtonShape (TabBarButton&, Graphics&, const Path& path, bool isMouseOver, bool isMouseDown) = 0;
virtual Button* createTabBarExtrasButton() = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 5
- 2774
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.cpp
File diff suppressed because it is too large
View File


+ 83
- 519
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel.h View File

@@ -25,14 +25,80 @@
#ifndef JUCE_LOOKANDFEEL_H_INCLUDED
#define JUCE_LOOKANDFEEL_H_INCLUDED
//==============================================================================
/** This class is used to hold a few look and feel base classes which are associated
with classes that may not be present because they're from modules other than
juce_gui_basics.
*/
struct JUCE_API ExtraLookAndFeelBaseClasses
{
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LassoComponentMethods
{
virtual ~LassoComponentMethods() {}
virtual void drawLasso (Graphics&, Component& lassoComp) = 0;
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API KeyMappingEditorComponentMethods
{
virtual ~KeyMappingEditorComponentMethods() {}
virtual void drawKeymapChangeButton (Graphics&, int width, int height, Button&, const String& keyDescription) = 0;
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API AudioDeviceSelectorComponentMethods
{
virtual ~AudioDeviceSelectorComponentMethods() {}
virtual void drawLevelMeter (Graphics&, int width, int height, float level) = 0;
};
};
//==============================================================================
/**
LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses
can be used to apply different 'skins' to the application.
This class is an abstract base-class - for actual look-and-feels that you can
instantiate, see LookAndFeel_V1, LookAndFeel_V2 and LookAndFeel_V3.
@see LookAndFeel_V1, LookAndFeel_V2, LookAndFeel_V3
*/
class JUCE_API LookAndFeel
class JUCE_API LookAndFeel : public ScrollBar::LookAndFeelMethods,
public Button::LookAndFeelMethods,
public ImageButton::LookAndFeelMethods,
public TextEditor::LookAndFeelMethods,
public FileBrowserComponent::LookAndFeelMethods,
public TreeView::LookAndFeelMethods,
public BubbleComponent::LookAndFeelMethods,
public AlertWindow::LookAndFeelMethods,
public PopupMenu::LookAndFeelMethods,
public ComboBox::LookAndFeelMethods,
public Label::LookAndFeelMethods,
public Slider::LookAndFeelMethods,
public ResizableWindow::LookAndFeelMethods,
public DocumentWindow::LookAndFeelMethods,
public TooltipWindow::LookAndFeelMethods,
public TabbedButtonBar::LookAndFeelMethods,
public PropertyComponent::LookAndFeelMethods,
public FilenameComponent::LookAndFeelMethods,
public GroupComponent::LookAndFeelMethods,
public TableHeaderComponent::LookAndFeelMethods,
public CallOutBox::LookAndFeelMethods,
public Toolbar::LookAndFeelMethods,
public ConcertinaPanel::LookAndFeelMethods,
public ProgressBar::LookAndFeelMethods,
public StretchableLayoutResizerBar::LookAndFeelMethods,
public ExtraLookAndFeelBaseClasses::KeyMappingEditorComponentMethods,
public ExtraLookAndFeelBaseClasses::AudioDeviceSelectorComponentMethods,
public ExtraLookAndFeelBaseClasses::LassoComponentMethods
{
public:
//==============================================================================
@@ -60,7 +126,6 @@ public:
*/
static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) noexcept;
//==============================================================================
/** Looks for a colour that has been registered with the given colour ID number.
@@ -82,9 +147,7 @@ public:
Colour findColour (int colourId) const noexcept;
/** Registers a colour to be used for a particular purpose.
For more details, see the comments for findColour().
@see findColour, Component::findColour, Component::setColour
*/
void setColour (int colourId, Colour colour) noexcept;
@@ -94,9 +157,12 @@ public:
*/
bool isColourSpecified (int colourId) const noexcept;
//==============================================================================
virtual Typeface::Ptr getTypefaceForFont (const Font& font);
/** Returns the typeface that should be used for a given font.
The default implementation just does what you'd expect it to, but you can override
this if you want to intercept fonts and use your own custom typeface object.
*/
virtual Typeface::Ptr getTypefaceForFont (const Font&);
/** Allows you to change the default sans-serif font.
@@ -110,509 +176,38 @@ public:
/** Override this to get the chance to swap a component's mouse cursor for a
customised one.
*/
virtual MouseCursor getMouseCursorFor (Component& component);
virtual MouseCursor getMouseCursorFor (Component&);
//==============================================================================
// Creates a new graphics context object.
/** Creates a new graphics context object. */
virtual LowLevelGraphicsContext* createGraphicsContext (const Image& imageToRenderOn,
const Point<int>& origin,
const RectangleList<int>& initialClip);
//==============================================================================
/** Draws the lozenge-shaped background for a standard button. */
virtual void drawButtonBackground (Graphics&,
Button& button,
const Colour& backgroundColour,
bool isMouseOverButton,
bool isButtonDown);
virtual Font getTextButtonFont (TextButton& button);
/** Draws the text for a TextButton. */
virtual void drawButtonText (Graphics&,
TextButton& button,
bool isMouseOverButton,
bool isButtonDown);
/** Draws the contents of a standard ToggleButton. */
virtual void drawToggleButton (Graphics&,
ToggleButton& button,
bool isMouseOverButton,
bool isButtonDown);
virtual void changeToggleButtonWidthToFitText (ToggleButton& button);
virtual void drawTickBox (Graphics&,
Component& component,
float x, float y, float w, float h,
bool ticked,
bool isEnabled,
bool isMouseOverButton,
bool isButtonDown);
virtual void drawDrawableButton (Graphics&,
DrawableButton& button,
bool isMouseOverButton,
bool isButtonDown);
//==============================================================================
// AlertWindow handling..
virtual AlertWindow* createAlertWindow (const String& title,
const String& message,
const String& button1,
const String& button2,
const String& button3,
AlertWindow::AlertIconType iconType,
int numButtons,
Component* associatedComponent);
virtual void drawAlertBox (Graphics&,
AlertWindow& alert,
const Rectangle<int>& textArea,
TextLayout& textLayout);
virtual int getAlertBoxWindowFlags();
virtual int getAlertWindowButtonHeight();
virtual Font getAlertWindowMessageFont();
virtual Font getAlertWindowFont();
void setUsingNativeAlertWindows (bool shouldUseNativeAlerts);
bool isUsingNativeAlertWindows();
/** Draws a progress bar.
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
bar that fills the whole space (i.e. to say that the app is still busy but the progress
isn't known). It can use the current time as a basis for playing an animation.
(Used by progress bars in AlertWindow).
*/
virtual void drawProgressBar (Graphics&, ProgressBar& progressBar,
int width, int height,
double progress, const String& textToShow);
//==============================================================================
// Draws a small image that spins to indicate that something's happening..
// This method should use the current time to animate itself, so just keep
// repainting it every so often.
virtual void drawSpinningWaitAnimation (Graphics&, const Colour& colour,
int x, int y, int w, int h);
//==============================================================================
virtual bool areScrollbarButtonsVisible();
/** Draws one of the buttons on a scrollbar.
@param g the context to draw into
@param scrollbar the bar itself
@param width the width of the button
@param height the height of the button
@param buttonDirection the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
@param isMouseOverButton whether the mouse is currently over the button (also true if it's held down)
@param isButtonDown whether the mouse button's held down
/** Draws a small image that spins to indicate that something's happening.
This method should use the current time to animate itself, so just keep
repainting it every so often.
*/
virtual void drawScrollbarButton (Graphics& g,
ScrollBar& scrollbar,
int width, int height,
int buttonDirection,
bool isScrollbarVertical,
bool isMouseOverButton,
bool isButtonDown);
/** Draws the thumb area of a scrollbar.
@param g the context to draw into
@param scrollbar the bar itself
@param x the x position of the left edge of the thumb area to draw in
@param y the y position of the top edge of the thumb area to draw in
@param width the width of the thumb area to draw in
@param height the height of the thumb area to draw in
@param isScrollbarVertical true if it's a vertical bar, false if horizontal
@param thumbStartPosition for vertical bars, the y coordinate of the top of the
thumb, or its x position for horizontal bars
@param thumbSize for vertical bars, the height of the thumb, or its width for
horizontal bars. This may be 0 if the thumb shouldn't be drawn.
@param isMouseOver whether the mouse is over the thumb area, also true if the mouse is
currently dragging the thumb
@param isMouseDown whether the mouse is currently dragging the scrollbar
*/
virtual void drawScrollbar (Graphics& g,
ScrollBar& scrollbar,
int x, int y,
int width, int height,
bool isScrollbarVertical,
int thumbStartPosition,
int thumbSize,
bool isMouseOver,
bool isMouseDown);
/** Returns the component effect to use for a scrollbar */
virtual ImageEffectFilter* getScrollbarEffect();
/** Returns the minimum length in pixels to use for a scrollbar thumb. */
virtual int getMinimumScrollbarThumbSize (ScrollBar& scrollbar);
/** Returns the default thickness to use for a scrollbar. */
virtual int getDefaultScrollbarWidth();
/** Returns the length in pixels to use for a scrollbar button. */
virtual int getScrollbarButtonSize (ScrollBar& scrollbar);
virtual void drawSpinningWaitAnimation (Graphics&, const Colour& colour,
int x, int y, int w, int h) = 0;
//==============================================================================
/** Returns a tick shape for use in yes/no boxes, etc. */
virtual Path getTickShape (float height);
virtual Path getTickShape (float height) = 0;
/** Returns a cross shape for use in yes/no boxes, etc. */
virtual Path getCrossShape (float height);
//==============================================================================
/** Draws the + or - box in a treeview. */
virtual void drawTreeviewPlusMinusBox (Graphics&, int x, int y, int w, int h, bool isPlus, bool isMouseOver);
virtual Path getCrossShape (float height) = 0;
//==============================================================================
virtual void fillTextEditorBackground (Graphics&, int width, int height, TextEditor& textEditor);
virtual void drawTextEditorOutline (Graphics&, int width, int height, TextEditor& textEditor);
virtual CaretComponent* createCaretComponent (Component* keyFocusOwner);
//==============================================================================
// These return a pointer to an internally cached drawable - make sure you don't keep
// a copy of this pointer anywhere, as it may become invalid in the future.
virtual const Drawable* getDefaultFolderImage();
virtual const Drawable* getDefaultDocumentFileImage();
virtual AttributedString createFileChooserHeaderText (const String& title,
const String& instructions);
virtual void drawFileBrowserRow (Graphics&, int width, int height,
const String& filename, Image* icon,
const String& fileSizeDescription,
const String& fileTimeDescription,
bool isDirectory,
bool isItemSelected,
int itemIndex,
DirectoryContentsDisplayComponent& component);
virtual Button* createFileBrowserGoUpButton();
virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp,
DirectoryContentsDisplayComponent* fileListComponent,
FilePreviewComponent* previewComp,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton);
//==============================================================================
virtual void drawBubble (Graphics&, BubbleComponent&,
const Point<float>& tip, const Rectangle<float>& body);
//==============================================================================
virtual void drawLasso (Graphics&, Component& lassoComp);
//==============================================================================
/** Fills the background of a popup menu component. */
virtual void drawPopupMenuBackground (Graphics&, int width, int height);
/** Draws one of the items in a popup menu. */
virtual void drawPopupMenuItem (Graphics&,
int width, int height,
bool isSeparator,
bool isActive,
bool isHighlighted,
bool isTicked,
bool hasSubMenu,
const String& text,
const String& shortcutKeyText,
Image* image,
const Colour* const textColour);
/** Returns the size and style of font to use in popup menus. */
virtual Font getPopupMenuFont();
virtual void drawPopupMenuUpDownArrow (Graphics&,
int width, int height,
bool isScrollUpArrow);
/** Finds the best size for an item in a popup menu. */
virtual void getIdealPopupMenuItemSize (const String& text,
bool isSeparator,
int standardMenuItemHeight,
int& idealWidth,
int& idealHeight);
virtual int getMenuWindowFlags();
virtual void drawMenuBarBackground (Graphics&, int width, int height,
bool isMouseOverBar,
MenuBarComponent& menuBar);
virtual int getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText);
virtual Font getMenuBarFont (MenuBarComponent& menuBar, int itemIndex, const String& itemText);
virtual void drawMenuBarItem (Graphics&,
int width, int height,
int itemIndex,
const String& itemText,
bool isMouseOverItem,
bool isMenuOpen,
bool isMouseOverBar,
MenuBarComponent& menuBar);
//==============================================================================
virtual void drawComboBox (Graphics&, int width, int height,
bool isButtonDown,
int buttonX, int buttonY,
int buttonW, int buttonH,
ComboBox& box);
virtual Font getComboBoxFont (ComboBox& box);
virtual Label* createComboBoxTextBox (ComboBox& box);
virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition);
virtual DropShadower* createDropShadowerForComponent (Component*) = 0;
//==============================================================================
virtual void drawLabel (Graphics&, Label&);
virtual Font getLabelFont (Label&);
//==============================================================================
virtual void drawLinearSlider (Graphics&,
int x, int y,
int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle style,
Slider& slider);
virtual void drawLinearSliderBackground (Graphics&,
int x, int y,
int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle style,
Slider& slider);
virtual void drawLinearSliderThumb (Graphics&,
int x, int y,
int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle style,
Slider& slider);
virtual int getSliderThumbRadius (Slider& slider);
virtual void drawRotarySlider (Graphics&,
int x, int y,
int width, int height,
float sliderPosProportional,
float rotaryStartAngle,
float rotaryEndAngle,
Slider& slider);
virtual Button* createSliderButton (bool isIncrement);
virtual Label* createSliderTextBox (Slider& slider);
virtual ImageEffectFilter* getSliderEffect();
virtual Font getSliderPopupFont();
virtual int getSliderPopupPlacement();
//==============================================================================
virtual void getTooltipSize (const String& tipText, int& width, int& height);
virtual void drawTooltip (Graphics&, const String& text, int width, int height);
//==============================================================================
virtual Button* createFilenameComponentBrowseButton (const String& text);
virtual void layoutFilenameComponent (FilenameComponent& filenameComp,
ComboBox* filenameBox, Button* browseButton);
//==============================================================================
virtual void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component& panel);
//==============================================================================
virtual void drawCornerResizer (Graphics&,
int w, int h,
bool isMouseOver,
bool isMouseDragging);
virtual void drawResizableFrame (Graphics&,
int w, int h,
const BorderSize<int>&);
//==============================================================================
virtual void fillResizableWindowBackground (Graphics&, int w, int h,
const BorderSize<int>&,
ResizableWindow& window);
virtual void drawResizableWindowBorder (Graphics&,
int w, int h,
const BorderSize<int>& border,
ResizableWindow& window);
//==============================================================================
virtual void drawDocumentWindowTitleBar (DocumentWindow& window,
Graphics&, int w, int h,
int titleSpaceX, int titleSpaceW,
const Image* icon,
bool drawTitleTextOnLeft);
virtual Button* createDocumentWindowButton (int buttonType);
virtual void positionDocumentWindowButtons (DocumentWindow& window,
int titleBarX, int titleBarY,
int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft);
virtual int getDefaultMenuBarHeight();
//==============================================================================
virtual DropShadower* createDropShadowerForComponent (Component* component);
//==============================================================================
virtual void drawStretchableLayoutResizerBar (Graphics&,
int w, int h,
bool isVerticalBar,
bool isMouseOver,
bool isMouseDragging);
//==============================================================================
virtual void drawGroupComponentOutline (Graphics&, int w, int h,
const String& text,
const Justification& position,
GroupComponent& group);
//==============================================================================
virtual int getTabButtonSpaceAroundImage();
virtual int getTabButtonOverlap (int tabDepth);
virtual int getTabButtonBestWidth (TabBarButton&, int tabDepth);
virtual Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton&, Rectangle<int>& textArea, Component& extraComp);
virtual void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown);
virtual void drawTabButtonText (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown);
virtual void drawTabbedButtonBarBackground (TabbedButtonBar&, Graphics&);
virtual void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int w, int h);
virtual void createTabButtonShape (TabBarButton&, Path& path, bool isMouseOver, bool isMouseDown);
virtual void fillTabButtonShape (TabBarButton&, Graphics&, const Path& path, bool isMouseOver, bool isMouseDown);
virtual Button* createTabBarExtrasButton();
//==============================================================================
virtual void drawImageButton (Graphics&, Image* image,
int imageX, int imageY, int imageW, int imageH,
const Colour& overlayColour,
float imageOpacity,
ImageButton& button);
//==============================================================================
virtual void drawTableHeaderBackground (Graphics&, TableHeaderComponent&);
virtual void drawTableHeaderColumn (Graphics&, const String& columnName, int columnId,
int width, int height,
bool isMouseOver, bool isMouseDown,
int columnFlags);
//==============================================================================
virtual void paintToolbarBackground (Graphics&, int width, int height, Toolbar& toolbar);
virtual Button* createToolbarMissingItemsButton (Toolbar& toolbar);
virtual void paintToolbarButtonBackground (Graphics&, int width, int height,
bool isMouseOver, bool isMouseDown,
ToolbarItemComponent& component);
virtual void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
const String& text, ToolbarItemComponent& component);
//==============================================================================
virtual void drawPropertyPanelSectionHeader (Graphics&, const String& name,
bool isOpen, int width, int height);
virtual void drawPropertyComponentBackground (Graphics&, int width, int height,
PropertyComponent& component);
virtual void drawPropertyComponentLabel (Graphics&, int width, int height,
PropertyComponent& component);
virtual Rectangle<int> getPropertyComponentContentPosition (PropertyComponent& component);
//==============================================================================
virtual void drawCallOutBoxBackground (CallOutBox& box, Graphics&, const Path& path, Image& cachedImage);
//==============================================================================
virtual void drawLevelMeter (Graphics&, int width, int height, float level);
virtual void drawKeymapChangeButton (Graphics&, int width, int height, Button& button, const String& keyDescription);
//==============================================================================
/** Plays the system's default 'beep' noise, to alert the user about something very important.
*/
/** Plays the system's default 'beep' noise, to alert the user about something very important. */
virtual void playAlertSound();
//==============================================================================
/** Draws a 3D raised (or indented) bevel using two colours.
The bevel is drawn inside the given rectangle, and greater bevel thicknesses
extend inwards.
The top-left colour is used for the top- and left-hand edges of the
bevel; the bottom-right colour is used for the bottom- and right-hand
edges.
If useGradient is true, then the bevel fades out to make it look more curved
and less angular. If sharpEdgeOnOutside is true, the outside of the bevel is
sharp, and it fades towards the centre; if sharpEdgeOnOutside is false, then
the centre edges are sharp and it fades towards the outside.
*/
static void drawBevel (Graphics&,
int x, int y, int width, int height,
int bevelThickness,
const Colour& topLeftColour = Colours::white,
const Colour& bottomRightColour = Colours::black,
bool useGradient = true,
bool sharpEdgeOnOutside = true);
/** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */
static void drawGlassSphere (Graphics&,
float x, float y,
float diameter,
const Colour& colour,
float outlineThickness) noexcept;
static void drawGlassPointer (Graphics&,
float x, float y,
float diameter,
const Colour& colour, float outlineThickness,
int direction) noexcept;
/** Utility function to draw a shiny, glassy oblong (for text buttons). */
static void drawGlassLozenge (Graphics&,
float x, float y,
float width, float height,
const Colour& colour,
float outlineThickness,
float cornerSize,
bool flatOnLeft, bool flatOnRight,
bool flatOnTop, bool flatOnBottom) noexcept;
static Drawable* loadDrawableFromData (const void* data, size_t numBytes);
private:
//==============================================================================
friend class WeakReference<LookAndFeel>;
@@ -628,40 +223,9 @@ private:
};
SortedSet<ColourSetting> colours;
// default typeface names
String defaultSans, defaultSerif, defaultFixed;
ScopedPointer<Drawable> folderImage, documentImage;
bool useNativeAlertWindows;
void drawShinyButtonShape (Graphics&,
float x, float y, float w, float h, float maxCornerSize,
const Colour& baseColour,
float strokeWidth,
bool flatOnLeft,
bool flatOnRight,
bool flatOnTop,
bool flatOnBottom) noexcept;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// These methods have been deprecated - see their new parameter lists..
virtual int drawFileBrowserRow (Graphics&, int, int, const String&, Image*, const String&, const String&, bool, bool, int) { return 0; }
virtual int drawTabButton (Graphics&, int, int, const Colour&, int, const String&, Button&, TabbedButtonBar::Orientation, bool, bool, bool) { return 0; }
virtual int createTabButtonShape (Path&, int, int, int, const String&, Button&, TabbedButtonBar::Orientation, bool, bool, bool) { return 0; }
virtual int fillTabButtonShape (Graphics&, const Path&, const Colour&, int, const String&, Button&, TabbedButtonBar::Orientation, bool, bool, bool) { return 0; }
virtual int drawTabAreaBehindFrontButton (Graphics&, int, int, TabbedButtonBar&, TabbedButtonBar::Orientation) { return 0; }
virtual int drawTabButtonText (Graphics&, int, int, int, int, const Colour&, int, const String&, Button&, TabbedButtonBar::Orientation, bool, bool, bool) { return 0; }
virtual int getTabButtonBestWidth (int, const String&, int, Button&) { return 0; }
virtual int drawBubble (Graphics&, float, float, float, float, float, float) { return 0; }
virtual int getFontForTextButton (TextButton&) { return 0; }
virtual int createFileChooserHeaderText (const String&, const String&, GlyphArrangement&, int) { return 0; }
#endif
class GlassWindowButton;
class SliderLabelComp;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel)
};


+ 567
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.cpp View File

@@ -0,0 +1,567 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
LookAndFeel_V1::LookAndFeel_V1()
{
setColour (TextButton::buttonColourId, Colour (0xffbbbbff));
setColour (ListBox::outlineColourId, findColour (ComboBox::outlineColourId));
setColour (ScrollBar::thumbColourId, Colour (0xffbbbbdd));
setColour (ScrollBar::backgroundColourId, Colours::transparentBlack);
setColour (Slider::thumbColourId, Colours::white);
setColour (Slider::trackColourId, Colour (0x7f000000));
setColour (Slider::textBoxOutlineColourId, Colours::grey);
setColour (ProgressBar::backgroundColourId, Colours::white.withAlpha (0.6f));
setColour (ProgressBar::foregroundColourId, Colours::green.withAlpha (0.7f));
setColour (PopupMenu::backgroundColourId, Colour (0xffeef5f8));
setColour (PopupMenu::highlightedBackgroundColourId, Colour (0xbfa4c2ce));
setColour (PopupMenu::highlightedTextColourId, Colours::black);
setColour (TextEditor::focusedOutlineColourId, findColour (TextButton::buttonColourId));
scrollbarShadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 2, Point<int>()));
}
LookAndFeel_V1::~LookAndFeel_V1()
{
}
//==============================================================================
void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown)
{
const int width = button.getWidth();
const int height = button.getHeight();
const float indent = 2.0f;
const int cornerSize = jmin (roundToInt (width * 0.4f),
roundToInt (height * 0.4f));
Path p;
p.addRoundedRectangle (indent, indent,
width - indent * 2.0f,
height - indent * 2.0f,
(float) cornerSize);
Colour bc (backgroundColour.withMultipliedSaturation (0.3f));
if (isMouseOverButton)
{
if (isButtonDown)
bc = bc.brighter();
else if (bc.getBrightness() > 0.5f)
bc = bc.darker (0.1f);
else
bc = bc.brighter (0.1f);
}
g.setColour (bc);
g.fillPath (p);
g.setColour (bc.contrasting().withAlpha ((isMouseOverButton) ? 0.6f : 0.4f));
g.strokePath (p, PathStrokeType ((isMouseOverButton) ? 2.0f : 1.4f));
}
void LookAndFeel_V1::drawTickBox (Graphics& g, Component& /*component*/,
float x, float y, float w, float h,
const bool ticked,
const bool isEnabled,
const bool /*isMouseOverButton*/,
const bool isButtonDown)
{
Path box;
box.addRoundedRectangle (0.0f, 2.0f, 6.0f, 6.0f, 1.0f);
g.setColour (isEnabled ? Colours::blue.withAlpha (isButtonDown ? 0.3f : 0.1f)
: Colours::lightgrey.withAlpha (0.1f));
AffineTransform trans (AffineTransform::scale (w / 9.0f, h / 9.0f).translated (x, y));
g.fillPath (box, trans);
g.setColour (Colours::black.withAlpha (0.6f));
g.strokePath (box, PathStrokeType (0.9f), trans);
if (ticked)
{
Path tick;
tick.startNewSubPath (1.5f, 3.0f);
tick.lineTo (3.0f, 6.0f);
tick.lineTo (6.0f, 0.0f);
g.setColour (isEnabled ? Colours::black : Colours::grey);
g.strokePath (tick, PathStrokeType (2.5f), trans);
}
}
void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown)
{
if (button.hasKeyboardFocus (true))
{
g.setColour (button.findColour (TextEditor::focusedOutlineColourId));
g.drawRect (0, 0, button.getWidth(), button.getHeight());
}
const int tickWidth = jmin (20, button.getHeight() - 4);
drawTickBox (g, button, 4.0f, (button.getHeight() - tickWidth) * 0.5f,
(float) tickWidth, (float) tickWidth,
button.getToggleState(),
button.isEnabled(),
isMouseOverButton,
isButtonDown);
g.setColour (button.findColour (ToggleButton::textColourId));
g.setFont (jmin (15.0f, button.getHeight() * 0.6f));
if (! button.isEnabled())
g.setOpacity (0.5f);
const int textX = tickWidth + 5;
g.drawFittedText (button.getButtonText(),
textX, 4,
button.getWidth() - textX - 2, button.getHeight() - 8,
Justification::centredLeft, 10);
}
void LookAndFeel_V1::drawProgressBar (Graphics& g, ProgressBar& progressBar,
int width, int height,
double progress, const String& textToShow)
{
if (progress < 0 || progress >= 1.0)
{
LookAndFeel_V2::drawProgressBar (g, progressBar, width, height, progress, textToShow);
}
else
{
const Colour background (progressBar.findColour (ProgressBar::backgroundColourId));
const Colour foreground (progressBar.findColour (ProgressBar::foregroundColourId));
g.fillAll (background);
g.setColour (foreground);
g.fillRect (1, 1,
jlimit (0, width - 2, roundToInt (progress * (width - 2))),
height - 2);
if (textToShow.isNotEmpty())
{
g.setColour (Colour::contrasting (background, foreground));
g.setFont (height * 0.6f);
g.drawText (textToShow, 0, 0, width, height, Justification::centred, false);
}
}
}
void LookAndFeel_V1::drawScrollbarButton (Graphics& g, ScrollBar& bar,
int width, int height, int buttonDirection,
bool isScrollbarVertical,
bool isMouseOverButton,
bool isButtonDown)
{
if (isScrollbarVertical)
width -= 2;
else
height -= 2;
Path p;
if (buttonDirection == 0)
p.addTriangle (width * 0.5f, height * 0.2f,
width * 0.1f, height * 0.7f,
width * 0.9f, height * 0.7f);
else if (buttonDirection == 1)
p.addTriangle (width * 0.8f, height * 0.5f,
width * 0.3f, height * 0.1f,
width * 0.3f, height * 0.9f);
else if (buttonDirection == 2)
p.addTriangle (width * 0.5f, height * 0.8f,
width * 0.1f, height * 0.3f,
width * 0.9f, height * 0.3f);
else if (buttonDirection == 3)
p.addTriangle (width * 0.2f, height * 0.5f,
width * 0.7f, height * 0.1f,
width * 0.7f, height * 0.9f);
if (isButtonDown)
g.setColour (Colours::white);
else if (isMouseOverButton)
g.setColour (Colours::white.withAlpha (0.7f));
else
g.setColour (bar.findColour (ScrollBar::thumbColourId).withAlpha (0.5f));
g.fillPath (p);
g.setColour (Colours::black.withAlpha (0.5f));
g.strokePath (p, PathStrokeType (0.5f));
}
void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar,
int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown)
{
g.fillAll (bar.findColour (ScrollBar::backgroundColourId));
g.setColour (bar.findColour (ScrollBar::thumbColourId)
.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.15f));
if (thumbSize > 0.0f)
{
Rectangle<int> thumb;
if (isScrollbarVertical)
{
width -= 2;
g.fillRect (x + roundToInt (width * 0.35f), y,
roundToInt (width * 0.3f), height);
thumb.setBounds (x + 1, thumbStartPosition,
width - 2, thumbSize);
}
else
{
height -= 2;
g.fillRect (x, y + roundToInt (height * 0.35f),
width, roundToInt (height * 0.3f));
thumb.setBounds (thumbStartPosition, y + 1,
thumbSize, height - 2);
}
g.setColour (bar.findColour (ScrollBar::thumbColourId)
.withAlpha ((isMouseOver || isMouseDown) ? 0.95f : 0.7f));
g.fillRect (thumb);
g.setColour (Colours::black.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.25f));
g.drawRect (thumb.getX(), thumb.getY(), thumb.getWidth(), thumb.getHeight());
if (thumbSize > 16)
{
for (int i = 3; --i >= 0;)
{
const float linePos = thumbStartPosition + thumbSize / 2 + (i - 1) * 4.0f;
g.setColour (Colours::black.withAlpha (0.15f));
if (isScrollbarVertical)
{
g.drawLine (x + width * 0.2f, linePos, width * 0.8f, linePos);
g.setColour (Colours::white.withAlpha (0.15f));
g.drawLine (width * 0.2f, linePos - 1, width * 0.8f, linePos - 1);
}
else
{
g.drawLine (linePos, height * 0.2f, linePos, height * 0.8f);
g.setColour (Colours::white.withAlpha (0.15f));
g.drawLine (linePos - 1, height * 0.2f, linePos - 1, height * 0.8f);
}
}
}
}
}
ImageEffectFilter* LookAndFeel_V1::getScrollbarEffect()
{
return &scrollbarShadow;
}
//==============================================================================
void LookAndFeel_V1::drawPopupMenuBackground (Graphics& g, int width, int height)
{
g.fillAll (findColour (PopupMenu::backgroundColourId));
g.setColour (Colours::black.withAlpha (0.6f));
g.drawRect (0, 0, width, height);
}
void LookAndFeel_V1::drawMenuBarBackground (Graphics& g, int /*width*/, int /*height*/, bool, MenuBarComponent& menuBar)
{
g.fillAll (menuBar.findColour (PopupMenu::backgroundColourId));
}
//==============================================================================
void LookAndFeel_V1::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
{
if (textEditor.isEnabled())
{
g.setColour (textEditor.findColour (TextEditor::outlineColourId));
g.drawRect (0, 0, width, height);
}
}
//==============================================================================
void LookAndFeel_V1::drawComboBox (Graphics& g, int width, int height,
const bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox& box)
{
g.fillAll (box.findColour (ComboBox::backgroundColourId));
g.setColour (box.findColour ((isButtonDown) ? ComboBox::buttonColourId
: ComboBox::backgroundColourId));
g.fillRect (buttonX, buttonY, buttonW, buttonH);
g.setColour (box.findColour (ComboBox::outlineColourId));
g.drawRect (0, 0, width, height);
const float arrowX = 0.2f;
const float arrowH = 0.3f;
if (box.isEnabled())
{
Path p;
p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH),
buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f,
buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f);
p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH),
buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f,
buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f);
g.setColour (box.findColour ((isButtonDown) ? ComboBox::backgroundColourId
: ComboBox::buttonColourId));
g.fillPath (p);
}
}
Font LookAndFeel_V1::getComboBoxFont (ComboBox& box)
{
Font f (jmin (15.0f, box.getHeight() * 0.85f));
f.setHorizontalScale (0.9f);
return f;
}
//==============================================================================
static void drawTriangle (Graphics& g, float x1, float y1, float x2, float y2, float x3, float y3, Colour fill, Colour outline)
{
Path p;
p.addTriangle (x1, y1, x2, y2, x3, y3);
g.setColour (fill);
g.fillPath (p);
g.setColour (outline);
g.strokePath (p, PathStrokeType (0.3f));
}
void LookAndFeel_V1::drawLinearSlider (Graphics& g,
int x, int y, int w, int h,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle style,
Slider& slider)
{
g.fillAll (slider.findColour (Slider::backgroundColourId));
if (style == Slider::LinearBar)
{
g.setColour (slider.findColour (Slider::thumbColourId));
g.fillRect (x, y, (int) sliderPos - x, h);
g.setColour (slider.findColour (Slider::textBoxTextColourId).withMultipliedAlpha (0.5f));
g.drawRect (x, y, (int) sliderPos - x, h);
}
else
{
g.setColour (slider.findColour (Slider::trackColourId)
.withMultipliedAlpha (slider.isEnabled() ? 1.0f : 0.3f));
if (slider.isHorizontal())
{
g.fillRect (x, y + roundToInt (h * 0.6f),
w, roundToInt (h * 0.2f));
}
else
{
g.fillRect (x + roundToInt (w * 0.5f - jmin (3.0f, w * 0.1f)), y,
jmin (4, roundToInt (w * 0.2f)), h);
}
float alpha = 0.35f;
if (slider.isEnabled())
alpha = slider.isMouseOverOrDragging() ? 1.0f : 0.7f;
const Colour fill (slider.findColour (Slider::thumbColourId).withAlpha (alpha));
const Colour outline (Colours::black.withAlpha (slider.isEnabled() ? 0.7f : 0.35f));
if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical)
{
drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), minSliderPos,
x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos - 7.0f,
x + w * 0.5f - jmin (8.0f, w * 0.4f), minSliderPos,
fill, outline);
drawTriangle (g, x + w * 0.5f + jmin (4.0f, w * 0.3f), maxSliderPos,
x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos,
x + w * 0.5f - jmin (8.0f, w * 0.4f), maxSliderPos + 7.0f,
fill, outline);
}
else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal)
{
drawTriangle (g, minSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f),
minSliderPos - 7.0f, y + h * 0.9f ,
minSliderPos, y + h * 0.9f,
fill, outline);
drawTriangle (g, maxSliderPos, y + h * 0.6f - jmin (4.0f, h * 0.3f),
maxSliderPos, y + h * 0.9f,
maxSliderPos + 7.0f, y + h * 0.9f,
fill, outline);
}
if (style == Slider::LinearHorizontal || style == Slider::ThreeValueHorizontal)
{
drawTriangle (g, sliderPos, y + h * 0.9f,
sliderPos - 7.0f, y + h * 0.2f,
sliderPos + 7.0f, y + h * 0.2f,
fill, outline);
}
else if (style == Slider::LinearVertical || style == Slider::ThreeValueVertical)
{
drawTriangle (g, x + w * 0.5f - jmin (4.0f, w * 0.3f), sliderPos,
x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos - 7.0f,
x + w * 0.5f + jmin (8.0f, w * 0.4f), sliderPos + 7.0f,
fill, outline);
}
}
}
Button* LookAndFeel_V1::createSliderButton (const bool isIncrement)
{
if (isIncrement)
return new ArrowButton ("u", 0.75f, Colours::white.withAlpha (0.8f));
else
return new ArrowButton ("d", 0.25f, Colours::white.withAlpha (0.8f));
}
ImageEffectFilter* LookAndFeel_V1::getSliderEffect()
{
return &scrollbarShadow;
}
int LookAndFeel_V1::getSliderThumbRadius (Slider&)
{
return 8;
}
//==============================================================================
void LookAndFeel_V1::drawCornerResizer (Graphics& g, int w, int h, bool isMouseOver, bool isMouseDragging)
{
g.setColour ((isMouseOver || isMouseDragging) ? Colours::lightgrey
: Colours::darkgrey);
const float lineThickness = jmin (w, h) * 0.1f;
for (float i = 0.0f; i < 1.0f; i += 0.3f)
{
g.drawLine (w * i,
h + 1.0f,
w + 1.0f,
h * i,
lineThickness);
}
}
//==============================================================================
Button* LookAndFeel_V1::createDocumentWindowButton (int buttonType)
{
Path shape;
if (buttonType == DocumentWindow::closeButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.0f, 1.0f, 1.0f), 0.35f);
shape.addLineSegment (Line<float> (1.0f, 0.0f, 0.0f, 1.0f), 0.35f);
ShapeButton* const b = new ShapeButton ("close",
Colour (0x7fff3333),
Colour (0xd7ff3333),
Colour (0xf7ff3333));
b->setShape (shape, true, true, true);
return b;
}
else if (buttonType == DocumentWindow::minimiseButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), 0.25f);
DrawableButton* b = new DrawableButton ("minimise", DrawableButton::ImageFitted);
DrawablePath dp;
dp.setPath (shape);
dp.setFill (Colours::black.withAlpha (0.3f));
b->setImages (&dp);
return b;
}
else if (buttonType == DocumentWindow::maximiseButton)
{
shape.addLineSegment (Line<float> (0.5f, 0.0f, 0.5f, 1.0f), 0.25f);
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), 0.25f);
DrawableButton* b = new DrawableButton ("maximise", DrawableButton::ImageFitted);
DrawablePath dp;
dp.setPath (shape);
dp.setFill (Colours::black.withAlpha (0.3f));
b->setImages (&dp);
return b;
}
jassertfalse;
return nullptr;
}
void LookAndFeel_V1::positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft)
{
titleBarY += titleBarH / 8;
titleBarH -= titleBarH / 4;
const int buttonW = titleBarH;
int x = positionTitleBarButtonsOnLeft ? titleBarX + 4
: titleBarX + titleBarW - buttonW - 4;
if (closeButton != nullptr)
{
closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
x += positionTitleBarButtonsOnLeft ? buttonW + buttonW / 5
: -(buttonW + buttonW / 5);
}
if (positionTitleBarButtonsOnLeft)
std::swap (minimiseButton, maximiseButton);
if (maximiseButton != nullptr)
{
maximiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
}
if (minimiseButton != nullptr)
minimiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
}

+ 101
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V1.h View File

@@ -0,0 +1,101 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_LOOKANDFEEL_V1_H_INCLUDED
#define JUCE_LOOKANDFEEL_V1_H_INCLUDED
//==============================================================================
/**
The original JUCE look-and-feel, as used back from 2002 to about 2007ish.
@see LookAndFeel, LookAndFeel_V2, LookAndFeel_V3
*/
class JUCE_API LookAndFeel_V1 : public LookAndFeel_V2
{
public:
LookAndFeel_V1();
~LookAndFeel_V1();
//==============================================================================
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) override;
void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
double progress, const String& textToShow) override;
//==============================================================================
void drawScrollbarButton (Graphics&, ScrollBar&, int width, int height,
int buttonDirection, bool isScrollbarVertical,
bool isMouseOverButton, bool isButtonDown) override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown) override;
ImageEffectFilter* getScrollbarEffect() override;
//==============================================================================
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
//==============================================================================
void drawPopupMenuBackground (Graphics&, int width, int height) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
//==============================================================================
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox&) override;
Font getComboBoxFont (ComboBox&) override;
//==============================================================================
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
int getSliderThumbRadius (Slider&) override;
Button* createSliderButton (bool isIncrement) override;
ImageEffectFilter* getSliderEffect() override;
//==============================================================================
void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) override;
Button* createDocumentWindowButton (int buttonType) override;
void positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton, Button* maximiseButton, Button* closeButton,
bool positionTitleBarButtonsOnLeft) override;
private:
DropShadowEffect scrollbarShadow;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V1)
};
#endif // JUCE_LOOKANDFEEL_H_INCLUDED

+ 2947
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.cpp
File diff suppressed because it is too large
View File


+ 347
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V2.h View File

@@ -0,0 +1,347 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_LOOKANDFEEL_V2_H_INCLUDED
#define JUCE_LOOKANDFEEL_V2_H_INCLUDED
//==============================================================================
/**
This LookAndFeel subclass implements the juce style from around 2008-12.
@see LookAndFeel, LookAndFeel_V1, LookAndFeel_V3
*/
class JUCE_API LookAndFeel_V2 : public LookAndFeel
{
public:
LookAndFeel_V2();
~LookAndFeel_V2();
//==============================================================================
void drawButtonBackground (Graphics&, Button& button, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
Font getTextButtonFont (TextButton&) override;
void drawButtonText (Graphics&, TextButton& button,
bool isMouseOverButton, bool isButtonDown) override;
void drawToggleButton (Graphics&, ToggleButton& button, bool isMouseOverButton, bool isButtonDown) override;
void changeToggleButtonWidthToFitText (ToggleButton&) override;
void drawTickBox (Graphics&, Component&,
float x, float y, float w, float h,
bool ticked, bool isEnabled, bool isMouseOverButton, bool isButtonDown) override;
void drawDrawableButton (Graphics&, DrawableButton&, bool isMouseOverButton, bool isButtonDown) override;
//==============================================================================
AlertWindow* createAlertWindow (const String& title, const String& message,
const String& button1,
const String& button2,
const String& button3,
AlertWindow::AlertIconType iconType,
int numButtons, Component* associatedComponent) override;
void drawAlertBox (Graphics&, AlertWindow&, const Rectangle<int>& textArea, TextLayout&) override;
int getAlertBoxWindowFlags() override;
int getAlertWindowButtonHeight() override;
Font getAlertWindowMessageFont() override;
Font getAlertWindowFont() override;
//==============================================================================
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
void drawSpinningWaitAnimation (Graphics&, const Colour& colour, int x, int y, int w, int h) override;
//==============================================================================
bool areScrollbarButtonsVisible() override;
void drawScrollbarButton (Graphics& g, ScrollBar&, int width, int height, int buttonDirection,
bool isScrollbarVertical, bool isMouseOverButton, bool isButtonDown) override;
void drawScrollbar (Graphics& g, ScrollBar&, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown) override;
ImageEffectFilter* getScrollbarEffect() override;
int getMinimumScrollbarThumbSize (ScrollBar&) override;
int getDefaultScrollbarWidth() override;
int getScrollbarButtonSize (ScrollBar& scrollbar) override;
//==============================================================================
Path getTickShape (float height) override;
Path getCrossShape (float height) override;
//==============================================================================
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver) override;
bool areLinesDrawnForTreeView (TreeView&) override;
int getTreeViewIndentSize (TreeView&) override;
//==============================================================================
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
CaretComponent* createCaretComponent (Component* keyFocusOwner) override;
//==============================================================================
const Drawable* getDefaultFolderImage() override;
const Drawable* getDefaultDocumentFileImage() override;
AttributedString createFileChooserHeaderText (const String& title, const String& instructions) override;
void drawFileBrowserRow (Graphics&, int width, int height,
const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex,
DirectoryContentsDisplayComponent&) override;
Button* createFileBrowserGoUpButton() override;
void layoutFileBrowserComponent (FileBrowserComponent&,
DirectoryContentsDisplayComponent*,
FilePreviewComponent*,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton) override;
//==============================================================================
void drawBubble (Graphics&, BubbleComponent&, const Point<float>& tip, const Rectangle<float>& body) override;
void drawLasso (Graphics&, Component&) override;
//==============================================================================
void drawPopupMenuBackground (Graphics&, int width, int height) override;
void drawPopupMenuItem (Graphics&, int width, int height,
bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu,
const String& text, const String& shortcutKeyText,
Image* image, const Colour* textColour) override;
Font getPopupMenuFont() override;
void drawPopupMenuUpDownArrow (Graphics&, int width, int height, bool isScrollUpArrow) override;
void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight,
int& idealWidth, int& idealHeight) override;
int getMenuWindowFlags() override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
int getMenuBarItemWidth (MenuBarComponent&, int itemIndex, const String& itemText) override;
Font getMenuBarFont (MenuBarComponent&, int itemIndex, const String& itemText) override;
int getDefaultMenuBarHeight() override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
//==============================================================================
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
Font getComboBoxFont (ComboBox&) override;
Label* createComboBoxTextBox (ComboBox&) override;
void positionComboBoxText (ComboBox&, Label&) override;
//==============================================================================
void drawLabel (Graphics&, Label&) override;
Font getLabelFont (Label&) override;
//==============================================================================
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawLinearSliderBackground (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawLinearSliderThumb (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawRotarySlider (Graphics&, int x, int y, int width, int height,
float sliderPosProportional, float rotaryStartAngle, float rotaryEndAngle,
Slider&) override;
int getSliderThumbRadius (Slider&) override;
Button* createSliderButton (bool isIncrement) override;
Label* createSliderTextBox (Slider&) override;
ImageEffectFilter* getSliderEffect() override;
Font getSliderPopupFont() override;
int getSliderPopupPlacement() override;
//==============================================================================
void getTooltipSize (const String& tipText, int& width, int& height) override;
void drawTooltip (Graphics&, const String& text, int width, int height) override;
//==============================================================================
Button* createFilenameComponentBrowseButton (const String& text) override;
void layoutFilenameComponent (FilenameComponent& filenameComp, ComboBox* filenameBox, Button* browseButton) override;
//==============================================================================
void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component& panel) override;
//==============================================================================
void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) override;
void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) override;
//==============================================================================
void fillResizableWindowBackground (Graphics&, int w, int h, const BorderSize<int>&, ResizableWindow&) override;
void drawResizableWindowBorder (Graphics&, int w, int h, const BorderSize<int>& border, ResizableWindow&) override;
//==============================================================================
void drawDocumentWindowTitleBar (DocumentWindow&, Graphics&, int w, int h,
int titleSpaceX, int titleSpaceW,
const Image* icon, bool drawTitleTextOnLeft) override;
Button* createDocumentWindowButton (int buttonType) override;
void positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft) override;
//==============================================================================
DropShadower* createDropShadowerForComponent (Component*) override;
//==============================================================================
void drawStretchableLayoutResizerBar (Graphics&, int w, int h, bool isVerticalBar,
bool isMouseOver, bool isMouseDragging) override;
//==============================================================================
void drawGroupComponentOutline (Graphics&, int w, int h, const String& text,
const Justification&, GroupComponent&) override;
//==============================================================================
int getTabButtonSpaceAroundImage() override;
int getTabButtonOverlap (int tabDepth) override;
int getTabButtonBestWidth (TabBarButton&, int tabDepth) override;
Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton&, Rectangle<int>& textArea, Component& extraComp) override;
void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
void drawTabButtonText (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
void drawTabbedButtonBarBackground (TabbedButtonBar&, Graphics&) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int w, int h) override;
void createTabButtonShape (TabBarButton&, Path& path, bool isMouseOver, bool isMouseDown) override;
void fillTabButtonShape (TabBarButton&, Graphics&, const Path& path, bool isMouseOver, bool isMouseDown) override;
Button* createTabBarExtrasButton() override;
//==============================================================================
void drawImageButton (Graphics&, Image*,
int imageX, int imageY, int imageW, int imageH,
const Colour& overlayColour, float imageOpacity, ImageButton&) override;
//==============================================================================
void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) override;
void drawTableHeaderColumn (Graphics&, const String& columnName, int columnId,
int width, int height, bool isMouseOver, bool isMouseDown,
int columnFlags) override;
//==============================================================================
void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) override;
Button* createToolbarMissingItemsButton (Toolbar&) override;
void paintToolbarButtonBackground (Graphics&, int width, int height,
bool isMouseOver, bool isMouseDown,
ToolbarItemComponent&) override;
void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
const String& text, ToolbarItemComponent&) override;
//==============================================================================
void drawPropertyPanelSectionHeader (Graphics&, const String& name, bool isOpen, int width, int height) override;
void drawPropertyComponentBackground (Graphics&, int width, int height, PropertyComponent&) override;
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
//==============================================================================
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path& path, Image& cachedImage) override;
//==============================================================================
void drawLevelMeter (Graphics&, int width, int height, float level) override;
void drawKeymapChangeButton (Graphics&, int width, int height, Button& button, const String& keyDescription) override;
//==============================================================================
/** Draws a 3D raised (or indented) bevel using two colours.
The bevel is drawn inside the given rectangle, and greater bevel thicknesses
extend inwards.
The top-left colour is used for the top- and left-hand edges of the
bevel; the bottom-right colour is used for the bottom- and right-hand
edges.
If useGradient is true, then the bevel fades out to make it look more curved
and less angular. If sharpEdgeOnOutside is true, the outside of the bevel is
sharp, and it fades towards the centre; if sharpEdgeOnOutside is false, then
the centre edges are sharp and it fades towards the outside.
*/
static void drawBevel (Graphics&,
int x, int y, int width, int height,
int bevelThickness,
const Colour& topLeftColour = Colours::white,
const Colour& bottomRightColour = Colours::black,
bool useGradient = true,
bool sharpEdgeOnOutside = true);
/** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */
static void drawGlassSphere (Graphics&, float x, float y, float diameter,
const Colour& colour, float outlineThickness) noexcept;
static void drawGlassPointer (Graphics&, float x, float y, float diameter,
const Colour& colour, float outlineThickness, int direction) noexcept;
/** Utility function to draw a shiny, glassy oblong (for text buttons). */
static void drawGlassLozenge (Graphics&,
float x, float y, float width, float height,
const Colour& colour, float outlineThickness, float cornerSize,
bool flatOnLeft, bool flatOnRight, bool flatOnTop, bool flatOnBottom) noexcept;
private:
//==============================================================================
ScopedPointer<Drawable> folderImage, documentImage;
void drawShinyButtonShape (Graphics&,
float x, float y, float w, float h, float maxCornerSize,
const Colour& baseColour, float strokeWidth,
bool flatOnLeft, bool flatOnRight, bool flatOnTop, bool flatOnBottom) noexcept;
class GlassWindowButton;
class SliderLabelComp;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V2)
};
#endif // JUCE_LOOKANDFEEL_H_INCLUDED

+ 361
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.cpp View File

@@ -0,0 +1,361 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
LookAndFeel_V3::LookAndFeel_V3()
{
setColour (TreeView::selectedItemBackgroundColourId, Colour (0x301111ee));
const Colour textButtonColour (0xffeeeeff);
setColour (TextButton::buttonColourId, textButtonColour);
setColour (ComboBox::buttonColourId, textButtonColour);
setColour (ScrollBar::thumbColourId, Colour::greyLevel (0.8f).contrasting().withAlpha (0.13f));
}
LookAndFeel_V3::~LookAndFeel_V3() {}
bool LookAndFeel_V3::areScrollbarButtonsVisible() { return false; }
void LookAndFeel_V3::drawStretchableLayoutResizerBar (Graphics& g, int /*w*/, int /*h*/, bool /*isVerticalBar*/,
bool isMouseOver, bool isMouseDragging)
{
if (isMouseOver || isMouseDragging)
g.fillAll (Colours::yellow.withAlpha (0.4f));
}
void LookAndFeel_V3::drawScrollbar (Graphics& g, ScrollBar& scrollbar, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown)
{
Path thumbPath;
if (thumbSize > 0)
{
const float thumbIndent = (isScrollbarVertical ? width : height) * 0.25f;
const float thumbIndentx2 = thumbIndent * 2.0f;
if (isScrollbarVertical)
thumbPath.addRoundedRectangle (x + thumbIndent, thumbStartPosition + thumbIndent,
width - thumbIndentx2, thumbSize - thumbIndentx2, (width - thumbIndentx2) * 0.5f);
else
thumbPath.addRoundedRectangle (thumbStartPosition + thumbIndent, y + thumbIndent,
thumbSize - thumbIndentx2, height - thumbIndentx2, (height - thumbIndentx2) * 0.5f);
}
Colour thumbCol (scrollbar.findColour (ScrollBar::thumbColourId, true));
if (isMouseOver || isMouseDown)
thumbCol = thumbCol.withMultipliedAlpha (2.0f);
g.setColour (thumbCol);
g.fillPath (thumbPath);
g.setColour (thumbCol.contrasting ((isMouseOver || isMouseDown) ? 0.2f : 0.1f));
g.strokePath (thumbPath, PathStrokeType (1.0f));
}
void LookAndFeel_V3::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int>& area,
bool isMouseOver, bool /*isMouseDown*/,
ConcertinaPanel&, Component& panel)
{
const Colour bkg (Colours::grey);
g.setGradientFill (ColourGradient (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), 0, (float) area.getY(),
Colours::darkgrey.withAlpha (0.2f), 0, (float) area.getBottom(), false));
g.fillAll();
g.setColour (bkg.contrasting().withAlpha (0.04f));
g.fillRect (area.withHeight (1));
g.fillRect (area.withTop (area.getBottom() - 1));
g.setColour (bkg.contrasting());
g.setFont (Font (area.getHeight() * 0.6f).boldened());
g.drawFittedText (panel.getName(), 4, 0, area.getWidth() - 6, area.getHeight(), Justification::centredLeft, 1);
}
static void drawButtonShape (Graphics& g, const Path& outline, Colour baseColour, float height)
{
const float mainBrightness = baseColour.getBrightness();
const float mainAlpha = baseColour.getFloatAlpha();
g.setGradientFill (ColourGradient (baseColour.brighter (0.2f), 0.0f, 0.0f,
baseColour.darker (0.25f), 0.0f, height, false));
g.fillPath (outline);
g.setColour (Colours::white.withAlpha (0.4f * mainAlpha * mainBrightness * mainBrightness));
g.strokePath (outline, PathStrokeType (1.0f), AffineTransform::translation (0.0f, 1.0f)
.scaled (1.0f, (height - 1.6f) / height));
g.setColour (Colours::black.withAlpha (0.4f * mainAlpha));
g.strokePath (outline, PathStrokeType (1.0f));
}
void LookAndFeel_V3::drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown)
{
Colour baseColour (backgroundColour.withMultipliedSaturation (button.hasKeyboardFocus (true) ? 1.3f : 0.9f)
.withMultipliedAlpha (button.isEnabled() ? 0.9f : 0.5f));
if (isButtonDown || isMouseOverButton)
baseColour = baseColour.contrasting (isButtonDown ? 0.2f : 0.1f);
const bool flatOnLeft = button.isConnectedOnLeft();
const bool flatOnRight = button.isConnectedOnRight();
const bool flatOnTop = button.isConnectedOnTop();
const bool flatOnBottom = button.isConnectedOnBottom();
const float width = button.getWidth() - 1.0f;
const float height = button.getHeight() - 1.0f;
const float cornerSize = 4.0f;
Path outline;
outline.addRoundedRectangle (0.5f, 0.5f, width, height, cornerSize, cornerSize,
! (flatOnLeft || flatOnTop),
! (flatOnRight || flatOnTop),
! (flatOnLeft || flatOnBottom),
! (flatOnRight || flatOnBottom));
drawButtonShape (g, outline, baseColour, height);
}
void LookAndFeel_V3::drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header)
{
Rectangle<int> r (header.getLocalBounds());
g.setColour (Colours::black.withAlpha (0.5f));
g.fillRect (r.removeFromBottom (1));
g.setColour (Colours::white.withAlpha (0.6f));
g.fillRect (r);
g.setColour (Colours::black.withAlpha (0.5f));
for (int i = header.getNumColumns (true); --i >= 0;)
g.fillRect (header.getColumnPosition (i).removeFromRight (1));
}
int LookAndFeel_V3::getTabButtonOverlap (int /*tabDepth*/) { return -1; }
int LookAndFeel_V3::getTabButtonSpaceAroundImage() { return 1; }
void LookAndFeel_V3::createTabTextLayout (const TabBarButton& button, float length, float depth,
Colour colour, TextLayout& textLayout)
{
Font font (depth * 0.5f);
font.setUnderline (button.hasKeyboardFocus (false));
AttributedString s;
s.setJustification (Justification::centred);
s.append (button.getButtonText().trim(), font, colour);
textLayout.createLayout (s, length);
}
void LookAndFeel_V3::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown)
{
const Rectangle<int> activeArea (button.getActiveArea());
const TabbedButtonBar::Orientation o = button.getTabbedButtonBar().getOrientation();
const Colour bkg (button.getTabBackgroundColour());
if (button.getToggleState())
{
g.setColour (bkg);
g.fillRect (activeArea);
}
else
{
Point<int> p1, p2;
switch (o)
{
case TabbedButtonBar::TabsAtBottom: p1 = activeArea.getBottomLeft(); p2 = activeArea.getTopLeft(); break;
case TabbedButtonBar::TabsAtTop: p1 = activeArea.getTopLeft(); p2 = activeArea.getBottomLeft(); break;
case TabbedButtonBar::TabsAtRight: p1 = activeArea.getTopRight(); p2 = activeArea.getTopLeft(); break;
case TabbedButtonBar::TabsAtLeft: p1 = activeArea.getTopLeft(); p2 = activeArea.getTopRight(); break;
default: jassertfalse; break;
}
g.setGradientFill (ColourGradient (bkg.brighter (0.2f), (float) p1.x, (float) p1.y,
bkg.darker (0.1f), (float) p2.x, (float) p2.y, false));
g.fillRect (activeArea);
}
g.setColour (bkg.contrasting (0.3f));
Rectangle<int> r (activeArea);
if (o != TabbedButtonBar::TabsAtBottom) g.fillRect (r.removeFromTop (1));
if (o != TabbedButtonBar::TabsAtTop) g.fillRect (r.removeFromBottom (1));
if (o != TabbedButtonBar::TabsAtRight) g.fillRect (r.removeFromLeft (1));
if (o != TabbedButtonBar::TabsAtLeft) g.fillRect (r.removeFromRight (1));
const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f;
const Colour col (bkg.contrasting().withMultipliedAlpha (alpha));
const Rectangle<float> area (button.getTextArea().toFloat());
float length = area.getWidth();
float depth = area.getHeight();
if (button.getTabbedButtonBar().isVertical())
std::swap (length, depth);
TextLayout textLayout;
createTabTextLayout (button, length, depth, col, textLayout);
AffineTransform t;
switch (o)
{
case TabbedButtonBar::TabsAtLeft: t = t.rotated (float_Pi * -0.5f).translated (area.getX(), area.getBottom()); break;
case TabbedButtonBar::TabsAtRight: t = t.rotated (float_Pi * 0.5f).translated (area.getRight(), area.getY()); break;
case TabbedButtonBar::TabsAtTop:
case TabbedButtonBar::TabsAtBottom: t = t.translated (area.getX(), area.getY()); break;
default: jassertfalse; break;
}
g.addTransform (t);
textLayout.draw (g, Rectangle<float> (length, depth));
}
void LookAndFeel_V3::drawTreeviewPlusMinusBox (Graphics& g, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver)
{
Path p;
p.addTriangle (0.0f, 0.0f, 1.0f, isOpen ? 0.0f : 0.5f, isOpen ? 0.5f : 0.0f, 1.0f);
g.setColour (backgroundColour.contrasting().withAlpha (isMouseOver ? 0.5f : 0.3f));
g.fillPath (p, p.getTransformToScaleToFit (area.reduced (2, area.getHeight() / 4), true));
}
bool LookAndFeel_V3::areLinesDrawnForTreeView (TreeView&)
{
return false;
}
int LookAndFeel_V3::getTreeViewIndentSize (TreeView&)
{
return 20;
}
void LookAndFeel_V3::drawComboBox (Graphics& g, int width, int height, const bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box)
{
g.fillAll (box.findColour (ComboBox::backgroundColourId));
const Colour buttonColour (box.findColour (ComboBox::buttonColourId));
if (box.isEnabled() && box.hasKeyboardFocus (false))
{
g.setColour (buttonColour);
g.drawRect (0, 0, width, height, 2);
}
else
{
g.setColour (box.findColour (ComboBox::outlineColourId));
g.drawRect (0, 0, width, height);
}
const float outlineThickness = box.isEnabled() ? (isButtonDown ? 1.2f : 0.5f) : 0.3f;
Path buttonShape;
buttonShape.addRectangle (buttonX + outlineThickness,
buttonY + outlineThickness,
buttonW - outlineThickness * 2.0f,
buttonH - outlineThickness * 2.0f);
drawButtonShape (g, buttonShape,
buttonColour.withMultipliedSaturation (box.hasKeyboardFocus (true) ? 1.3f : 0.9f)
.withMultipliedAlpha (box.isEnabled() ? 0.9f : 0.5f),
(float) height);
if (box.isEnabled())
{
const float arrowX = 0.3f;
const float arrowH = 0.2f;
Path p;
p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.45f - arrowH),
buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.45f,
buttonX + buttonW * arrowX, buttonY + buttonH * 0.45f);
p.addTriangle (buttonX + buttonW * 0.5f, buttonY + buttonH * (0.55f + arrowH),
buttonX + buttonW * (1.0f - arrowX), buttonY + buttonH * 0.55f,
buttonX + buttonW * arrowX, buttonY + buttonH * 0.55f);
g.setColour (box.findColour (ComboBox::arrowColourId));
g.fillPath (p);
}
}
void LookAndFeel_V3::drawPopupMenuBackground (Graphics& g, int width, int height)
{
g.fillAll (findColour (PopupMenu::backgroundColourId));
(void) width; (void) height;
#if ! JUCE_MAC
g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.6f));
g.drawRect (0, 0, width, height);
#endif
}
void LookAndFeel_V3::drawKeymapChangeButton (Graphics& g, int width, int height,
Button& button, const String& keyDescription)
{
const Colour textColour (button.findColour (0x100ad01 /*KeyMappingEditorComponent::textColourId*/, true));
if (keyDescription.isNotEmpty())
{
if (button.isEnabled())
{
g.setColour (textColour.withAlpha (button.isDown() ? 0.4f : (button.isOver() ? 0.2f : 0.1f)));
g.fillRoundedRectangle (button.getLocalBounds().toFloat(), 4.0f);
g.drawRoundedRectangle (button.getLocalBounds().toFloat(), 4.0f, 1.0f);
}
g.setColour (textColour);
g.setFont (height * 0.6f);
g.drawFittedText (keyDescription, 4, 0, width - 8, height, Justification::centred, 1);
}
else
{
const float thickness = 7.0f;
const float indent = 22.0f;
Path p;
p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
p.setUsingNonZeroWinding (false);
g.setColour (textColour.darker(0.1f).withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f)));
g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, width - 4.0f, height - 4.0f, true));
}
if (button.hasKeyboardFocus (false))
{
g.setColour (textColour.withAlpha (0.4f));
g.drawRect (0, 0, width, height);
}
}

+ 79
- 0
source/modules/juce_gui_basics/lookandfeel/juce_LookAndFeel_V3.h View File

@@ -0,0 +1,79 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2013 - Raw Material Software Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found 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.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_LOOKANDFEEL_V3_H_INCLUDED
#define JUCE_LOOKANDFEEL_V3_H_INCLUDED
//==============================================================================
/**
The latest JUCE look-and-feel style, as introduced in 2013.
@see LookAndFeel, LookAndFeel_V1, LookAndFeel_V2
*/
class JUCE_API LookAndFeel_V3 : public LookAndFeel_V2
{
public:
LookAndFeel_V3();
~LookAndFeel_V3();
//==============================================================================
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) override;
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver) override;
bool areLinesDrawnForTreeView (TreeView&) override;
int getTreeViewIndentSize (TreeView&) override;
void drawComboBox (Graphics& g, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) override;
void drawKeymapChangeButton (Graphics& g, int width, int height, Button& button, const String& keyDescription) override;
void drawPopupMenuBackground (Graphics& g, int width, int height) override;
int getTabButtonOverlap (int tabDepth) override;
int getTabButtonSpaceAroundImage() override;
void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
void drawStretchableLayoutResizerBar (Graphics&, int w, int h, bool isVerticalBar, bool isMouseOver, bool isMouseDragging) override;
bool areScrollbarButtonsVisible() override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height, bool isScrollbarVertical,
int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) override;
void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area, bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component&) override;
static void createTabTextLayout (const TabBarButton& button, float length, float depth, Colour colour, TextLayout&);
private:
Image backgroundTexture;
Colour backgroundTextureBaseColour;
};
#endif // JUCE_LOOKANDFEEL_H_INCLUDED

+ 56
- 0
source/modules/juce_gui_basics/menus/juce_PopupMenu.h View File

@@ -480,6 +480,62 @@ public:
void addCustomItem (int itemResultID, CustomComponent* customComponent,
const PopupMenu* optionalSubMenu = nullptr);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
menu drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
/** Fills the background of a popup menu component. */
virtual void drawPopupMenuBackground (Graphics&, int width, int height) = 0;
/** Draws one of the items in a popup menu. */
virtual void drawPopupMenuItem (Graphics&, int width, int height,
bool isSeparator, bool isActive, bool isHighlighted,
bool isTicked, bool hasSubMenu,
const String& text,
const String& shortcutKeyText,
Image* icon,
const Colour* textColour) = 0;
/** Returns the size and style of font to use in popup menus. */
virtual Font getPopupMenuFont() = 0;
virtual void drawPopupMenuUpDownArrow (Graphics&,
int width, int height,
bool isScrollUpArrow) = 0;
/** Finds the best size for an item in a popup menu. */
virtual void getIdealPopupMenuItemSize (const String& text,
bool isSeparator,
int standardMenuItemHeight,
int& idealWidth,
int& idealHeight) = 0;
virtual int getMenuWindowFlags() = 0;
virtual void drawMenuBarBackground (Graphics&, int width, int height,
bool isMouseOverBar,
MenuBarComponent&) = 0;
virtual int getDefaultMenuBarHeight() = 0;
virtual int getMenuBarItemWidth (MenuBarComponent&, int itemIndex, const String& itemText) = 0;
virtual Font getMenuBarFont (MenuBarComponent&, int itemIndex, const String& itemText) = 0;
virtual void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex,
const String& itemText,
bool isMouseOverItem,
bool isMenuOpen,
bool isMouseOverBar,
MenuBarComponent&) = 0;
};
private:
//==============================================================================
JUCE_PUBLIC_IN_DLL_BUILD (class Item)


+ 13
- 0
source/modules/juce_gui_basics/misc/juce_BubbleComponent.h View File

@@ -136,6 +136,19 @@ public:
outlineColourId = 0x1000af1 /**< The colour to use for an outline around the bubble. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawBubble (Graphics&, BubbleComponent&,
const Point<float>& positionOfTip,
const Rectangle<float>& body) = 0;
};
protected:
//==============================================================================
/** Subclasses should override this to return the size of the content they


+ 34
- 19
source/modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -315,26 +315,39 @@ public:
}
//==============================================================================
void handleMouseDownCallback (int index, float x, float y, int64 time)
void handleMouseDownCallback (int index, Point<float> pos, int64 time)
{
lastMousePos.setXY ((int) x, (int) y);
currentModifiers = currentModifiers.withoutMouseButtons();
handleMouseEvent (index, lastMousePos, currentModifiers, time);
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
handleMouseEvent (index, lastMousePos, currentModifiers, time);
lastMousePos = pos;
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons(), time);
if (isValidPeer (this))
handleMouseDragCallback (index, pos, time);
}
void handleMouseDragCallback (int index, float x, float y, int64 time)
void handleMouseDragCallback (int index, Point<float> pos, int64 time)
{
lastMousePos.setXY ((int) x, (int) y);
handleMouseEvent (index, lastMousePos, currentModifiers, time);
lastMousePos = pos;
jassert (index < 64);
touchesDown = (touchesDown | (1 << (index & 63)));
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons()
.withFlags (ModifierKeys::leftButtonModifier), time);
}
void handleMouseUpCallback (int index, float x, float y, int64 time)
void handleMouseUpCallback (int index, Point<float> pos, int64 time)
{
lastMousePos.setXY ((int) x, (int) y);
currentModifiers = currentModifiers.withoutMouseButtons();
handleMouseEvent (index, lastMousePos, currentModifiers, time);
lastMousePos = pos;
jassert (index < 64);
touchesDown = (touchesDown & ~(1 << (index & 63)));
if (touchesDown == 0)
currentModifiers = currentModifiers.withoutMouseButtons();
handleMouseEvent (index, pos.toInt(), currentModifiers.withoutMouseButtons(), time);
}
void handleKeyDownCallback (int k, int kc)
@@ -461,7 +474,8 @@ public:
//==============================================================================
static ModifierKeys currentModifiers;
static Point<int> lastMousePos;
static Point<float> lastMousePos;
static int64 touchesDown;
private:
//==============================================================================
@@ -526,7 +540,8 @@ private:
};
ModifierKeys AndroidComponentPeer::currentModifiers = 0;
Point<int> AndroidComponentPeer::lastMousePos;
Point<float> AndroidComponentPeer::lastMousePos;
int64 AndroidComponentPeer::touchesDown = 0;
//==============================================================================
#define JUCE_VIEW_CALLBACK(returnType, javaMethodName, params, juceMethodInvocation) \
@@ -537,9 +552,9 @@ Point<int> AndroidComponentPeer::lastMousePos;
}
JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas), handlePaintCallback (env, canvas))
JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, (float) x, (float) y, (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, (float) x, (float) y, (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, (float) x, (float) y, (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject view, jlong host), handleMovedOrResized())
JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject view, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus))
JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc))
@@ -582,7 +597,7 @@ bool MouseInputSource::SourceList::addSource()
Point<int> MouseInputSource::getCurrentRawMousePosition()
{
return AndroidComponentPeer::lastMousePos;
return AndroidComponentPeer::lastMousePos.toInt();
}
void MouseInputSource::setRawMousePosition (Point<int>)


+ 1
- 0
source/modules/juce_gui_basics/native/juce_ios_UIViewComponentPeer.mm View File

@@ -499,6 +499,7 @@ UIViewComponentPeer::UIViewComponentPeer (Component& comp, const int windowStyle
r.origin.y = [UIScreen mainScreen].bounds.size.height - (r.origin.y + r.size.height);
window = [[JuceUIWindow alloc] init];
window.hidden = true;
window.autoresizesSubviews = NO;
window.transform = CGAffineTransformIdentity;
window.frame = r;


+ 10
- 2
source/modules/juce_gui_basics/native/juce_mac_MouseCursor.mm View File

@@ -62,7 +62,6 @@ namespace MouseCursorHelpers
return CustomMouseCursorInfo (im, (int) (hx * im.getWidth()),
(int) (hy * im.getHeight())).create();
jassertfalse;
return nullptr;
}
}
@@ -95,7 +94,16 @@ void* MouseCursor::createStandardMouseCursor (MouseCursor::StandardCursorType ty
case LeftEdgeResizeCursor: c = [NSCursor resizeLeftCursor]; break;
case RightEdgeResizeCursor: c = [NSCursor resizeRightCursor]; break;
case CrosshairCursor: c = [NSCursor crosshairCursor]; break;
case CopyingCursor: return MouseCursorHelpers::fromWebKitFile ("copyCursor.png", 0, 0);
case CopyingCursor:
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
if (void* m = MouseCursorHelpers::fromWebKitFile ("copyCursor.png", 0, 0))
return m;
#endif
c = [NSCursor dragCopyCursor]; // added in 10.6
break;
}
case UpDownResizeCursor:
case TopEdgeResizeCursor:


+ 1
- 1
source/modules/juce_gui_basics/native/juce_mac_NSViewComponentPeer.mm View File

@@ -1686,7 +1686,7 @@ struct JuceNSWindowClass : public ObjCClass <NSWindow>
addMethod (@selector (canBecomeKeyWindow), canBecomeKeyWindow, "c@:");
addMethod (@selector (becomeKeyWindow), becomeKeyWindow, "v@:");
addMethod (@selector (windowShouldClose:), windowShouldClose, "c@:@");
addMethod (@selector (constrainFrameRect:toScreen:), constrainFrameRect, @encode (NSRect), "@:", @encode (NSRect*), "@");
addMethod (@selector (constrainFrameRect:toScreen:), constrainFrameRect, @encode (NSRect), "@:", @encode (NSRect), "@");
addMethod (@selector (windowWillResize:toSize:), windowWillResize, @encode (NSSize), "@:@", @encode (NSSize));
addMethod (@selector (zoom:), zoom, "v@:@");
addMethod (@selector (windowWillMove:), windowWillMove, "v@:@");


+ 23
- 16
source/modules/juce_gui_basics/native/juce_win32_Windowing.cpp View File

@@ -1807,13 +1807,10 @@ private:
{
const DWORD flags = inputInfo[i].dwFlags;
if ((flags & TOUCHEVENTF_PRIMARY) == 0 // primary events are handled by WM_LBUTTON etc
&& (flags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE | TOUCHEVENTF_UP)) != 0)
{
if (! handleTouchInput (inputInfo[i], (flags & TOUCHEVENTF_DOWN) != 0,
(flags & TOUCHEVENTF_UP) != 0))
if ((flags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_MOVE | TOUCHEVENTF_UP)) != 0)
if (! handleTouchInput (inputInfo[i], (flags & TOUCHEVENTF_PRIMARY) != 0,
(flags & TOUCHEVENTF_DOWN) != 0, (flags & TOUCHEVENTF_UP) != 0))
return 0; // abandon method if this window was deleted by the callback
}
}
}
@@ -1821,7 +1818,7 @@ private:
return 0;
}
bool handleTouchInput (const TOUCHINPUT& touch, const bool isDown, const bool isUp)
bool handleTouchInput (const TOUCHINPUT& touch, const bool isPrimary, const bool isDown, const bool isUp)
{
bool isCancel = false;
const int touchIndex = currentTouches.getIndexOfTouch (touch.dwID);
@@ -1835,10 +1832,13 @@ private:
currentModifiers = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
modsToSend = currentModifiers;
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
handleMouseEvent (touchIndex + 1, pos, modsToSend.withoutMouseButtons(), time);
if (! isValidPeer (this)) // (in case this component was deleted by the event)
return false;
if (! isPrimary)
{
// this forces a mouse-enter/up event, in case for some reason we didn't get a mouse-up before.
handleMouseEvent (touchIndex, pos, modsToSend.withoutMouseButtons(), time);
if (! isValidPeer (this)) // (in case this component was deleted by the event)
return false;
}
}
else if (isUp)
{
@@ -1848,6 +1848,10 @@ private:
if (! currentTouches.areAnyTouchesActive())
isCancel = true;
}
else
{
modsToSend = currentModifiers.withoutMouseButtons().withFlags (ModifierKeys::leftButtonModifier);
}
if (isCancel)
{
@@ -1855,13 +1859,16 @@ private:
currentModifiers = currentModifiers.withoutMouseButtons();
}
handleMouseEvent (touchIndex + 1, pos, modsToSend, time);
if (! isValidPeer (this)) // (in case this component was deleted by the event)
return false;
if (! isPrimary)
{
handleMouseEvent (touchIndex, pos, modsToSend, time);
if (! isValidPeer (this)) // (in case this component was deleted by the event)
return false;
}
if (isUp || isCancel)
if ((isUp || isCancel) && ! isPrimary)
{
handleMouseEvent (touchIndex + 1, Point<int> (-10, -10), currentModifiers, time);
handleMouseEvent (touchIndex, Point<int> (-10, -10), currentModifiers, time);
if (! isValidPeer (this))
return false;
}


+ 12
- 0
source/modules/juce_gui_basics/properties/juce_PropertyComponent.h View File

@@ -102,6 +102,18 @@ public:
/** By default, this just repaints the component. */
void enablementChanged() override;
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawPropertyPanelSectionHeader (Graphics&, const String& name, bool isOpen, int width, int height) = 0;
virtual void drawPropertyComponentBackground (Graphics&, int width, int height, PropertyComponent&) = 0;
virtual void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) = 0;
virtual Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) = 0;
};
protected:
/** Used by the PropertyPanel to determine how high this component needs to be.
A subclass can update this value in its constructor but shouldn't alter it later


+ 19
- 0
source/modules/juce_gui_basics/widgets/juce_ComboBox.h View File

@@ -333,6 +333,25 @@ public:
arrowColourId = 0x1000e00, /**< The colour for the arrow shape that pops up the menu */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
ComboBox functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) = 0;
virtual Font getComboBoxFont (ComboBox&) = 0;
virtual Label* createComboBoxTextBox (ComboBox&) = 0;
virtual void positionComboBoxText (ComboBox&, Label& labelToPosition) = 0;
};
//==============================================================================
/** @internal */
void labelTextChanged (Label*) override;


+ 12
- 0
source/modules/juce_gui_basics/widgets/juce_Label.h View File

@@ -249,6 +249,18 @@ public:
/** Returns the currently-visible text editor, or nullptr if none is open. */
TextEditor* getCurrentTextEditor() const noexcept;
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
label drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawLabel (Graphics&, Label&) = 0;
virtual Font getLabelFont (Label&) = 0;
};
protected:
//==============================================================================
/** Creates the TextEditor component that will be used when the user has clicked on the label.


+ 18
- 0
source/modules/juce_gui_basics/widgets/juce_ProgressBar.h View File

@@ -90,6 +90,24 @@ public:
classes will probably use variations on this colour. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
/** Draws a progress bar.
If the progress value is less than 0 or greater than 1.0, this should draw a spinning
bar that fills the whole space (i.e. to say that the app is still busy but the progress
isn't known). It can use the current time as a basis for playing an animation.
(Used by progress bars in AlertWindow).
*/
virtual void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
double progress, const String& textToShow) = 0;
};
protected:
//==============================================================================
/** @internal */


+ 51
- 0
source/modules/juce_gui_basics/widgets/juce_Slider.h View File

@@ -762,6 +762,57 @@ public:
textBoxOutlineColourId = 0x1001700 /**< The colour to use for a border around the text-editor box. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
slider drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
//==============================================================================
virtual void drawLinearSlider (Graphics&,
int x, int y, int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle,
Slider&) = 0;
virtual void drawLinearSliderBackground (Graphics&,
int x, int y, int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle style,
Slider&) = 0;
virtual void drawLinearSliderThumb (Graphics&,
int x, int y, int width, int height,
float sliderPos,
float minSliderPos,
float maxSliderPos,
const Slider::SliderStyle,
Slider&) = 0;
virtual int getSliderThumbRadius (Slider&) = 0;
virtual void drawRotarySlider (Graphics&,
int x, int y, int width, int height,
float sliderPosProportional,
float rotaryStartAngle,
float rotaryEndAngle,
Slider&) = 0;
virtual Button* createSliderButton (bool isIncrement) = 0;
virtual Label* createSliderTextBox (Slider&) = 0;
virtual ImageEffectFilter* getSliderEffect() = 0;
virtual Font getSliderPopupFont() = 0;
virtual int getSliderPopupPlacement() = 0;
};
protected:
//==============================================================================
/** @internal */


+ 13
- 0
source/modules/juce_gui_basics/widgets/juce_TableHeaderComponent.h View File

@@ -366,6 +366,19 @@ public:
*/
virtual void reactToMenuItem (int menuReturnId, int columnIdClicked);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) = 0;
virtual void drawTableHeaderColumn (Graphics&, const String& columnName, int columnId,
int width, int height,
bool isMouseOver, bool isMouseDown, int columnFlags) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 14
- 0
source/modules/juce_gui_basics/widgets/juce_TextEditor.h View File

@@ -580,6 +580,20 @@ public:
void setInputRestrictions (int maxTextLength,
const String& allowedCharacters = String::empty);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
TextEditor drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) = 0;
virtual void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) = 0;
virtual CaretComponent* createCaretComponent (Component* keyFocusOwner) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 18
- 0
source/modules/juce_gui_basics/widgets/juce_Toolbar.h View File

@@ -267,6 +267,24 @@ public:
bool restoreFromString (ToolbarItemFactory& factoryToUse,
const String& savedVersion);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) = 0;
virtual Button* createToolbarMissingItemsButton (Toolbar&) = 0;
virtual void paintToolbarButtonBackground (Graphics&, int width, int height,
bool isMouseOver, bool isMouseDown,
ToolbarItemComponent&) = 0;
virtual void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
const String& text, ToolbarItemComponent&) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 34
- 21
source/modules/juce_gui_basics/widgets/juce_TreeView.cpp View File

@@ -439,7 +439,7 @@ TreeView::TreeView (const String& name)
: Component (name),
viewport (new TreeViewport()),
rootItem (nullptr),
indentSize (24),
indentSize (-1),
defaultOpenness (false),
needsRecalculating (true),
rootItemVisible (true),
@@ -522,6 +522,12 @@ void TreeView::setIndentSize (const int newIndentSize)
}
}
int TreeView::getIndentSize() noexcept
{
return indentSize >= 0 ? indentSize
: getLookAndFeel().getTreeViewIndentSize (*this);
}
void TreeView::setDefaultOpenness (const bool isOpenByDefault)
{
if (defaultOpenness != isOpenByDefault)
@@ -860,7 +866,7 @@ void TreeView::recalculateIfNeeded()
//==============================================================================
struct TreeView::InsertPoint
{
InsertPoint (const TreeView& view, const StringArray& files,
InsertPoint (TreeView& view, const StringArray& files,
const DragAndDropTarget::SourceDetails& dragSourceDetails)
: pos (dragSourceDetails.localPosition),
item (view.getItemAt (dragSourceDetails.localPosition.y)),
@@ -1125,7 +1131,8 @@ TreeViewItem::TreeViewItem()
totalWidth (0),
selected (false),
redrawNeeded (true),
drawLinesInside (true),
drawLinesInside (false),
drawLinesSet (false),
drawsInLeftMargin (false),
openness (opennessDefault)
{
@@ -1317,10 +1324,10 @@ void TreeViewItem::paintItem (Graphics&, int, int)
{
}
void TreeViewItem::paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver)
void TreeViewItem::paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour backgroundColour, bool isMouseOver)
{
ownerView->getLookAndFeel()
.drawTreeviewPlusMinusBox (g, 0, 0, width, height, ! isOpen(), isMouseOver);
getOwnerView()->getLookAndFeel()
.drawTreeviewPlusMinusBox (g, area, backgroundColour, isOpen(), isMouseOver);
}
void TreeViewItem::paintHorizontalConnectingLine (Graphics& g, const Line<float>& line)
@@ -1495,6 +1502,12 @@ namespace TreeViewHelpers
}
}
bool TreeViewItem::areLinesDrawn() const
{
return drawLinesSet ? drawLinesInside
: (ownerView != nullptr && ownerView->getLookAndFeel().areLinesDrawnForTreeView (*ownerView));
}
void TreeViewItem::paintRecursively (Graphics& g, int width)
{
jassert (ownerView != nullptr);
@@ -1510,7 +1523,12 @@ void TreeViewItem::paintRecursively (Graphics& g, int width)
if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0,
drawsInLeftMargin ? itemW + indent : itemW, itemHeight))
{
if (isSelected())
g.fillAll (ownerView->findColour (TreeView::selectedItemBackgroundColourId));
paintItem (g, itemW, itemHeight);
}
}
const float halfH = itemHeight * 0.5f;
@@ -1521,11 +1539,12 @@ void TreeViewItem::paintRecursively (Graphics& g, int width)
{
float x = (depth + 0.5f) * indentWidth;
if (parentItem != nullptr && parentItem->drawLinesInside)
const bool parentLinesDrawn = parentItem != nullptr && parentItem->areLinesDrawn();
if (parentLinesDrawn)
paintVerticalConnectingLine (g, Line<float> (x, 0, x, isLastOfSiblings() ? halfH : (float) itemHeight));
if ((parentItem != nullptr && parentItem->drawLinesInside)
|| (parentItem == nullptr && drawLinesInside))
if (parentLinesDrawn || (parentItem == nullptr && areLinesDrawn()))
paintHorizontalConnectingLine (g, Line<float> (x, halfH, x + indentWidth / 2, halfH));
{
@@ -1536,8 +1555,7 @@ void TreeViewItem::paintRecursively (Graphics& g, int width)
{
x -= (float) indentWidth;
if ((p->parentItem == nullptr || p->parentItem->drawLinesInside)
&& ! p->isLastOfSiblings())
if ((p->parentItem == nullptr || p->parentItem->areLinesDrawn()) && ! p->isLastOfSiblings())
p->paintVerticalConnectingLine (g, Line<float> (x, 0, x, (float) itemHeight));
p = p->parentItem;
@@ -1545,15 +1563,9 @@ void TreeViewItem::paintRecursively (Graphics& g, int width)
}
if (mightContainSubItems())
{
Graphics::ScopedSaveState ss (g);
g.setOrigin (depth * indentWidth, 0);
g.reduceClipRegion (0, 0, indentWidth, itemHeight);
paintOpenCloseButton (g, indentWidth, itemHeight,
paintOpenCloseButton (g, Rectangle<float> ((float) (depth * indentWidth), 0, (float) indentWidth, (float) itemHeight),
Colours::white,
ownerView->viewport->getContentComp()->isMouseOverButton (this));
}
}
if (isOpen())
@@ -1731,6 +1743,7 @@ int TreeViewItem::getRowNumberInTree() const noexcept
void TreeViewItem::setLinesDrawnForSubItems (const bool drawLines) noexcept
{
drawLinesInside = drawLines;
drawLinesSet = true;
}
TreeViewItem* TreeViewItem::getNextVisibleItem (const bool recurse) const noexcept
@@ -1840,8 +1853,8 @@ XmlElement* TreeViewItem::getOpennessState (const bool canReturnNull) const
e = new XmlElement ("OPEN");
for (int i = 0; i < subItems.size(); ++i)
e->addChildElement (subItems.getUnchecked(i)->getOpennessState (true));
for (int i = subItems.size(); --i >= 0;)
e->prependChildElement (subItems.getUnchecked(i)->getOpennessState (true));
}
else
{


+ 50
- 10
source/modules/juce_gui_basics/widgets/juce_TreeView.h View File

@@ -83,6 +83,20 @@ public:
*/
void addSubItem (TreeViewItem* newItem, int insertPosition = -1);
/** Adds a sub-item with a sort-comparator, assuming that the existing items are already sorted.
@param comparator the comparator object for sorting - see sortSubItems() for details about
the methods this class must provide.
@param newItem the object to add to the item's sub-item list. Once added, these can be
found using getSubItem(). When the items are later removed with
removeSubItem() (or when this item is deleted), they will be deleted.
*/
template <class ElementComparator>
void addSubItemSorted (ElementComparator& comparator, TreeViewItem* newItem)
{
addSubItem (newItem, findInsertIndexInSortedArray (comparator, subItems.begin(), newItem, 0, subItems.size()));
}
/** Removes one of the sub-items.
@param index the item to remove
@@ -178,7 +192,7 @@ public:
bool areAllParentsOpen() const noexcept;
/** Changes whether lines are drawn to connect any sub-items to this item.
By default, line-drawing is turned on.
By default, line-drawing is turned on according to LookAndFeel::areLinesDrawnForTreeView().
*/
void setLinesDrawnForSubItems (bool shouldDrawLines) noexcept;
@@ -299,11 +313,14 @@ public:
/** Draws the item's open/close button.
If you don't implement this method, the default behaviour is to
call LookAndFeel::drawTreeviewPlusMinusBox(), but you can override
it for custom effects.
If you don't implement this method, the default behaviour is to call
LookAndFeel::drawTreeviewPlusMinusBox(), but you can override it for custom
effects. You may want to override it and call the base-class implementation
with a different backgroundColour parameter, if your implementation has a
background colour other than the default (white).
*/
virtual void paintOpenCloseButton (Graphics&, int width, int height, bool isMouseOver);
virtual void paintOpenCloseButton (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isMouseOver);
/** Draws the line that connects this item to the vertical line extending below its parent. */
virtual void paintHorizontalConnectingLine (Graphics&, const Line<float>& line);
@@ -519,12 +536,13 @@ private:
//==============================================================================
TreeView* ownerView;
TreeViewItem* parentItem;
OwnedArray <TreeViewItem> subItems;
OwnedArray<TreeViewItem> subItems;
int y, itemHeight, totalHeight, itemWidth, totalWidth;
int uid;
bool selected : 1;
bool redrawNeeded : 1;
bool drawLinesInside : 1;
bool drawLinesSet : 1;
bool drawsInLeftMargin : 1;
unsigned int openness : 2;
@@ -549,6 +567,7 @@ private:
XmlElement* getOpennessState (bool canReturnNull) const;
bool removeSubItemFromList (int index, bool deleteItem);
void removeAllSubItemsFromList();
bool areLinesDrawn() const;
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// The parameters for these methods have changed - please update your code!
@@ -721,7 +740,7 @@ public:
/** Returns the number of pixels by which each nested level of the tree is indented.
@see setIndentSize
*/
int getIndentSize() const noexcept { return indentSize; }
int getIndentSize() noexcept;
/** Changes the distance by which each nested level of the tree is indented.
@see getIndentSize
@@ -779,9 +798,25 @@ public:
*/
enum ColourIds
{
backgroundColourId = 0x1000500, /**< A background colour to fill the component with. */
linesColourId = 0x1000501, /**< The colour to draw the lines with.*/
dragAndDropIndicatorColourId = 0x1000502 /**< The colour to use for the drag-and-drop target position indicator. */
backgroundColourId = 0x1000500, /**< A background colour to fill the component with. */
linesColourId = 0x1000501, /**< The colour to draw the lines with.*/
dragAndDropIndicatorColourId = 0x1000502, /**< The colour to use for the drag-and-drop target position indicator. */
selectedItemBackgroundColourId = 0x1000503 /**< The colour to use to fill the background of any selected items. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
treeview drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isItemOpen, bool isMouseOver) = 0;
virtual bool areLinesDrawnForTreeView (TreeView&) = 0;
virtual int getTreeViewIndentSize (TreeView&) = 0;
};
//==============================================================================
@@ -849,6 +884,11 @@ private:
void moveIntoSelectedItem();
void moveByPages (int numPages);
#if JUCE_CATCH_DEPRECATED_CODE_MISUSE
// this method has been deprecated - see the new version..
virtual int paintOpenCloseButton (Graphics&, int, int, bool) { return 0; }
#endif
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeView)
};


+ 26
- 0
source/modules/juce_gui_basics/windows/juce_AlertWindow.h View File

@@ -417,6 +417,32 @@ public:
outlineColourId = 0x1001820 /**< An optional colour to use to draw a border around the window. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
alert-window drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual AlertWindow* createAlertWindow (const String& title, const String& message,
const String& button1,
const String& button2,
const String& button3,
AlertWindow::AlertIconType iconType,
int numButtons,
Component* associatedComponent) = 0;
virtual void drawAlertBox (Graphics&, AlertWindow&, const Rectangle<int>& textArea, TextLayout&) = 0;
virtual int getAlertBoxWindowFlags() = 0;
virtual int getAlertWindowButtonHeight() = 0;
virtual Font getAlertWindowMessageFont() = 0;
virtual Font getAlertWindowFont() = 0;
};
protected:
//==============================================================================
/** @internal */


+ 12
- 4
source/modules/juce_gui_basics/windows/juce_CallOutBox.cpp View File

@@ -48,8 +48,11 @@ CallOutBox::~CallOutBox()
{
}
enum { callOutBoxDismissCommandId = 0x4f83a04b };
//==============================================================================
class CallOutBoxCallback : public ModalComponentManager::Callback
class CallOutBoxCallback : public ModalComponentManager::Callback,
private Timer
{
public:
CallOutBoxCallback (Component* c, const Rectangle<int>& area, Component* parent)
@@ -57,9 +60,16 @@ public:
{
callout.setVisible (true);
callout.enterModalState (true, this);
startTimer (200);
}
void modalStateFinished (int) {}
void modalStateFinished (int) override {}
void timerCallback() override
{
if (! Process::isForegroundProcess())
callout.postCommandMessage (callOutBoxDismissCommandId);
}
ScopedPointer<Component> content;
CallOutBox callout;
@@ -110,8 +120,6 @@ bool CallOutBox::hitTest (int x, int y)
return outline.contains ((float) x, (float) y);
}
enum { callOutBoxDismissCommandId = 0x4f83a04b };
void CallOutBox::inputAttemptWhenModal()
{
const Point<int> mousePos (getMouseXYRelative() + getBounds().getPosition());


+ 9
- 0
source/modules/juce_gui_basics/windows/juce_CallOutBox.h View File

@@ -118,6 +118,15 @@ public:
const Rectangle<int>& areaToPointTo,
Component* parentComponent);
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image& cachedImage) = 0;
};
//==============================================================================
/** @internal */
void paint (Graphics&) override;


+ 0
- 4
source/modules/juce_gui_basics/windows/juce_ComponentPeer.cpp View File

@@ -298,15 +298,11 @@ void ComponentPeer::handleMovedOrResized()
Rectangle<int> newBounds (Component::ComponentHelpers::rawPeerPositionToLocal (component, getBounds()));
Rectangle<int> oldBounds (component.getBounds());
// oldBounds = Component::ComponentHelpers::localPositionToRawPeerPos (component, oldBounds);
const bool wasMoved = (oldBounds.getPosition() != newBounds.getPosition());
const bool wasResized = (oldBounds.getWidth() != newBounds.getWidth() || oldBounds.getHeight() != newBounds.getHeight());
if (wasMoved || wasResized)
{
// newBounds = Component::ComponentHelpers::rawPeerPositionToLocal (component, newBounds);
component.bounds = newBounds;
if (wasResized)


+ 24
- 0
source/modules/juce_gui_basics/windows/juce_DocumentWindow.h View File

@@ -223,6 +223,30 @@ public:
and feel class how this is used. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
window drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void drawDocumentWindowTitleBar (DocumentWindow&,
Graphics&, int w, int h,
int titleSpaceX, int titleSpaceW,
const Image* icon,
bool drawTitleTextOnLeft) = 0;
virtual Button* createDocumentWindowButton (int buttonType) = 0;
virtual void positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft) = 0;
};
//==============================================================================
#ifndef DOXYGEN
/** @internal */


+ 16
- 1
source/modules/juce_gui_basics/windows/juce_ResizableWindow.h View File

@@ -306,8 +306,23 @@ public:
bool resizeToFit = false));
using TopLevelWindow::addToDesktop;
protected:
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
window drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
//==============================================================================
virtual void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) = 0;
virtual void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) = 0;
virtual void fillResizableWindowBackground (Graphics&, int w, int h, const BorderSize<int>&, ResizableWindow&) = 0;
virtual void drawResizableWindowBorder (Graphics&, int w, int h, const BorderSize<int>& border, ResizableWindow&) = 0;
};
protected:
/** @internal */
void paint (Graphics&) override;
/** (if overriding this, make sure you call ResizableWindow::moved() in your subclass) */


+ 11
- 0
source/modules/juce_gui_basics/windows/juce_TooltipWindow.h View File

@@ -96,6 +96,17 @@ public:
outlineColourId = 0x1001c10 /**< The colour to use to draw an outline around the tooltip. */
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes to provide
window drawing functionality.
*/
struct JUCE_API LookAndFeelMethods
{
virtual ~LookAndFeelMethods() {}
virtual void getTooltipSize (const String& tipText, int& width, int& height) = 0;
virtual void drawTooltip (Graphics&, const String& text, int width, int height) = 0;
};
private:
//==============================================================================


Loading…
Cancel
Save