diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile index 3c738cbedc..125baeda99 100644 --- a/Builds/Linux/Makefile +++ b/Builds/Linux/Makefile @@ -354,1487 +354,1487 @@ clean: $(OBJDIR)/juce_Application.o: ../../src/application/juce_Application.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Application.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ApplicationCommandInfo.o: ../../src/application/juce_ApplicationCommandInfo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ApplicationCommandInfo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ApplicationCommandManager.o: ../../src/application/juce_ApplicationCommandManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ApplicationCommandManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ApplicationCommandTarget.o: ../../src/application/juce_ApplicationCommandTarget.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ApplicationCommandTarget.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ApplicationProperties.o: ../../src/application/juce_ApplicationProperties.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ApplicationProperties.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AiffAudioFormat.o: ../../src/audio/audio_file_formats/juce_AiffAudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AiffAudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioFormat.o: ../../src/audio/audio_file_formats/juce_AudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioFormatManager.o: ../../src/audio/audio_file_formats/juce_AudioFormatManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioFormatManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioSubsectionReader.o: ../../src/audio/audio_file_formats/juce_AudioSubsectionReader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioSubsectionReader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioThumbnail.o: ../../src/audio/audio_file_formats/juce_AudioThumbnail.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioThumbnail.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioThumbnailCache.o: ../../src/audio/audio_file_formats/juce_AudioThumbnailCache.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioThumbnailCache.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FlacAudioFormat.o: ../../src/audio/audio_file_formats/juce_FlacAudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FlacAudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_OggVorbisAudioFormat.o: ../../src/audio/audio_file_formats/juce_OggVorbisAudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_OggVorbisAudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_QuickTimeAudioFormat.o: ../../src/audio/audio_file_formats/juce_QuickTimeAudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_QuickTimeAudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_WavAudioFormat.o: ../../src/audio/audio_file_formats/juce_WavAudioFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_WavAudioFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioFormatReaderSource.o: ../../src/audio/audio_sources/juce_AudioFormatReaderSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioFormatReaderSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioSourcePlayer.o: ../../src/audio/audio_sources/juce_AudioSourcePlayer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioSourcePlayer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioTransportSource.o: ../../src/audio/audio_sources/juce_AudioTransportSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioTransportSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BufferingAudioSource.o: ../../src/audio/audio_sources/juce_BufferingAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BufferingAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ChannelRemappingAudioSource.o: ../../src/audio/audio_sources/juce_ChannelRemappingAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ChannelRemappingAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_IIRFilterAudioSource.o: ../../src/audio/audio_sources/juce_IIRFilterAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_IIRFilterAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MixerAudioSource.o: ../../src/audio/audio_sources/juce_MixerAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MixerAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ResamplingAudioSource.o: ../../src/audio/audio_sources/juce_ResamplingAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ResamplingAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ToneGeneratorAudioSource.o: ../../src/audio/audio_sources/juce_ToneGeneratorAudioSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ToneGeneratorAudioSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioDeviceManager.o: ../../src/audio/devices/juce_AudioDeviceManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioDeviceManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioIODevice.o: ../../src/audio/devices/juce_AudioIODevice.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioIODevice.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioIODeviceType.o: ../../src/audio/devices/juce_AudioIODeviceType.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioIODeviceType.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiOutput.o: ../../src/audio/devices/juce_MidiOutput.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiOutput.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioDataConverters.o: ../../src/audio/dsp/juce_AudioDataConverters.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioDataConverters.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioSampleBuffer.o: ../../src/audio/dsp/juce_AudioSampleBuffer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioSampleBuffer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_IIRFilter.o: ../../src/audio/dsp/juce_IIRFilter.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_IIRFilter.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiBuffer.o: ../../src/audio/midi/juce_MidiBuffer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiBuffer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiFile.o: ../../src/audio/midi/juce_MidiFile.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiFile.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiKeyboardState.o: ../../src/audio/midi/juce_MidiKeyboardState.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiKeyboardState.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiMessage.o: ../../src/audio/midi/juce_MidiMessage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiMessage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiMessageCollector.o: ../../src/audio/midi/juce_MidiMessageCollector.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiMessageCollector.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiMessageSequence.o: ../../src/audio/midi/juce_MidiMessageSequence.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiMessageSequence.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_VSTPluginFormat.o: ../../src/audio/plugins/formats/juce_VSTPluginFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_VSTPluginFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioPluginFormat.o: ../../src/audio/plugins/juce_AudioPluginFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioPluginFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioPluginFormatManager.o: ../../src/audio/plugins/juce_AudioPluginFormatManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioPluginFormatManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioPluginInstance.o: ../../src/audio/plugins/juce_AudioPluginInstance.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioPluginInstance.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KnownPluginList.o: ../../src/audio/plugins/juce_KnownPluginList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KnownPluginList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PluginDescription.o: ../../src/audio/plugins/juce_PluginDescription.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PluginDescription.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PluginDirectoryScanner.o: ../../src/audio/plugins/juce_PluginDirectoryScanner.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PluginDirectoryScanner.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PluginListComponent.o: ../../src/audio/plugins/juce_PluginListComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PluginListComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioProcessor.o: ../../src/audio/processors/juce_AudioProcessor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioProcessor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioProcessorEditor.o: ../../src/audio/processors/juce_AudioProcessorEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioProcessorEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioProcessorGraph.o: ../../src/audio/processors/juce_AudioProcessorGraph.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioProcessorGraph.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioProcessorPlayer.o: ../../src/audio/processors/juce_AudioProcessorPlayer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioProcessorPlayer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GenericAudioProcessorEditor.o: ../../src/audio/processors/juce_GenericAudioProcessorEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GenericAudioProcessorEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Sampler.o: ../../src/audio/synthesisers/juce_Sampler.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Sampler.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Synthesiser.o: ../../src/audio/synthesisers/juce_Synthesiser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Synthesiser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BigInteger.o: ../../src/containers/juce_BigInteger.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BigInteger.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DynamicObject.o: ../../src/containers/juce_DynamicObject.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DynamicObject.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Identifier.o: ../../src/containers/juce_Identifier.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Identifier.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MemoryBlock.o: ../../src/containers/juce_MemoryBlock.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MemoryBlock.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_NamedValueSet.o: ../../src/containers/juce_NamedValueSet.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_NamedValueSet.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PropertySet.o: ../../src/containers/juce_PropertySet.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PropertySet.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Value.o: ../../src/containers/juce_Value.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Value.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ValueTree.o: ../../src/containers/juce_ValueTree.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ValueTree.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Variant.o: ../../src/containers/juce_Variant.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Variant.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileLogger.o: ../../src/core/juce_FileLogger.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileLogger.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Logger.o: ../../src/core/juce_Logger.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Logger.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PerformanceCounter.o: ../../src/core/juce_PerformanceCounter.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PerformanceCounter.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Random.o: ../../src/core/juce_Random.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Random.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RelativeTime.o: ../../src/core/juce_RelativeTime.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RelativeTime.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SystemStats.o: ../../src/core/juce_SystemStats.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SystemStats.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Time.o: ../../src/core/juce_Time.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Time.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Uuid.o: ../../src/core/juce_Uuid.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Uuid.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BlowFish.o: ../../src/cryptography/juce_BlowFish.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BlowFish.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MD5.o: ../../src/cryptography/juce_MD5.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MD5.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Primes.o: ../../src/cryptography/juce_Primes.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Primes.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RSAKey.o: ../../src/cryptography/juce_RSAKey.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RSAKey.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ActionBroadcaster.o: ../../src/events/juce_ActionBroadcaster.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ActionBroadcaster.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ActionListenerList.o: ../../src/events/juce_ActionListenerList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ActionListenerList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AsyncUpdater.o: ../../src/events/juce_AsyncUpdater.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AsyncUpdater.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ChangeBroadcaster.o: ../../src/events/juce_ChangeBroadcaster.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ChangeBroadcaster.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ChangeListenerList.o: ../../src/events/juce_ChangeListenerList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ChangeListenerList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_InterprocessConnection.o: ../../src/events/juce_InterprocessConnection.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_InterprocessConnection.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_InterprocessConnectionServer.o: ../../src/events/juce_InterprocessConnectionServer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_InterprocessConnectionServer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Message.o: ../../src/events/juce_Message.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Message.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MessageListener.o: ../../src/events/juce_MessageListener.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MessageListener.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MessageManager.o: ../../src/events/juce_MessageManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MessageManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MultiTimer.o: ../../src/events/juce_MultiTimer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MultiTimer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Timer.o: ../../src/events/juce_Timer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Timer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Component.o: ../../src/gui/components/juce_Component.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Component.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentListener.o: ../../src/gui/components/juce_ComponentListener.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentListener.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Desktop.o: ../../src/gui/components/juce_Desktop.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Desktop.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ArrowButton.o: ../../src/gui/components/buttons/juce_ArrowButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ArrowButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Button.o: ../../src/gui/components/buttons/juce_Button.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Button.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DrawableButton.o: ../../src/gui/components/buttons/juce_DrawableButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DrawableButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_HyperlinkButton.o: ../../src/gui/components/buttons/juce_HyperlinkButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_HyperlinkButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ImageButton.o: ../../src/gui/components/buttons/juce_ImageButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ImageButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ShapeButton.o: ../../src/gui/components/buttons/juce_ShapeButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ShapeButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TextButton.o: ../../src/gui/components/buttons/juce_TextButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TextButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ToggleButton.o: ../../src/gui/components/buttons/juce_ToggleButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ToggleButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ToolbarButton.o: ../../src/gui/components/buttons/juce_ToolbarButton.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ToolbarButton.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_CodeDocument.o: ../../src/gui/components/code_editor/juce_CodeDocument.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_CodeDocument.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_CodeEditorComponent.o: ../../src/gui/components/code_editor/juce_CodeEditorComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_CodeEditorComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_CPlusPlusCodeTokeniser.o: ../../src/gui/components/code_editor/juce_CPlusPlusCodeTokeniser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_CPlusPlusCodeTokeniser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComboBox.o: ../../src/gui/components/controls/juce_ComboBox.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComboBox.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Label.o: ../../src/gui/components/controls/juce_Label.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Label.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ListBox.o: ../../src/gui/components/controls/juce_ListBox.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ListBox.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ProgressBar.o: ../../src/gui/components/controls/juce_ProgressBar.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ProgressBar.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Slider.o: ../../src/gui/components/controls/juce_Slider.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Slider.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TableHeaderComponent.o: ../../src/gui/components/controls/juce_TableHeaderComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TableHeaderComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TableListBox.o: ../../src/gui/components/controls/juce_TableListBox.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TableListBox.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TextEditor.o: ../../src/gui/components/controls/juce_TextEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TextEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Toolbar.o: ../../src/gui/components/controls/juce_Toolbar.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Toolbar.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ToolbarItemComponent.o: ../../src/gui/components/controls/juce_ToolbarItemComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ToolbarItemComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ToolbarItemPalette.o: ../../src/gui/components/controls/juce_ToolbarItemPalette.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ToolbarItemPalette.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TreeView.o: ../../src/gui/components/controls/juce_TreeView.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TreeView.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DirectoryContentsDisplayComponent.o: ../../src/gui/components/filebrowser/juce_DirectoryContentsDisplayComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DirectoryContentsDisplayComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DirectoryContentsList.o: ../../src/gui/components/filebrowser/juce_DirectoryContentsList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DirectoryContentsList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileBrowserComponent.o: ../../src/gui/components/filebrowser/juce_FileBrowserComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileBrowserComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileChooser.o: ../../src/gui/components/filebrowser/juce_FileChooser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileChooser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileChooserDialogBox.o: ../../src/gui/components/filebrowser/juce_FileChooserDialogBox.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileChooserDialogBox.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileFilter.o: ../../src/gui/components/filebrowser/juce_FileFilter.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileFilter.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileListComponent.o: ../../src/gui/components/filebrowser/juce_FileListComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileListComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FilenameComponent.o: ../../src/gui/components/filebrowser/juce_FilenameComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FilenameComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileSearchPathListComponent.o: ../../src/gui/components/filebrowser/juce_FileSearchPathListComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileSearchPathListComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileTreeComponent.o: ../../src/gui/components/filebrowser/juce_FileTreeComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileTreeComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ImagePreviewComponent.o: ../../src/gui/components/filebrowser/juce_ImagePreviewComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ImagePreviewComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_WildcardFileFilter.o: ../../src/gui/components/filebrowser/juce_WildcardFileFilter.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_WildcardFileFilter.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KeyboardFocusTraverser.o: ../../src/gui/components/keyboard/juce_KeyboardFocusTraverser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KeyboardFocusTraverser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KeyListener.o: ../../src/gui/components/keyboard/juce_KeyListener.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KeyListener.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KeyMappingEditorComponent.o: ../../src/gui/components/keyboard/juce_KeyMappingEditorComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KeyMappingEditorComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KeyPress.o: ../../src/gui/components/keyboard/juce_KeyPress.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KeyPress.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_KeyPressMappingSet.o: ../../src/gui/components/keyboard/juce_KeyPressMappingSet.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_KeyPressMappingSet.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ModifierKeys.o: ../../src/gui/components/keyboard/juce_ModifierKeys.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ModifierKeys.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentAnimator.o: ../../src/gui/components/layout/juce_ComponentAnimator.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentAnimator.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentBoundsConstrainer.o: ../../src/gui/components/layout/juce_ComponentBoundsConstrainer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentBoundsConstrainer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentMovementWatcher.o: ../../src/gui/components/layout/juce_ComponentMovementWatcher.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentMovementWatcher.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GroupComponent.o: ../../src/gui/components/layout/juce_GroupComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GroupComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MultiDocumentPanel.o: ../../src/gui/components/layout/juce_MultiDocumentPanel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MultiDocumentPanel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ResizableBorderComponent.o: ../../src/gui/components/layout/juce_ResizableBorderComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ResizableBorderComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ResizableCornerComponent.o: ../../src/gui/components/layout/juce_ResizableCornerComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ResizableCornerComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ScrollBar.o: ../../src/gui/components/layout/juce_ScrollBar.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ScrollBar.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StretchableLayoutManager.o: ../../src/gui/components/layout/juce_StretchableLayoutManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StretchableLayoutManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StretchableLayoutResizerBar.o: ../../src/gui/components/layout/juce_StretchableLayoutResizerBar.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StretchableLayoutResizerBar.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StretchableObjectResizer.o: ../../src/gui/components/layout/juce_StretchableObjectResizer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StretchableObjectResizer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TabbedButtonBar.o: ../../src/gui/components/layout/juce_TabbedButtonBar.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TabbedButtonBar.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TabbedComponent.o: ../../src/gui/components/layout/juce_TabbedComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TabbedComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Viewport.o: ../../src/gui/components/layout/juce_Viewport.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Viewport.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_LookAndFeel.o: ../../src/gui/components/lookandfeel/juce_LookAndFeel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_LookAndFeel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_OldSchoolLookAndFeel.o: ../../src/gui/components/lookandfeel/juce_OldSchoolLookAndFeel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_OldSchoolLookAndFeel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MenuBarComponent.o: ../../src/gui/components/menus/juce_MenuBarComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MenuBarComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MenuBarModel.o: ../../src/gui/components/menus/juce_MenuBarModel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MenuBarModel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PopupMenu.o: ../../src/gui/components/menus/juce_PopupMenu.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PopupMenu.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentDragger.o: ../../src/gui/components/mouse/juce_ComponentDragger.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentDragger.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DragAndDropContainer.o: ../../src/gui/components/mouse/juce_DragAndDropContainer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DragAndDropContainer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MouseCursor.o: ../../src/gui/components/mouse/juce_MouseCursor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MouseCursor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MouseEvent.o: ../../src/gui/components/mouse/juce_MouseEvent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MouseEvent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MouseHoverDetector.o: ../../src/gui/components/mouse/juce_MouseHoverDetector.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MouseHoverDetector.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MouseInputSource.o: ../../src/gui/components/mouse/juce_MouseInputSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MouseInputSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MouseListener.o: ../../src/gui/components/mouse/juce_MouseListener.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MouseListener.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BooleanPropertyComponent.o: ../../src/gui/components/properties/juce_BooleanPropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BooleanPropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ButtonPropertyComponent.o: ../../src/gui/components/properties/juce_ButtonPropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ButtonPropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ChoicePropertyComponent.o: ../../src/gui/components/properties/juce_ChoicePropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ChoicePropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PropertyComponent.o: ../../src/gui/components/properties/juce_PropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PropertyPanel.o: ../../src/gui/components/properties/juce_PropertyPanel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PropertyPanel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SliderPropertyComponent.o: ../../src/gui/components/properties/juce_SliderPropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SliderPropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TextPropertyComponent.o: ../../src/gui/components/properties/juce_TextPropertyComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TextPropertyComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AudioDeviceSelectorComponent.o: ../../src/gui/components/special/juce_AudioDeviceSelectorComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AudioDeviceSelectorComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BubbleComponent.o: ../../src/gui/components/special/juce_BubbleComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BubbleComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BubbleMessageComponent.o: ../../src/gui/components/special/juce_BubbleMessageComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BubbleMessageComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ColourSelector.o: ../../src/gui/components/special/juce_ColourSelector.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ColourSelector.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DropShadower.o: ../../src/gui/components/special/juce_DropShadower.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DropShadower.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MagnifierComponent.o: ../../src/gui/components/special/juce_MagnifierComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MagnifierComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MidiKeyboardComponent.o: ../../src/gui/components/special/juce_MidiKeyboardComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MidiKeyboardComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_OpenGLComponent.o: ../../src/gui/components/special/juce_OpenGLComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_OpenGLComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PreferencesPanel.o: ../../src/gui/components/special/juce_PreferencesPanel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PreferencesPanel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SystemTrayIconComponent.o: ../../src/gui/components/special/juce_SystemTrayIconComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SystemTrayIconComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AlertWindow.o: ../../src/gui/components/windows/juce_AlertWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AlertWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ComponentPeer.o: ../../src/gui/components/windows/juce_ComponentPeer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ComponentPeer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DialogWindow.o: ../../src/gui/components/windows/juce_DialogWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DialogWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DocumentWindow.o: ../../src/gui/components/windows/juce_DocumentWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DocumentWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ResizableWindow.o: ../../src/gui/components/windows/juce_ResizableWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ResizableWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SplashScreen.o: ../../src/gui/components/windows/juce_SplashScreen.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SplashScreen.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ThreadWithProgressWindow.o: ../../src/gui/components/windows/juce_ThreadWithProgressWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ThreadWithProgressWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TooltipWindow.o: ../../src/gui/components/windows/juce_TooltipWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TooltipWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TopLevelWindow.o: ../../src/gui/components/windows/juce_TopLevelWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TopLevelWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Colour.o: ../../src/gui/graphics/colour/juce_Colour.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Colour.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ColourGradient.o: ../../src/gui/graphics/colour/juce_ColourGradient.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ColourGradient.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Colours.o: ../../src/gui/graphics/colour/juce_Colours.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Colours.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_EdgeTable.o: ../../src/gui/graphics/contexts/juce_EdgeTable.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_EdgeTable.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FillType.o: ../../src/gui/graphics/contexts/juce_FillType.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FillType.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Graphics.o: ../../src/gui/graphics/contexts/juce_Graphics.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Graphics.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Justification.o: ../../src/gui/graphics/contexts/juce_Justification.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Justification.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_LowLevelGraphicsPostScriptRenderer.o: ../../src/gui/graphics/contexts/juce_LowLevelGraphicsPostScriptRenderer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_LowLevelGraphicsPostScriptRenderer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_LowLevelGraphicsSoftwareRenderer.o: ../../src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_LowLevelGraphicsSoftwareRenderer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RectanglePlacement.o: ../../src/gui/graphics/contexts/juce_RectanglePlacement.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RectanglePlacement.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Drawable.o: ../../src/gui/graphics/drawables/juce_Drawable.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Drawable.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DrawableComposite.o: ../../src/gui/graphics/drawables/juce_DrawableComposite.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DrawableComposite.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DrawableImage.o: ../../src/gui/graphics/drawables/juce_DrawableImage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DrawableImage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DrawablePath.o: ../../src/gui/graphics/drawables/juce_DrawablePath.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DrawablePath.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DrawableText.o: ../../src/gui/graphics/drawables/juce_DrawableText.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DrawableText.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SVGParser.o: ../../src/gui/graphics/drawables/juce_SVGParser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SVGParser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DropShadowEffect.o: ../../src/gui/graphics/effects/juce_DropShadowEffect.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DropShadowEffect.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GlowEffect.o: ../../src/gui/graphics/effects/juce_GlowEffect.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GlowEffect.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ReduceOpacityEffect.o: ../../src/gui/graphics/effects/juce_ReduceOpacityEffect.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ReduceOpacityEffect.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Font.o: ../../src/gui/graphics/fonts/juce_Font.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Font.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GlyphArrangement.o: ../../src/gui/graphics/fonts/juce_GlyphArrangement.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GlyphArrangement.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TextLayout.o: ../../src/gui/graphics/fonts/juce_TextLayout.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TextLayout.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Typeface.o: ../../src/gui/graphics/fonts/juce_Typeface.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Typeface.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_AffineTransform.o: ../../src/gui/graphics/geometry/juce_AffineTransform.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_AffineTransform.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BorderSize.o: ../../src/gui/graphics/geometry/juce_BorderSize.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BorderSize.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Path.o: ../../src/gui/graphics/geometry/juce_Path.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Path.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PathIterator.o: ../../src/gui/graphics/geometry/juce_PathIterator.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PathIterator.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PathStrokeType.o: ../../src/gui/graphics/geometry/juce_PathStrokeType.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PathStrokeType.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PositionedRectangle.o: ../../src/gui/graphics/geometry/juce_PositionedRectangle.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PositionedRectangle.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RectangleList.o: ../../src/gui/graphics/geometry/juce_RectangleList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RectangleList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RelativeCoordinate.o: ../../src/gui/graphics/geometry/juce_RelativeCoordinate.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RelativeCoordinate.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GIFLoader.o: ../../src/gui/graphics/imaging/image_file_formats/juce_GIFLoader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GIFLoader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_JPEGLoader.o: ../../src/gui/graphics/imaging/image_file_formats/juce_JPEGLoader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_JPEGLoader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PNGLoader.o: ../../src/gui/graphics/imaging/image_file_formats/juce_PNGLoader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PNGLoader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Image.o: ../../src/gui/graphics/imaging/juce_Image.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Image.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ImageCache.o: ../../src/gui/graphics/imaging/juce_ImageCache.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ImageCache.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ImageConvolutionKernel.o: ../../src/gui/graphics/imaging/juce_ImageConvolutionKernel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ImageConvolutionKernel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ImageFileFormat.o: ../../src/gui/graphics/imaging/juce_ImageFileFormat.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ImageFileFormat.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DirectoryIterator.o: ../../src/io/files/juce_DirectoryIterator.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DirectoryIterator.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_File.o: ../../src/io/files/juce_File.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_File.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileInputStream.o: ../../src/io/files/juce_FileInputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileInputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileOutputStream.o: ../../src/io/files/juce_FileOutputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileOutputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileSearchPath.o: ../../src/io/files/juce_FileSearchPath.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileSearchPath.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_NamedPipe.o: ../../src/io/files/juce_NamedPipe.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_NamedPipe.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TemporaryFile.o: ../../src/io/files/juce_TemporaryFile.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TemporaryFile.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ZipFile.o: ../../src/io/files/juce_ZipFile.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ZipFile.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Socket.o: ../../src/io/network/juce_Socket.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Socket.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_URL.o: ../../src/io/network/juce_URL.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_URL.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_BufferedInputStream.o: ../../src/io/streams/juce_BufferedInputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_BufferedInputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileInputSource.o: ../../src/io/streams/juce_FileInputSource.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileInputSource.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GZIPCompressorOutputStream.o: ../../src/io/streams/juce_GZIPCompressorOutputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GZIPCompressorOutputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_GZIPDecompressorInputStream.o: ../../src/io/streams/juce_GZIPDecompressorInputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_GZIPDecompressorInputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_InputStream.o: ../../src/io/streams/juce_InputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_InputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MemoryInputStream.o: ../../src/io/streams/juce_MemoryInputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MemoryInputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_MemoryOutputStream.o: ../../src/io/streams/juce_MemoryOutputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_MemoryOutputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_OutputStream.o: ../../src/io/streams/juce_OutputStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_OutputStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_SubregionStream.o: ../../src/io/streams/juce_SubregionStream.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_SubregionStream.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_NativeCode.o: ../../src/native/juce_linux_NativeCode.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_NativeCode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_NativeCode.o: ../../src/native/juce_win32_NativeCode.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_NativeCode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_posix_NamedPipe.o: ../../src/native/common/juce_posix_NamedPipe.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_posix_NamedPipe.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Audio.o: ../../src/native/linux/juce_linux_Audio.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Audio.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_AudioCDReader.o: ../../src/native/linux/juce_linux_AudioCDReader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_AudioCDReader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Clipboard.o: ../../src/native/linux/juce_linux_Clipboard.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Clipboard.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_FileChooser.o: ../../src/native/linux/juce_linux_FileChooser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_FileChooser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Files.o: ../../src/native/linux/juce_linux_Files.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Files.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Fonts.o: ../../src/native/linux/juce_linux_Fonts.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Fonts.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_JackAudio.o: ../../src/native/linux/juce_linux_JackAudio.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_JackAudio.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Messaging.o: ../../src/native/linux/juce_linux_Messaging.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Messaging.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Midi.o: ../../src/native/linux/juce_linux_Midi.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Midi.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Network.o: ../../src/native/linux/juce_linux_Network.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Network.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_SystemStats.o: ../../src/native/linux/juce_linux_SystemStats.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_SystemStats.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Threads.o: ../../src/native/linux/juce_linux_Threads.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Threads.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_WebBrowserComponent.o: ../../src/native/linux/juce_linux_WebBrowserComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_WebBrowserComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_linux_Windowing.o: ../../src/native/linux/juce_linux_Windowing.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_linux_Windowing.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_iphone_Audio.o: ../../src/native/mac/juce_iphone_Audio.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_iphone_Audio.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_mac_CoreAudio.o: ../../src/native/mac/juce_mac_CoreAudio.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_mac_CoreAudio.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_mac_CoreMidi.o: ../../src/native/mac/juce_mac_CoreMidi.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_mac_CoreMidi.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_ActiveXComponent.o: ../../src/native/windows/juce_win32_ActiveXComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_ActiveXComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_ASIO.o: ../../src/native/windows/juce_win32_ASIO.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_ASIO.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_AudioCDReader.o: ../../src/native/windows/juce_win32_AudioCDReader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_AudioCDReader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_CameraDevice.o: ../../src/native/windows/juce_win32_CameraDevice.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_CameraDevice.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_DirectSound.o: ../../src/native/windows/juce_win32_DirectSound.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_DirectSound.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_DynamicLibraryLoader.o: ../../src/native/windows/juce_win32_DynamicLibraryLoader.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_DynamicLibraryLoader.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_FileChooser.o: ../../src/native/windows/juce_win32_FileChooser.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_FileChooser.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Files.o: ../../src/native/windows/juce_win32_Files.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Files.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Fonts.o: ../../src/native/windows/juce_win32_Fonts.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Fonts.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Messaging.o: ../../src/native/windows/juce_win32_Messaging.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Messaging.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Midi.o: ../../src/native/windows/juce_win32_Midi.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Midi.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Misc.o: ../../src/native/windows/juce_win32_Misc.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Misc.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Network.o: ../../src/native/windows/juce_win32_Network.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Network.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_OpenGLComponent.o: ../../src/native/windows/juce_win32_OpenGLComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_OpenGLComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_PlatformUtils.o: ../../src/native/windows/juce_win32_PlatformUtils.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_PlatformUtils.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_QuickTimeMovieComponent.o: ../../src/native/windows/juce_win32_QuickTimeMovieComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_QuickTimeMovieComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_SystemStats.o: ../../src/native/windows/juce_win32_SystemStats.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_SystemStats.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Threads.o: ../../src/native/windows/juce_win32_Threads.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Threads.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_WASAPI.o: ../../src/native/windows/juce_win32_WASAPI.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_WASAPI.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_WebBrowserComponent.o: ../../src/native/windows/juce_win32_WebBrowserComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_WebBrowserComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_win32_Windowing.o: ../../src/native/windows/juce_win32_Windowing.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_win32_Windowing.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_CharacterFunctions.o: ../../src/text/juce_CharacterFunctions.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_CharacterFunctions.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_LocalisedStrings.o: ../../src/text/juce_LocalisedStrings.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_LocalisedStrings.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_String.o: ../../src/text/juce_String.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_String.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StringArray.o: ../../src/text/juce_StringArray.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StringArray.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StringPairArray.o: ../../src/text/juce_StringPairArray.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StringPairArray.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_StringPool.o: ../../src/text/juce_StringPool.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_StringPool.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_XmlDocument.o: ../../src/text/juce_XmlDocument.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_XmlDocument.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_XmlElement.o: ../../src/text/juce_XmlElement.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_XmlElement.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ReadWriteLock.o: ../../src/threads/juce_ReadWriteLock.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ReadWriteLock.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_Thread.o: ../../src/threads/juce_Thread.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_Thread.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_ThreadPool.o: ../../src/threads/juce_ThreadPool.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_ThreadPool.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_TimeSliceThread.o: ../../src/threads/juce_TimeSliceThread.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_TimeSliceThread.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_DeletedAtShutdown.o: ../../src/utilities/juce_DeletedAtShutdown.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_DeletedAtShutdown.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_FileBasedDocument.o: ../../src/utilities/juce_FileBasedDocument.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_FileBasedDocument.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_PropertiesFile.o: ../../src/utilities/juce_PropertiesFile.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_PropertiesFile.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_RecentlyOpenedFilesList.o: ../../src/utilities/juce_RecentlyOpenedFilesList.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_RecentlyOpenedFilesList.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/juce_UndoManager.o: ../../src/utilities/juce_UndoManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling juce_UndoManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/Jucer (experimental)/Builds/Linux/Makefile b/extras/Jucer (experimental)/Builds/Linux/Makefile index d4772c74b5..41ec312d9f 100644 --- a/extras/Jucer (experimental)/Builds/Linux/Makefile +++ b/extras/Jucer (experimental)/Builds/Linux/Makefile @@ -68,7 +68,6 @@ OBJECTS := \ $(OBJDIR)/jucer_ProjectTreeViewBase.o \ $(OBJDIR)/jucer_TreeViewTypes.o \ $(OBJDIR)/jucer_CodeHelpers.o \ - $(OBJDIR)/jucer_Coordinate.o \ $(OBJDIR)/jucer_FileHelpers.o \ $(OBJDIR)/jucer_StoredSettings.o \ $(OBJDIR)/jucer_MiscUtilities.o \ @@ -96,177 +95,172 @@ clean: $(OBJDIR)/jucer_CodeGenerator.o: ../../Source/model/Component/jucer_CodeGenerator.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_CodeGenerator.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ComponentDocument.o: ../../Source/model/Component/jucer_ComponentDocument.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ComponentDocument.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ComponentTypeManager.o: ../../Source/model/Component/Types/jucer_ComponentTypeManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ComponentTypeManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_DrawableDocument.o: ../../Source/model/Drawable/jucer_DrawableDocument.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_DrawableDocument.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_NewFileWizard.o: ../../Source/model/Project/jucer_NewFileWizard.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_NewFileWizard.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_Project.o: ../../Source/model/Project/jucer_Project.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_Project.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ProjectExporter.o: ../../Source/model/Project/jucer_ProjectExporter.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ProjectExporter.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ProjectWizard.o: ../../Source/model/Project/jucer_ProjectWizard.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ProjectWizard.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ResourceFile.o: ../../Source/model/Project/jucer_ResourceFile.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ResourceFile.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_SourceCodeEditor.o: ../../Source/ui/Code\ Editor/jucer_SourceCodeEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_SourceCodeEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ComponentEditor.o: ../../Source/ui/Component\ Editor/jucer_ComponentEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ComponentEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ComponentViewer.o: ../../Source/ui/Component\ Editor/jucer_ComponentViewer.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ComponentViewer.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_DrawableEditor.o: ../../Source/ui/Drawable\ Editor/jucer_DrawableEditor.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_DrawableEditor.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_EditorCanvas.o: ../../Source/ui/Editor\ Base/jucer_EditorCanvas.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_EditorCanvas.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_DocumentEditorComponent.o: ../../Source/ui/jucer_DocumentEditorComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_DocumentEditorComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_JucerTreeViewBase.o: ../../Source/ui/jucer_JucerTreeViewBase.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_JucerTreeViewBase.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_MainWindow.o: ../../Source/ui/jucer_MainWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_MainWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_OpenDocumentManager.o: ../../Source/ui/jucer_OpenDocumentManager.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_OpenDocumentManager.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_GroupInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_GroupInformationComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_GroupInformationComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ItemPreviewComponent.o: ../../Source/ui/Project\ Editor/jucer_ItemPreviewComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ItemPreviewComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ProjectContentComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectContentComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ProjectContentComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ProjectInformationComponent.o: ../../Source/ui/Project\ Editor/jucer_ProjectInformationComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ProjectInformationComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_ProjectTreeViewBase.o: ../../Source/ui/Project\ Editor/jucer_ProjectTreeViewBase.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_ProjectTreeViewBase.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_TreeViewTypes.o: ../../Source/ui/Project\ Editor/jucer_TreeViewTypes.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_TreeViewTypes.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_CodeHelpers.o: ../../Source/utility/jucer_CodeHelpers.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) - @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" - -$(OBJDIR)/jucer_Coordinate.o: ../../Source/utility/jucer_Coordinate.cpp - -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_CodeHelpers.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_FileHelpers.o: ../../Source/utility/jucer_FileHelpers.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_FileHelpers.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_StoredSettings.o: ../../Source/utility/jucer_StoredSettings.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_StoredSettings.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_MiscUtilities.o: ../../Source/utility/jucer_MiscUtilities.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_MiscUtilities.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/jucer_Main.o: ../../Source/jucer_Main.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling jucer_Main.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling BinaryData.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode1.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode2.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode3.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode4.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj index 20378ddf27..f737d37c7f 100644 --- a/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj +++ b/extras/Jucer (experimental)/Builds/MacOSX/The Jucer.xcodeproj/project.pbxproj @@ -42,7 +42,6 @@ 984444E3B2947675DC7D65DA = { isa = PBXBuildFile; fileRef = 1FDE55685608689765ADC578; }; 58BF60E87F9A8EDCACC5D1AE = { isa = PBXBuildFile; fileRef = 939E2A7946081DB4D21B89B6; }; 28B94C4BB7B572E6F5419E5D = { isa = PBXBuildFile; fileRef = 78E0309CB6D5E7E80B5BED7D; }; - 5BF87265418D736250283182 = { isa = PBXBuildFile; fileRef = C7ADB43F83A83FFC08921A12; }; 12C1D006503C664FF07F476F = { isa = PBXBuildFile; fileRef = 5533704F0D30A9C62058FEC7; }; DDAB225ABE572196882C3524 = { isa = PBXBuildFile; fileRef = 7A1CD936BD306A6E0BEFB046; }; 92612DD3884793248F1EC45A = { isa = PBXBuildFile; fileRef = 49A1C43070A68985C25F34C7; }; @@ -85,6 +84,7 @@ E894E1F6D582678EE1F02763 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Viewport.h; path = ../../Source/model/Component/Types/jucer_Viewport.h; sourceTree = SOURCE_ROOT; }; B1471E8698D193FBCF0DD13D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_DrawableDocument.cpp; path = ../../Source/model/Drawable/jucer_DrawableDocument.cpp; sourceTree = SOURCE_ROOT; }; 739F94CA6213B43D867AB0FD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableDocument.h; path = ../../Source/model/Drawable/jucer_DrawableDocument.h; sourceTree = SOURCE_ROOT; }; + BDE8CD9273E1B0D0E500D283 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_DrawableTypeHandler.h; path = ../../Source/model/Drawable/jucer_DrawableTypeHandler.h; sourceTree = SOURCE_ROOT; }; 9DCB32BBD7053ACCB598CE79 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_NewFileWizard.cpp; path = ../../Source/model/Project/jucer_NewFileWizard.cpp; sourceTree = SOURCE_ROOT; }; 201DF0B7B4AA3E03B1AA5144 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_NewFileWizard.h; path = ../../Source/model/Project/jucer_NewFileWizard.h; sourceTree = SOURCE_ROOT; }; 4179D4C7BF616A4A3C3E11CA = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Project.cpp; path = ../../Source/model/Project/jucer_Project.cpp; sourceTree = SOURCE_ROOT; }; @@ -143,8 +143,6 @@ 9C58E022906C193862372BC1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CodeHelpers.h; path = ../../Source/utility/jucer_CodeHelpers.h; sourceTree = SOURCE_ROOT; }; AAF3C58696944A256CA61730 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_ColourEditorComponent.h; path = ../../Source/utility/jucer_ColourEditorComponent.h; sourceTree = SOURCE_ROOT; }; 9736236B5C4D6A16FC7E03AC = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Colours.h; path = ../../Source/utility/jucer_Colours.h; sourceTree = SOURCE_ROOT; }; - C7ADB43F83A83FFC08921A12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_Coordinate.cpp; path = ../../Source/utility/jucer_Coordinate.cpp; sourceTree = SOURCE_ROOT; }; - EFA0636FB8ABA3377AB6C6F4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_Coordinate.h; path = ../../Source/utility/jucer_Coordinate.h; sourceTree = SOURCE_ROOT; }; CC9A3046B8B9FCDFE2092F51 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_CoordinatePropertyComponent.h; path = ../../Source/utility/jucer_CoordinatePropertyComponent.h; sourceTree = SOURCE_ROOT; }; 5533704F0D30A9C62058FEC7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = jucer_FileHelpers.cpp; path = ../../Source/utility/jucer_FileHelpers.cpp; sourceTree = SOURCE_ROOT; }; 27E71DE11448E4D6721D5508 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jucer_FileHelpers.h; path = ../../Source/utility/jucer_FileHelpers.h; sourceTree = SOURCE_ROOT; }; @@ -204,7 +202,8 @@ 7C95A5CDB1B24D227D92749E ); name = Component; sourceTree = ""; }; E70E3BE796E91EA86CFE10FE = { isa = PBXGroup; children = ( B1471E8698D193FBCF0DD13D, - 739F94CA6213B43D867AB0FD ); name = Drawable; sourceTree = ""; }; + 739F94CA6213B43D867AB0FD, + BDE8CD9273E1B0D0E500D283 ); name = Drawable; sourceTree = ""; }; ADA17383E5554BCDF567AACC = { isa = PBXGroup; children = ( 9DCB32BBD7053ACCB598CE79, 201DF0B7B4AA3E03B1AA5144, @@ -280,8 +279,6 @@ 9C58E022906C193862372BC1, AAF3C58696944A256CA61730, 9736236B5C4D6A16FC7E03AC, - C7ADB43F83A83FFC08921A12, - EFA0636FB8ABA3377AB6C6F4, CC9A3046B8B9FCDFE2092F51, 5533704F0D30A9C62058FEC7, 27E71DE11448E4D6721D5508, @@ -438,7 +435,6 @@ 984444E3B2947675DC7D65DA, 58BF60E87F9A8EDCACC5D1AE, 28B94C4BB7B572E6F5419E5D, - 5BF87265418D736250283182, 12C1D006503C664FF07F476F, DDAB225ABE572196882C3524, 92612DD3884793248F1EC45A, diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj index 68c1e057b6..1448d21fc2 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2005/The Jucer.vcproj @@ -154,6 +154,7 @@ + @@ -229,8 +230,6 @@ - - diff --git a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj index 1fa95b2037..6117d47c36 100644 --- a/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj +++ b/extras/Jucer (experimental)/Builds/VisualStudio2008/The Jucer.vcproj @@ -154,6 +154,7 @@ + @@ -229,8 +230,6 @@ - - diff --git a/extras/Jucer (experimental)/Jucer.jucer b/extras/Jucer (experimental)/Jucer.jucer index 8865a839e9..27e09c6714 100644 --- a/extras/Jucer (experimental)/Jucer.jucer +++ b/extras/Jucer (experimental)/Jucer.jucer @@ -72,6 +72,8 @@ file="Source/model/Drawable/jucer_DrawableDocument.cpp"/> + - - = 0;) - if (handlers.getUnchecked(i)->getXmlTag() == type) + if (handlers.getUnchecked(i)->getValueTreeType() == type) return handlers.getUnchecked(i); return 0; @@ -205,8 +205,8 @@ juce_ImplementSingleton_SingleThreaded (ComponentTypeManager); //============================================================================== ComponentTypeHandler::ComponentTypeHandler (const String& displayName_, const String& className_, - const String& xmlTag_, const String& memberNameRoot_) - : displayName (displayName_), className (className_), xmlTag (xmlTag_), + const Identifier& valueTreeType_, const String& memberNameRoot_) + : displayName (displayName_), className (className_), valueTreeType (valueTreeType_), memberNameRoot (memberNameRoot_) { } @@ -315,7 +315,7 @@ void ComponentTypeInstance::initialiseNewItemBasics() void ComponentTypeInstance::updateComponentBasics (Component* comp) { RelativeRectangle pos (state [ComponentDocument::compBoundsProperty].toString()); - comp->setBounds (pos.resolve (document).getSmallestIntegerContainer()); + comp->setBounds (pos.resolve (&document).getSmallestIntegerContainer()); //comp->setName (state [ComponentDocument::compNameProperty]); diff --git a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h index 8f8dc05973..4f9f58e52f 100644 --- a/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h +++ b/extras/Jucer (experimental)/Source/model/Component/Types/jucer_ComponentTypeManager.h @@ -86,11 +86,12 @@ class ComponentTypeHandler { public: //============================================================================== - ComponentTypeHandler (const String& displayName_, const String& className_, const String& xmlTag_, const String& memberNameRoot_); + ComponentTypeHandler (const String& displayName_, const String& className_, + const Identifier& valueTreeType_, const String& memberNameRoot_); virtual ~ComponentTypeHandler(); const String& getDisplayName() const { return displayName; } - const Identifier& getXmlTag() const { return xmlTag; } + const Identifier& getValueTreeType() const { return valueTreeType; } const String& getMemberNameRoot() const { return memberNameRoot; } virtual Component* createComponent() = 0; @@ -106,7 +107,7 @@ public: protected: //============================================================================== const String displayName, className, memberNameRoot; - const Identifier xmlTag; + const Identifier valueTreeType; private: ComponentTypeHandler (const ComponentTypeHandler&); diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp index bb00a8d2e0..ba024a4c28 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.cpp @@ -359,7 +359,7 @@ const ValueTree ComponentDocument::performNewComponentMenuItem (int menuResultCo if (handler != 0) { - ValueTree state (handler->getXmlTag()); + ValueTree state (handler->getValueTreeType()); state.setProperty (idProperty, createAlphaNumericUID(), 0); ComponentTypeInstance comp (*this, state); @@ -532,7 +532,7 @@ void ComponentDocument::renameAnchor (const String& oldName, const String& newNa { ValueTree v (getComponent(i)); RelativeRectangle coords (getCoordsFor (v)); - coords.renameAnchorIfUsed (oldName, newName, *this); + coords.renameAnchorIfUsed (oldName, newName, this); setCoordsFor (v, coords); } @@ -551,7 +551,7 @@ void ComponentDocument::addMarkerMenuItem (int i, const RelativeCoordinate& coor name << '.' << edge; menu.addItem (i, name, - ! (name == fullCoordName || requestedCoord.references (fullCoordName, *this)), + ! (name == fullCoordName || requestedCoord.references (fullCoordName, this)), name == (isAnchor1 ? coord.getAnchorName1() : coord.getAnchorName2())); } @@ -780,7 +780,7 @@ bool ComponentDocument::MarkerList::createProperties (Array props.add (new TextPropertyComponent (Value (new MarkerListBase::MarkerNameValueSource (this, getNameAsValue (marker))), "Marker Name", 256, false)); - props.add (new MarkerListBase::PositionPropertyComponent (document, *this, "Position", marker, + props.add (new MarkerListBase::PositionPropertyComponent (&document, *this, "Position", marker, marker.getPropertyAsValue (getMarkerPosProperty(), document.getUndoManager()))); return true; } diff --git a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h index 798e01b825..4e1f3e452d 100644 --- a/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h +++ b/extras/Jucer (experimental)/Source/model/Component/jucer_ComponentDocument.h @@ -28,7 +28,6 @@ #include "../../jucer_Headers.h" #include "../Project/jucer_Project.h" -#include "../../utility/jucer_Coordinate.h" #include "../../utility/jucer_MarkerListBase.h" #include "jucer_CodeGenerator.h" diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp index 56ae09a7d1..2f9bb4fbdd 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.cpp @@ -24,6 +24,54 @@ */ #include "jucer_DrawableDocument.h" +#include "jucer_DrawableTypeHandler.h" + + +//============================================================================== +class DrawableTypeManager : public DeletedAtShutdown +{ +public: + DrawableTypeManager() + { + handlers.add (new DrawablePathHandler()); + handlers.add (new DrawableImageHandler()); + } + + ~DrawableTypeManager() + { + } + + juce_DeclareSingleton_SingleThreaded_Minimal (DrawableTypeManager); + + //============================================================================== + int getNumHandlers() const { return handlers.size(); } + DrawableTypeHandler* getHandler (const int index) const { return handlers[index]; } + + DrawableTypeHandler* getHandlerFor (const Identifier& type) + { + for (int i = handlers.size(); --i >= 0;) + if (handlers.getUnchecked(i)->getValueTreeType() == type) + return handlers.getUnchecked(i); + + jassertfalse; + return 0; + } + + const StringArray getDisplayNames() + { + StringArray s; + + for (int i = 0; i < handlers.size(); ++i) + s.add (handlers.getUnchecked(i)->getDisplayName()); + + return s; + } + +private: + OwnedArray handlers; +}; + +juce_ImplementSingleton_SingleThreaded (DrawableTypeManager); //============================================================================== @@ -55,9 +103,9 @@ DrawableDocument::~DrawableDocument() root.removeListener (this); } -ValueTree DrawableDocument::getRootDrawableNode() const +DrawableComposite::ValueTreeWrapper DrawableDocument::getRootDrawableNode() const { - return root.getChild (0); + return DrawableComposite::ValueTreeWrapper (root.getChild (0)); } void DrawableDocument::checkRootObject() @@ -75,11 +123,6 @@ void DrawableDocument::checkRootObject() getCanvasHeight() = 500; } -const String DrawableDocument::getIdFor (const ValueTree& object) -{ - return object [Ids::id_]; -} - //============================================================================== void DrawableDocument::setName (const String& name) { @@ -194,59 +237,49 @@ void DrawableDocument::changed() } //============================================================================== -static const Colour getRandomColour() -{ - return Colours::red.withHue (Random::getSystemRandom().nextFloat()); -} +const int menuItemOffset = 0x63451fa4; -void DrawableDocument::addDrawable (Drawable& d) +void DrawableDocument::addNewItemMenuItems (PopupMenu& menu) const { - DrawableComposite dc; - dc.insertDrawable (d.createCopy()); - - ValueTree dcNode (dc.createValueTree (0)); - ValueTree subNode (dcNode.getChild(0)); - dcNode.removeChild (subNode, 0); - addMissingIds (subNode); + const StringArray displayNames (DrawableTypeManager::getInstance()->getDisplayNames()); - getRootDrawableNode().addChild (subNode, -1, getUndoManager()); + for (int i = 0; i < displayNames.size(); ++i) + menu.addItem (i + menuItemOffset, "New " + displayNames[i]); } -void DrawableDocument::addRectangle() +const ValueTree DrawableDocument::performNewItemMenuItem (int menuResultCode) { - Path p; - p.addRectangle ((float) Random::getSystemRandom().nextInt (500), - (float) Random::getSystemRandom().nextInt (500), - 100.0f, 100.0f); + const StringArray displayNames (DrawableTypeManager::getInstance()->getDisplayNames()); - DrawablePath d; - d.setPath (p); - d.setFill (FillType (getRandomColour())); + if (menuResultCode >= menuItemOffset && menuResultCode < menuItemOffset + displayNames.size()) + { + DrawableTypeHandler* handler = DrawableTypeManager::getInstance()->getHandler (menuResultCode - menuItemOffset); + jassert (handler != 0); - addDrawable (d); -} + if (handler != 0) + { + ValueTree state (handler->createNewInstance (*this, + Point (Random::getSystemRandom().nextFloat() * 100.0f + 100.0f, + Random::getSystemRandom().nextFloat() * 100.0f + 100.0f))); -void DrawableDocument::addCircle() -{ - Path p; - p.addEllipse ((float) Random::getSystemRandom().nextInt (500), - (float) Random::getSystemRandom().nextInt (500), - 100.0f, 100.0f); + getRootDrawableNode().addDrawable (state, -1, getUndoManager()); - DrawablePath d; - d.setPath (p); - d.setFill (FillType (getRandomColour())); + return state; + } + } - addDrawable (d); + return ValueTree::invalid; } -void DrawableDocument::addImage (const File& imageFile) +//============================================================================== +Image* DrawableDocument::getImageForIdentifier (const var& imageIdentifier) { - jassertfalse - - DrawableImage d; + return ImageCache::getFromMemory (BinaryData::juce_icon_png, BinaryData::juce_icon_pngSize); +} - addDrawable (d); +const var DrawableDocument::getIdentifierForImage (Image* image) +{ + return var::null; //xxx todo } //============================================================================== diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h index 961cede09c..fbd113f2cc 100644 --- a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableDocument.h @@ -28,13 +28,13 @@ #include "../../jucer_Headers.h" #include "../Project/jucer_Project.h" -#include "../../utility/jucer_Coordinate.h" #include "../../utility/jucer_MarkerListBase.h" //============================================================================== class DrawableDocument : public ValueTree::Listener, - public ChangeBroadcaster + public ChangeBroadcaster, + public Drawable::ImageProvider { public: //============================================================================== @@ -51,16 +51,13 @@ public: void changed(); ValueTree& getRoot() { return root; } - ValueTree getRootDrawableNode() const; - - void addRectangle(); - void addCircle(); - void addImage (const File& imageFile); + DrawableComposite::ValueTreeWrapper getRootDrawableNode() const; Value getCanvasWidth() const { return getRootValueNonUndoable (Ids::width); } Value getCanvasHeight() const { return getRootValueNonUndoable (Ids::height); } - static const String getIdFor (const ValueTree& object); + void addNewItemMenuItems (PopupMenu& menu) const; + const ValueTree performNewItemMenuItem (int menuResultCode); //============================================================================== class MarkerList : public MarkerListBase @@ -91,6 +88,9 @@ public: const String getNonexistentMarkerName (const String& name); void renameAnchor (const String& oldName, const String& newName); + Image* getImageForIdentifier (const var& imageIdentifier); + const var getIdentifierForImage (Image* image); + //============================================================================== void valueTreePropertyChanged (ValueTree& tree, const Identifier& name); void valueTreeChildrenChanged (ValueTree& tree); diff --git a/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h new file mode 100644 index 0000000000..44ba2a510d --- /dev/null +++ b/extras/Jucer (experimental)/Source/model/Drawable/jucer_DrawableTypeHandler.h @@ -0,0 +1,103 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-10 by Raw Material Software Ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the GNU General + Public License (Version 2), as published by the Free Software Foundation. + A copy of the license is included in the JUCE distribution, or can be found + online at www.gnu.org/licenses. + + JUCE is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + ------------------------------------------------------------------------------ + + To release a closed-source product which uses JUCE, commercial licenses are + available: visit www.rawmaterialsoftware.com/juce for more information. + + ============================================================================== +*/ + +#ifndef __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ +#define __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ + +#include "jucer_DrawableDocument.h" + + +//============================================================================== +class DrawableTypeHandler +{ +public: + DrawableTypeHandler (const String& displayName_, const Identifier& valueTreeType_) + : displayName (displayName_), valueTreeType (valueTreeType_) + { + } + + virtual ~DrawableTypeHandler() {} + + virtual const ValueTree createNewInstance (DrawableDocument& document, const Point& approxPosition) = 0; + + const String& getDisplayName() const { return displayName; } + const Identifier& getValueTreeType() const { return valueTreeType; } + +private: + const String displayName; + const Identifier valueTreeType; +}; + +//============================================================================== +class DrawablePathHandler : public DrawableTypeHandler +{ +public: + DrawablePathHandler() : DrawableTypeHandler ("Polygon", DrawablePath::valueTreeType) {} + ~DrawablePathHandler() {} + + const ValueTree createNewInstance (DrawableDocument& document, const Point& approxPosition) + { + Path p; + p.addTriangle (approxPosition.getX(), approxPosition.getY() - 50.0f, + approxPosition.getX() + 50.0f, approxPosition.getY() + 20.0f, + approxPosition.getX() - 50.0f, approxPosition.getY() + 20.0f); + + DrawablePath dp; + dp.setPath (p); + dp.setFill (Colours::lightblue.withHue (Random::getSystemRandom().nextFloat())); + return dp.createValueTree (0); + } +}; + +//============================================================================== +class DrawableImageHandler : public DrawableTypeHandler +{ +public: + DrawableImageHandler() : DrawableTypeHandler ("Image", DrawableImage::valueTreeType) {} + ~DrawableImageHandler() {} + + const ValueTree createNewInstance (DrawableDocument& document, const Point& approxPosition) + { + Image tempImage (Image::ARGB, 100, 100, true); + + { + Graphics g (tempImage); + g.fillAll (Colours::grey.withAlpha (0.3f)); + g.setColour (Colours::red); + g.setFont (40.0f); + g.drawText ("?", 0, 0, 100, 100, Justification::centred, false); + } + + DrawableImage di; + di.setTransform (RelativePoint (approxPosition), + RelativePoint (approxPosition + Point (100.0f, 0.0f)), + RelativePoint (approxPosition + Point (0.0f, 100.0f))); + return di.createValueTree (&document); + } +}; + + + +#endif // __JUCER_DRAWABLETYPEHANDLER_H_7FB02E2F__ diff --git a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h index 50610d73c3..4430c4616d 100644 --- a/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h +++ b/extras/Jucer (experimental)/Source/model/Project/jucer_ProjectExport_Make.h @@ -298,7 +298,7 @@ private: out << "$(OBJDIR)/" << escapeSpaces (getObjectFileFor (files.getReference(i))) << ": " << escapeSpaces (files.getReference(i).toUnixStyle()) << newLine << "\t-@mkdir -p $(OBJDIR)" << newLine - << "\t@echo $(notdir $<)" << newLine + << "\t@echo \"Compiling " << files.getReference(i).getFileName() << "\"" << newLine << (files.getReference(i).hasFileExtension (".c") ? "\t@$(CC) $(CFLAGS) -o \"$@\" -c \"$<\"" : "\t@$(CXX) $(CXXFLAGS) -o \"$@\" -c \"$<\"") << newLine << newLine; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h index 73acaab02a..1292ec2b55 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCanvas.h @@ -120,7 +120,7 @@ public: const Rectangle getObjectPosition (const ValueTree& state) { - return getDocument().getCoordsFor (state).resolve (getDocument()).getSmallestIntegerContainer(); + return getDocument().getCoordsFor (state).resolve (&getDocument()).getSmallestIntegerContainer(); } RelativeRectangle getObjectCoords (const ValueTree& state) @@ -176,14 +176,14 @@ public: const Rectangle getObjectPosition (const ValueTree& state) { ComponentDocument& doc = getDocument(); - return doc.getCoordsFor (state).resolve (doc); + return doc.getCoordsFor (state).resolve (&doc); } bool setObjectPosition (ValueTree& state, const Rectangle& newBounds) { ComponentDocument& doc = getDocument(); RelativeRectangle pr (doc.getCoordsFor (state)); - pr.moveToAbsolute (newBounds, doc); + pr.moveToAbsolute (newBounds, &doc); return doc.setCoordsFor (state, pr); } @@ -191,7 +191,7 @@ public: float getMarkerPosition (const ValueTree& marker, bool isX) { ComponentDocument& doc = getDocument(); - return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (doc); + return (float) doc.getMarkerList (isX).getCoordinate (marker).resolve (&doc); } }; diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp index 150e929fa0..aeb183dbe4 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.cpp @@ -80,7 +80,7 @@ void ComponentViewer::handleAsyncUpdate() background = Colour::fromString (componentDocument->getBackgroundColour().toString()); if (layoutManager == 0) - layoutManager = new ComponentAutoLayoutManager (this); + layoutManager = new RelativeRectangleLayoutManager (this); int i; for (i = getNumChildComponents(); --i >= 0;) diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h index 86d881fb9c..725512e085 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentViewer.h @@ -62,7 +62,7 @@ private: ComponentDocument* componentDocument; ValueTree documentRoot; - ScopedPointer layoutManager; + ScopedPointer layoutManager; Colour background; ComponentViewer (const ComponentViewer&); diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp index 185b283e4c..0c938e5810 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditor.cpp @@ -53,7 +53,7 @@ public: void createCanvas() { initialise (new DrawableEditorCanvas (editor), toolbarFactory, - new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode())); + new DrawableTreeViewItem (editor, editor.getDocument().getRootDrawableNode().getState())); } SelectedItemSet& getSelection() @@ -117,17 +117,10 @@ void DrawableEditor::selectionToBack() void DrawableEditor::showNewShapeMenu (Component* componentToAttachTo) { - /* PopupMenu m; - getDocument().addNewComponentMenuItems (m); - + getDocument().addNewItemMenuItems (m); const int r = m.showAt (componentToAttachTo); - - const ValueTree newComp (getDocument().performNewComponentMenuItem (r)); - - if (newComp.isValid()) - getSelection().selectOnly (newComp [ComponentDocument::idProperty]); -*/ + getDocument().performNewItemMenuItem (r); } //============================================================================== diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h index e960dc9759..2f56863bd1 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorCanvas.h @@ -54,8 +54,19 @@ public: void updateComponents() { - drawable = Drawable::createFromValueTree (getEditor().getDocument().getRootDrawableNode(), 0); - getComponentHolder()->repaint(); + DrawableDocument& doc = getEditor().getDocument(); + + if (drawable == 0) + { + drawable = Drawable::createFromValueTree (doc.getRootDrawableNode().getState(), &doc); + getComponentHolder()->repaint(); + } + else + { + const Rectangle damage (drawable->refreshFromValueTree (doc.getRootDrawableNode().getState(), &doc)); + getComponentHolder()->repaint (damage.getSmallestIntegerContainer()); + } + startTimer (500); } @@ -89,9 +100,9 @@ public: } else { -// getDocument().addNewComponentMenuItems (m); - // const int r = m.show(); - // getDocument().performNewComponentMenuItem (r); + getDocument().addNewItemMenuItems (m); + const int r = m.show(); + getDocument().performNewItemMenuItem (r); } } diff --git a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h index 54d5628e6e..53b5d1fc3a 100644 --- a/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h +++ b/extras/Jucer (experimental)/Source/ui/Drawable Editor/jucer_DrawableEditorTreeView.h @@ -38,14 +38,14 @@ public: DrawableTreeViewItem (DrawableEditor& editor_, const ValueTree& drawableRoot) : editor (editor_), node (drawableRoot), typeName (drawableRoot.getType().toString()) { - node.addListener (this); + node.getState().addListener (this); editor.getSelection().addChangeListener (this); } ~DrawableTreeViewItem() { editor.getSelection().removeChangeListener (this); - node.removeListener (this); + node.getState().removeListener (this); } //============================================================================== @@ -55,7 +55,7 @@ public: void valueTreeChildrenChanged (ValueTree& tree) { - if (tree == node) + if (tree == node.getState()) refreshSubItems(); } @@ -67,14 +67,13 @@ public: // TreeViewItem stuff.. bool mightContainSubItems() { - return node.getType() == DrawableComposite::valueTreeType - && node.getNumChildren() > 0; + return node.getState().getType() == DrawableComposite::valueTreeType; } const String getUniqueName() const { - jassert (node [Ids::id_].toString().isNotEmpty()); - return node [Ids::id_]; + jassert (node.getID().isNotEmpty()); + return node.getID(); } void itemOpennessChanged (bool isNowOpen) @@ -85,15 +84,17 @@ public: void refreshSubItems() { - if (node.getType() == DrawableComposite::valueTreeType) + if (node.getState().getType() == DrawableComposite::valueTreeType) { ScopedPointer oldOpenness (getOpennessState()); clearSubItems(); - for (int i = 0; i < node.getNumChildren(); ++i) + DrawableComposite::ValueTreeWrapper composite (node.getState()); + + for (int i = 0; i < composite.getNumDrawables(); ++i) { - ValueTree subNode (node.getChild (i)); + ValueTree subNode (composite.getDrawableState (i)); DrawableTreeViewItem* const item = new DrawableTreeViewItem (editor, subNode); addSubItem (item); } @@ -114,7 +115,7 @@ public: const String getRenamingName() const { - return node ["name"]; + return node.getID(); } void setName (const String& newName) @@ -138,7 +139,7 @@ public: void itemSelectionChanged (bool isNowSelected) { - const String objectId (DrawableDocument::getIdFor (node)); + const String objectId (node.getID()); if (isNowSelected) editor.getSelection().addToSelection (objectId); @@ -148,7 +149,7 @@ public: void changeListenerCallback (void*) { - setSelected (editor.getSelection().isSelected (DrawableDocument::getIdFor (node)), false); + setSelected (editor.getSelection().isSelected (node.getID()), false); } const String getTooltip() @@ -194,7 +195,7 @@ public: //============================================================================== DrawableEditor& editor; - ValueTree node; + Drawable::ValueTreeWrapperBase node; private: String typeName; diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp index 1c31a591b4..0c0c00902c 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.cpp @@ -243,7 +243,7 @@ public: void updatePosition() { RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); - const int pos = roundToInt (coord.resolve (getMarkerList())); + const int pos = roundToInt (coord.resolve (&getMarkerList())); const int width = 8; if (isX) @@ -309,7 +309,7 @@ public: canvas->getUndoManager().beginNewTransaction(); RelativeCoordinate coord (getMarkerList().getCoordinate (marker)); - dragStartPos = coord.resolve (getMarkerList()); + dragStartPos = coord.resolve (&getMarkerList()); } } @@ -335,7 +335,7 @@ public: // (can't use getDistanceFromDragStart() because it doesn't take into account auto-scrolling) coord.moveToAbsolute (jmax (0, roundToInt (dragStartPos + (isX ? e2.x - mouseDownPos.getX() : e2.y - mouseDownPos.getY()))), - getMarkerList()); + &getMarkerList()); getMarkerList().setCoordinate (marker, coord); } else diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h index cc65087da8..a5dbaef5eb 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorCanvas.h @@ -26,10 +26,10 @@ #ifndef __JUCER_EDITORCANVAS_H_EF886D17__ #define __JUCER_EDITORCANVAS_H_EF886D17__ -#include "../../utility/jucer_Coordinate.h" #include "../../utility/jucer_MarkerListBase.h" class EditorPanelBase; + //============================================================================== class EditorCanvasBase : public Component, public ValueTree::Listener, diff --git a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.cpp b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.cpp deleted file mode 100644 index 8c8aaca9d3..0000000000 --- a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-10 by Raw Material Software Ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the GNU General - Public License (Version 2), as published by the Free Software Foundation. - A copy of the license is included in the JUCE distribution, or can be found - online at www.gnu.org/licenses. - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.rawmaterialsoftware.com/juce for more information. - - ============================================================================== -*/ - -#include "jucer_Coordinate.h" - - -//============================================================================== -ComponentAutoLayoutManager::ComponentAutoLayoutManager (Component* parentComponent) - : parent (parentComponent) -{ - parent->addComponentListener (this); -} - -ComponentAutoLayoutManager::~ComponentAutoLayoutManager() -{ - parent->removeComponentListener (this); - - for (int i = components.size(); --i >= 0;) - components.getUnchecked(i)->component->removeComponentListener (this); -} - -void ComponentAutoLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord) -{ - for (int i = markers.size(); --i >= 0;) - { - MarkerPosition* m = markers.getUnchecked(i); - if (m->markerName == name) - { - m->position = coord; - applyLayout(); - return; - } - } - - markers.add (new MarkerPosition (name, coord)); - applyLayout(); -} - -void ComponentAutoLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords) -{ - jassert (comp != 0); - - // All the components that this layout manages must be inside the parent component.. - jassert (parent->isParentOf (comp)); - - for (int i = components.size(); --i >= 0;) - { - ComponentPosition* c = components.getUnchecked(i); - if (c->component == comp) - { - c->name = name; - c->coords = coords; - triggerAsyncUpdate(); - return; - } - } - - components.add (new ComponentPosition (comp, name, coords)); - comp->addComponentListener (this); - triggerAsyncUpdate(); -} - -void ComponentAutoLayoutManager::applyLayout() -{ - for (int i = components.size(); --i >= 0;) - { - ComponentPosition* c = components.getUnchecked(i); - - // All the components that this layout manages must be inside the parent component.. - jassert (parent->isParentOf (c->component)); - - c->component->setBounds (c->coords.resolve (*this).getSmallestIntegerContainer()); - } -} - -const RelativeCoordinate ComponentAutoLayoutManager::findNamedCoordinate (const String& objectName, const String& edge) const -{ - if (objectName == RelativeCoordinate::Strings::parent) - { - if (edge == RelativeCoordinate::Strings::right) return RelativeCoordinate ((double) parent->getWidth(), true); - if (edge == RelativeCoordinate::Strings::bottom) return RelativeCoordinate ((double) parent->getHeight(), false); - } - - if (objectName.isNotEmpty() && edge.isNotEmpty()) - { - for (int i = components.size(); --i >= 0;) - { - ComponentPosition* c = components.getUnchecked(i); - - if (c->name == objectName) - { - if (edge == RelativeCoordinate::Strings::left) return c->coords.left; - if (edge == RelativeCoordinate::Strings::right) return c->coords.right; - if (edge == RelativeCoordinate::Strings::top) return c->coords.top; - if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom; - } - } - } - - for (int i = markers.size(); --i >= 0;) - { - MarkerPosition* m = markers.getUnchecked(i); - - if (m->markerName == objectName) - return m->position; - } - - return RelativeCoordinate(); -} - -void ComponentAutoLayoutManager::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) -{ - triggerAsyncUpdate(); - - if (parent == &component) - handleUpdateNowIfNeeded(); -} - -void ComponentAutoLayoutManager::componentBeingDeleted (Component& component) -{ - for (int i = components.size(); --i >= 0;) - { - ComponentPosition* c = components.getUnchecked(i); - if (c->component == &component) - { - components.remove (i); - break; - } - } -} - -void ComponentAutoLayoutManager::handleAsyncUpdate() -{ - applyLayout(); -} - -ComponentAutoLayoutManager::MarkerPosition::MarkerPosition (const String& name, const RelativeCoordinate& coord) - : markerName (name), position (coord) -{ -} - -ComponentAutoLayoutManager::ComponentPosition::ComponentPosition (Component* component_, const String& name_, const RelativeRectangle& coords_) - : component (component_), name (name_), coords (coords_) -{ -} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h b/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h deleted file mode 100644 index 654396d95d..0000000000 --- a/extras/Jucer (experimental)/Source/utility/jucer_Coordinate.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - ============================================================================== - - This file is part of the JUCE library - "Jules' Utility Class Extensions" - Copyright 2004-10 by Raw Material Software Ltd. - - ------------------------------------------------------------------------------ - - JUCE can be redistributed and/or modified under the terms of the GNU General - Public License (Version 2), as published by the Free Software Foundation. - A copy of the license is included in the JUCE distribution, or can be found - online at www.gnu.org/licenses. - - JUCE is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU General Public License for more details. - - ------------------------------------------------------------------------------ - - To release a closed-source product which uses JUCE, commercial licenses are - available: visit www.rawmaterialsoftware.com/juce for more information. - - ============================================================================== -*/ - -#ifndef __JUCER_COORDINATE_H_EF56ACFA__ -#define __JUCER_COORDINATE_H_EF56ACFA__ - -#include "../jucer_Headers.h" - - - -//============================================================================== -/** -*/ -class ComponentAutoLayoutManager : public ComponentListener, - public RelativeCoordinate::NamedCoordinateFinder, - public AsyncUpdater -{ -public: - //============================================================================== - /** - */ - ComponentAutoLayoutManager (Component* parentComponent); - - /** Destructor. */ - ~ComponentAutoLayoutManager(); - - //============================================================================== - /** - */ - void setMarker (const String& name, const RelativeCoordinate& coord); - - /** - */ - void setComponentBounds (Component* component, const String& componentName, const RelativeRectangle& bounds); - - /** - */ - void applyLayout(); - - //============================================================================== - /** @internal */ - const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; - /** @internal */ - void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); - /** @internal */ - void componentBeingDeleted (Component& component); - /** @internal */ - void handleAsyncUpdate(); - - juce_UseDebuggingNewOperator - -private: - //============================================================================== - struct ComponentPosition - { - ComponentPosition (Component* component, const String& name, const RelativeRectangle& coords); - - Component* component; - String name; - RelativeRectangle coords; - }; - - struct MarkerPosition - { - MarkerPosition (const String& name, const RelativeCoordinate& coord); - - String markerName; - RelativeCoordinate position; - }; - - Component* parent; - OwnedArray components; - OwnedArray markers; - - ComponentAutoLayoutManager (const ComponentAutoLayoutManager&); - ComponentAutoLayoutManager& operator= (const ComponentAutoLayoutManager&); -}; - - -#endif // __JUCER_COORDINATE_H_EF56ACFA__ diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h b/extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h index 908e5256ea..0f16124177 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_CoordinatePropertyComponent.h @@ -34,7 +34,7 @@ class CoordinatePropertyComponent : public PropertyComponent, { public: //============================================================================== - CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder& nameSource_, const String& name, + CoordinatePropertyComponent (RelativeCoordinate::NamedCoordinateFinder* nameSource_, const String& name, const Value& coordValue_, bool isHorizontal_) : PropertyComponent (name, 40), nameSource (nameSource_), coordValue (coordValue_), @@ -142,7 +142,7 @@ public: virtual const String pickMarker (TextButton* button, const String& currentMarker, bool isAnchor1) = 0; protected: - RelativeCoordinate::NamedCoordinateFinder& nameSource; + RelativeCoordinate::NamedCoordinateFinder* nameSource; Value coordValue, textValue; Label* label; TextButton* proportionButton; diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h index a772f27b0f..4017175234 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_MarkerListBase.h @@ -56,7 +56,7 @@ public: { ValueTree v (getMarker (i)); RelativeCoordinate coord (getCoordinate (v)); - coord.renameAnchorIfUsed (oldName, newName, *this); + coord.renameAnchorIfUsed (oldName, newName, this); setCoordinate (v, coord); } } @@ -133,7 +133,7 @@ public: { public: //============================================================================== - PositionPropertyComponent (NamedCoordinateFinder& nameSource_, MarkerListBase& markerList_, + PositionPropertyComponent (NamedCoordinateFinder* nameSource_, MarkerListBase& markerList_, const String& name, const ValueTree& markerState_, const Value& coordValue_) : CoordinatePropertyComponent (nameSource_, name, coordValue_, markerList_.isHorizontal()), diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp index 19c23cc1ab..b76d1ef0fd 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp +++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.cpp @@ -266,3 +266,143 @@ void FloatingLabelComponent::paint (Graphics& g) g.setColour (colour); glyphs.draw (g, AffineTransform::translation (1.0f, 1.0f)); } + +//============================================================================== +RelativeRectangleLayoutManager::RelativeRectangleLayoutManager (Component* parentComponent) + : parent (parentComponent) +{ + parent->addComponentListener (this); +} + +RelativeRectangleLayoutManager::~RelativeRectangleLayoutManager() +{ + parent->removeComponentListener (this); + + for (int i = components.size(); --i >= 0;) + components.getUnchecked(i)->component->removeComponentListener (this); +} + +void RelativeRectangleLayoutManager::setMarker (const String& name, const RelativeCoordinate& coord) +{ + for (int i = markers.size(); --i >= 0;) + { + MarkerPosition* m = markers.getUnchecked(i); + if (m->markerName == name) + { + m->position = coord; + applyLayout(); + return; + } + } + + markers.add (new MarkerPosition (name, coord)); + applyLayout(); +} + +void RelativeRectangleLayoutManager::setComponentBounds (Component* comp, const String& name, const RelativeRectangle& coords) +{ + jassert (comp != 0); + + // All the components that this layout manages must be inside the parent component.. + jassert (parent->isParentOf (comp)); + + for (int i = components.size(); --i >= 0;) + { + ComponentPosition* c = components.getUnchecked(i); + if (c->component == comp) + { + c->name = name; + c->coords = coords; + triggerAsyncUpdate(); + return; + } + } + + components.add (new ComponentPosition (comp, name, coords)); + comp->addComponentListener (this); + triggerAsyncUpdate(); +} + +void RelativeRectangleLayoutManager::applyLayout() +{ + for (int i = components.size(); --i >= 0;) + { + ComponentPosition* c = components.getUnchecked(i); + + // All the components that this layout manages must be inside the parent component.. + jassert (parent->isParentOf (c->component)); + + c->component->setBounds (c->coords.resolve (this).getSmallestIntegerContainer()); + } +} + +const RelativeCoordinate RelativeRectangleLayoutManager::findNamedCoordinate (const String& objectName, const String& edge) const +{ + if (objectName == RelativeCoordinate::Strings::parent) + { + if (edge == RelativeCoordinate::Strings::right) return RelativeCoordinate ((double) parent->getWidth(), true); + if (edge == RelativeCoordinate::Strings::bottom) return RelativeCoordinate ((double) parent->getHeight(), false); + } + + if (objectName.isNotEmpty() && edge.isNotEmpty()) + { + for (int i = components.size(); --i >= 0;) + { + ComponentPosition* c = components.getUnchecked(i); + + if (c->name == objectName) + { + if (edge == RelativeCoordinate::Strings::left) return c->coords.left; + if (edge == RelativeCoordinate::Strings::right) return c->coords.right; + if (edge == RelativeCoordinate::Strings::top) return c->coords.top; + if (edge == RelativeCoordinate::Strings::bottom) return c->coords.bottom; + } + } + } + + for (int i = markers.size(); --i >= 0;) + { + MarkerPosition* m = markers.getUnchecked(i); + + if (m->markerName == objectName) + return m->position; + } + + return RelativeCoordinate(); +} + +void RelativeRectangleLayoutManager::componentMovedOrResized (Component& component, bool wasMoved, bool wasResized) +{ + triggerAsyncUpdate(); + + if (parent == &component) + handleUpdateNowIfNeeded(); +} + +void RelativeRectangleLayoutManager::componentBeingDeleted (Component& component) +{ + for (int i = components.size(); --i >= 0;) + { + ComponentPosition* c = components.getUnchecked(i); + if (c->component == &component) + { + components.remove (i); + break; + } + } +} + +void RelativeRectangleLayoutManager::handleAsyncUpdate() +{ + applyLayout(); +} + +RelativeRectangleLayoutManager::MarkerPosition::MarkerPosition (const String& name, const RelativeCoordinate& coord) + : markerName (name), position (coord) +{ +} + +RelativeRectangleLayoutManager::ComponentPosition::ComponentPosition (Component* component_, const String& name_, const RelativeRectangle& coords_) + : component (component_), name (name_), coords (coords_) +{ +} diff --git a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h index b7a368af56..36595058cd 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h +++ b/extras/Jucer (experimental)/Source/utility/jucer_MiscUtilities.h @@ -136,3 +136,72 @@ private: JucerToolbarButton (const JucerToolbarButton&); JucerToolbarButton& operator= (const JucerToolbarButton&); }; + + +//============================================================================== +/** +*/ +class RelativeRectangleLayoutManager : public ComponentListener, + public RelativeCoordinate::NamedCoordinateFinder, + public AsyncUpdater +{ +public: + //============================================================================== + /** + */ + RelativeRectangleLayoutManager (Component* parentComponent); + + /** Destructor. */ + ~RelativeRectangleLayoutManager(); + + //============================================================================== + /** + */ + void setMarker (const String& name, const RelativeCoordinate& coord); + + /** + */ + void setComponentBounds (Component* component, const String& componentName, const RelativeRectangle& bounds); + + /** + */ + void applyLayout(); + + //============================================================================== + /** @internal */ + const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; + /** @internal */ + void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized); + /** @internal */ + void componentBeingDeleted (Component& component); + /** @internal */ + void handleAsyncUpdate(); + + juce_UseDebuggingNewOperator + +private: + //============================================================================== + struct ComponentPosition + { + ComponentPosition (Component* component, const String& name, const RelativeRectangle& coords); + + Component* component; + String name; + RelativeRectangle coords; + }; + + struct MarkerPosition + { + MarkerPosition (const String& name, const RelativeCoordinate& coord); + + String markerName; + RelativeCoordinate position; + }; + + Component* parent; + OwnedArray components; + OwnedArray markers; + + RelativeRectangleLayoutManager (const RelativeRectangleLayoutManager&); + RelativeRectangleLayoutManager& operator= (const RelativeRectangleLayoutManager&); +}; diff --git a/extras/amalgamator/Builds/Linux/Makefile b/extras/amalgamator/Builds/Linux/Makefile index ee24beb5bd..5b4dbffcfc 100644 --- a/extras/amalgamator/Builds/Linux/Makefile +++ b/extras/amalgamator/Builds/Linux/Makefile @@ -63,12 +63,12 @@ clean: $(OBJDIR)/Main.o: ../../Source/Main.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling Main.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/audio plugin host/Builds/Linux/Makefile b/extras/audio plugin host/Builds/Linux/Makefile index 7a5e0ddbe9..7f234793be 100644 --- a/extras/audio plugin host/Builds/Linux/Makefile +++ b/extras/audio plugin host/Builds/Linux/Makefile @@ -70,47 +70,47 @@ clean: $(OBJDIR)/FilterGraph.o: ../../Source/FilterGraph.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling FilterGraph.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/GraphEditorPanel.o: ../../Source/GraphEditorPanel.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling GraphEditorPanel.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/HostStartup.o: ../../Source/HostStartup.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling HostStartup.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/InternalFilters.o: ../../Source/InternalFilters.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling InternalFilters.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/MainHostWindow.o: ../../Source/MainHostWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling MainHostWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode1.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode2.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode3.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode4.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/binarybuilder/Builds/Linux/Makefile b/extras/binarybuilder/Builds/Linux/Makefile index c3aa2fe4ee..cd9e0a1437 100644 --- a/extras/binarybuilder/Builds/Linux/Makefile +++ b/extras/binarybuilder/Builds/Linux/Makefile @@ -63,12 +63,12 @@ clean: $(OBJDIR)/Main.o: ../../Source/Main.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling Main.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode.o: ../../JuceLibraryCode/JuceLibraryCode.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/example projects/Builds/Linux/Makefile b/extras/example projects/Builds/Linux/Makefile index 4b48c5b328..42ce95afa9 100644 --- a/extras/example projects/Builds/Linux/Makefile +++ b/extras/example projects/Builds/Linux/Makefile @@ -67,32 +67,32 @@ clean: $(OBJDIR)/Main.o: ../../Source/Main.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling Main.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/MainComponent.o: ../../Source/MainComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling MainComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode1.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode2.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode3.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode4.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/extras/juce demo/Builds/Linux/Makefile b/extras/juce demo/Builds/Linux/Makefile index 6c44f3a40e..cd5c46ed29 100644 --- a/extras/juce demo/Builds/Linux/Makefile +++ b/extras/juce demo/Builds/Linux/Makefile @@ -87,132 +87,132 @@ clean: $(OBJDIR)/ApplicationStartup.o: ../../Source/ApplicationStartup.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling ApplicationStartup.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/MainDemoWindow.o: ../../Source/MainDemoWindow.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling MainDemoWindow.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoLatencyPage.o: ../../Source/demos/AudioDemoLatencyPage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoLatencyPage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoPlaybackPage.o: ../../Source/demos/AudioDemoPlaybackPage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoPlaybackPage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoRecordPage.o: ../../Source/demos/AudioDemoRecordPage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoRecordPage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoSetupPage.o: ../../Source/demos/AudioDemoSetupPage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoSetupPage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoSynthPage.o: ../../Source/demos/AudioDemoSynthPage.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoSynthPage.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/AudioDemoTabComponent.o: ../../Source/demos/AudioDemoTabComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling AudioDemoTabComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/CameraDemo.o: ../../Source/demos/CameraDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling CameraDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/CodeEditorDemo.o: ../../Source/demos/CodeEditorDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling CodeEditorDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/DragAndDropDemo.o: ../../Source/demos/DragAndDropDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling DragAndDropDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/FontsAndTextDemo.o: ../../Source/demos/FontsAndTextDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling FontsAndTextDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/InterprocessCommsDemo.o: ../../Source/demos/InterprocessCommsDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling InterprocessCommsDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/OpenGLDemo.o: ../../Source/demos/OpenGLDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling OpenGLDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/QuickTimeDemo.o: ../../Source/demos/QuickTimeDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling QuickTimeDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/RenderingTestComponent.o: ../../Source/demos/RenderingTestComponent.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling RenderingTestComponent.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/TableDemo.o: ../../Source/demos/TableDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling TableDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/ThreadingDemo.o: ../../Source/demos/ThreadingDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling ThreadingDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/TreeViewDemo.o: ../../Source/demos/TreeViewDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling TreeViewDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/WebBrowserDemo.o: ../../Source/demos/WebBrowserDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling WebBrowserDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/WidgetsDemo.o: ../../Source/demos/WidgetsDemo.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling WidgetsDemo.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/BinaryData.o: ../../JuceLibraryCode/BinaryData.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling BinaryData.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode1.o: ../../JuceLibraryCode/JuceLibraryCode1.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode1.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode2.o: ../../JuceLibraryCode/JuceLibraryCode2.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode2.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode3.o: ../../JuceLibraryCode/JuceLibraryCode3.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode3.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" $(OBJDIR)/JuceLibraryCode4.o: ../../JuceLibraryCode/JuceLibraryCode4.cpp -@mkdir -p $(OBJDIR) - @echo $(notdir $<) + @echo "Compiling JuceLibraryCode4.cpp" @$(CXX) $(CXXFLAGS) -o "$@" -c "$<" -include $(OBJECTS:%.o=%.d) diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index bc65eb880d..72108f5ac1 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -4264,6 +4264,11 @@ inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var { } +bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const throw() +{ + return name == other.name && value == other.value; +} + NamedValueSet::NamedValueSet() throw() { } @@ -4283,6 +4288,16 @@ NamedValueSet::~NamedValueSet() { } +bool NamedValueSet::operator== (const NamedValueSet& other) const +{ + return values == other.values; +} + +bool NamedValueSet::operator!= (const NamedValueSet& other) const +{ + return ! operator== (other); +} + int NamedValueSet::size() const throw() { return values.size(); @@ -5821,7 +5836,7 @@ DirectoryIterator::DirectoryIterator (const File& directory, bool isRecursive_, const String& wildCard_, const int whatToLookFor_) - : fileFinder (directory, isRecursive ? "*" : wildCard_), + : fileFinder (directory, isRecursive_ ? "*" : wildCard_), wildCard (wildCard_), path (File::addTrailingSeparator (directory.getFullPathName())), index (-1), @@ -11304,9 +11319,7 @@ static int indexOfMatch (const juce_wchar* const wildcard, else { if (wc == '*' && (wildcard [i + 1] == 0 - || indexOfMatch (wildcard + i + 1, - test + start + i, - ignoreCase) >= 0)) + || indexOfMatch (wildcard + i + 1, test + start + i, ignoreCase) >= 0)) { return start; } @@ -11342,9 +11355,7 @@ bool String::matchesWildcard (const String& wildcard, const bool ignoreCase) con else { return wc == '*' && (wildcard [i + 1] == 0 - || indexOfMatch (wildcard.text + i + 1, - text + i, - ignoreCase) >= 0); + || indexOfMatch (wildcard.text + i + 1, text + i, ignoreCase) >= 0); } } } @@ -16425,6 +16436,21 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan } } +bool ValueTree::SharedObject::isEquivalentTo (const SharedObject& other) const +{ + if (type != other.type + || properties.size() != other.properties.size() + || children.size() != other.children.size() + || properties != other.properties) + return false; + + for (int i = 0; i < children.size(); ++i) + if (! children.getUnchecked(i)->isEquivalentTo (*other.children.getUnchecked(i))) + return false; + + return true; +} + ValueTree::ValueTree() throw() : object (0) { @@ -16470,16 +16496,22 @@ ValueTree::~ValueTree() object->valueTreesWithListeners.removeValue (this); } -bool ValueTree::operator== (const ValueTree& other) const +bool ValueTree::operator== (const ValueTree& other) const throw() { return object == other.object; } -bool ValueTree::operator!= (const ValueTree& other) const +bool ValueTree::operator!= (const ValueTree& other) const throw() { return object != other.object; } +bool ValueTree::isEquivalentTo (const ValueTree& other) const +{ + return object == other.object + || (object != 0 && other.object != 0 && object->isEquivalentTo (*other.object)); +} + ValueTree ValueTree::createCopy() const { return ValueTree (object != 0 ? new SharedObject (*object) : 0); @@ -16632,7 +16664,7 @@ int ValueTree::indexOf (const ValueTree& child) const return object != 0 ? object->indexOf (child) : -1; } -void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) +void ValueTree::addChild (const ValueTree& child, int index, UndoManager* const undoManager) { if (object != 0) object->addChild (child.object, index, undoManager); @@ -39924,6 +39956,11 @@ void Component::repaint (const int x, const int y, internalRepaint (x, y, w, h); } +void Component::repaint (const Rectangle& area) +{ + repaint (area.getX(), area.getY(), area.getWidth(), area.getHeight()); +} + void Component::internalRepaint (int x, int y, int w, int h) { // if component methods are being called from threads other than the message @@ -39965,7 +40002,7 @@ void Component::internalRepaint (int x, int y, int w, int h) ComponentPeer* const peer = getPeer(); if (peer != 0) - peer->repaint (x, y, w, h); + peer->repaint (Rectangle (x, y, w, h)); } } } @@ -47969,8 +48006,7 @@ void ListBox::setHeaderComponent (Component* const newHeaderComponent) void ListBox::repaintRow (const int rowNumber) throw() { - const Rectangle r (getRowPosition (rowNumber, true)); - repaint (r.getX(), r.getY(), r.getWidth(), r.getHeight()); + repaint (getRowPosition (rowNumber, true)); } Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) @@ -56028,8 +56064,9 @@ void TreeViewItem::repaintItem() const { if (ownerView != 0 && areAllParentsOpen()) { - const Rectangle r (getItemPosition (true)); - ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight()); + Rectangle r (getItemPosition (true)); + r.setLeft (0); + ownerView->viewport->repaint (r); } } @@ -74004,14 +74041,14 @@ public: && ((unsigned int) position.getY()) < (unsigned int) magnifierComp->getHeight(); } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { const double zoom = magnifierComp->getScaleFactor(); - magnifierComp->repaint ((int) (x * zoom), - (int) (y * zoom), - roundToInt (w * zoom) + 1, - roundToInt (h * zoom) + 1); + magnifierComp->repaint ((int) (area.getX() * zoom), + (int) (area.getY() * zoom), + roundToInt (area.getWidth() * zoom) + 1, + roundToInt (area.getHeight() * zoom) + 1); } void performAnyPendingRepaintsNow() @@ -76849,9 +76886,7 @@ DocumentWindow::~DocumentWindow() void DocumentWindow::repaintTitleBar() { - const Rectangle titleBarArea (getTitleBarArea()); - repaint (titleBarArea.getX(), titleBarArea.getY(), - titleBarArea.getWidth(), titleBarArea.getHeight()); + repaint (getTitleBarArea()); } void DocumentWindow::setName (const String& newName) @@ -80080,6 +80115,16 @@ FillType::~FillType() throw() { } +bool FillType::operator== (const FillType& other) const +{ + return colour == other.colour && gradient == other.gradient && image == other.image; +} + +bool FillType::operator!= (const FillType& other) const +{ + return ! operator== (other); +} + void FillType::setColour (const Colour& newColour) throw() { gradient = 0; @@ -80114,6 +80159,11 @@ void FillType::setOpacity (const float newOpacity) throw() colour = colour.withAlpha (newOpacity); } +bool FillType::isInvisible() const throw() +{ + return colour.isTransparent() || (gradient != 0 && gradient->isInvisible()); +} + END_JUCE_NAMESPACE /*** End of inlined file: juce_FillType.cpp ***/ @@ -83168,41 +83218,38 @@ public: shapeToFill = clip->applyClipTo (shapeToFill); if (shapeToFill != 0) - fillShapeWithoutClipping (image, shapeToFill, replaceContents); - } + { + Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); - void fillShapeWithoutClipping (Image& image, const SoftwareRendererClasses::ClipRegionBase::Ptr& shapeToFill, const bool replaceContents) - { - Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); + if (fillType.isGradient()) + { + jassert (! replaceContents); // that option is just for solid colours - if (fillType.isGradient()) - { - jassert (! replaceContents); // that option is just for solid colours + ColourGradient g2 (*(fillType.gradient)); + g2.multiplyOpacity (fillType.getOpacity()); + g2.point1.addXY (-0.5f, -0.5f); + g2.point2.addXY (-0.5f, -0.5f); + AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); + const bool isIdentity = transform.isOnlyTranslation(); - ColourGradient g2 (*(fillType.gradient)); - g2.multiplyOpacity (fillType.getOpacity()); - g2.point1.addXY (-0.5f, -0.5f); - g2.point2.addXY (-0.5f, -0.5f); - AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); - const bool isIdentity = transform.isOnlyTranslation(); + if (isIdentity) + { + // If our translation doesn't involve any distortion, we can speed it up.. + g2.point1.applyTransform (transform); + g2.point2.applyTransform (transform); + transform = AffineTransform::identity; + } - if (isIdentity) + shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); + } + else if (fillType.isTiledImage()) { - // If our translation doesn't involve any distortion, we can speed it up.. - g2.point1.applyTransform (transform); - g2.point2.applyTransform (transform); - transform = AffineTransform::identity; + renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); + } + else + { + shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); } - - shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); - } - else if (fillType.isTiledImage()) - { - renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); - } - else - { - shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); } } @@ -83690,8 +83737,6 @@ END_JUCE_NAMESPACE /*** Start of inlined file: juce_Drawable.cpp ***/ BEGIN_JUCE_NAMESPACE -const Identifier Drawable::idProperty ("id"); - Drawable::RenderingContext::RenderingContext (Graphics& g_, const AffineTransform& transform_, const float opacity_) throw() @@ -83702,6 +83747,7 @@ Drawable::RenderingContext::RenderingContext (Graphics& g_, } Drawable::Drawable() + : parent (0) { } @@ -83709,8 +83755,7 @@ Drawable::~Drawable() { } -void Drawable::draw (Graphics& g, const float opacity, - const AffineTransform& transform) const +void Drawable::draw (Graphics& g, const float opacity, const AffineTransform& transform) const { render (RenderingContext (g, transform, opacity)); } @@ -83805,6 +83850,131 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ImageProvider* i return d; } +const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); +const Identifier Drawable::ValueTreeWrapperBase::type ("type"); +const Identifier Drawable::ValueTreeWrapperBase::x1 ("x1"); +const Identifier Drawable::ValueTreeWrapperBase::x2 ("x2"); +const Identifier Drawable::ValueTreeWrapperBase::y1 ("y1"); +const Identifier Drawable::ValueTreeWrapperBase::y2 ("y2"); +const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); +const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); +const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); + +Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) + : state (state_) +{ +} + +Drawable::ValueTreeWrapperBase::~ValueTreeWrapperBase() +{ +} + +const String Drawable::ValueTreeWrapperBase::getID() const +{ + return state [idProperty]; +} + +void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* undoManager) +{ + if (newID.isEmpty()) + state.removeProperty (idProperty, undoManager); + else + state.setProperty (idProperty, newID, undoManager); +} + +const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v) +{ + const String newType (v[type].toString()); + + if (newType == "solid") + { + const String colourString (v [colour].toString()); + return FillType (Colour (colourString.isEmpty() ? (uint32) 0xff000000 + : (uint32) colourString.getHexValue32())); + } + else if (newType == "gradient") + { + ColourGradient g; + g.point1.setXY (v[x1], v[y1]); + g.point2.setXY (v[x2], v[y2]); + g.isRadial = v[radial]; + + StringArray colourSteps; + colourSteps.addTokens (v[colours].toString(), false); + + for (int i = 0; i < colourSteps.size() / 2; ++i) + g.addColour (colourSteps[i * 2].getDoubleValue(), + Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); + + return FillType (g); + } + else if (newType == "image") + { + jassertfalse; //xxx todo + } + + jassertfalse; + return FillType(); +} + +void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager) +{ + ValueTree v (state.getChildWithName (tag)); + + if (! v.isValid()) + { + state.addChild (ValueTree (tag), -1, undoManager); + v = state.getChildWithName (tag); + } + + if (fillType.isColour()) + { + v.setProperty (type, "solid", undoManager); + v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); + v.removeProperty (x1, undoManager); + v.removeProperty (x2, undoManager); + v.removeProperty (y1, undoManager); + v.removeProperty (y2, undoManager); + v.removeProperty (radial, undoManager); + v.removeProperty (colours, undoManager); + } + else if (fillType.isGradient()) + { + v.setProperty (type, "gradient", undoManager); + v.setProperty (x1, fillType.gradient->point1.getX(), undoManager); + v.setProperty (y1, fillType.gradient->point1.getY(), undoManager); + v.setProperty (x2, fillType.gradient->point2.getX(), undoManager); + v.setProperty (y2, fillType.gradient->point2.getY(), undoManager); + v.setProperty (radial, fillType.gradient->isRadial, undoManager); + + String s; + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) + s << " " << fillType.gradient->getColourPosition (i) + << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); + + v.setProperty (colours, s.trimStart(), undoManager); + v.removeProperty (colour, undoManager); + } + else if (fillType.isTiledImage()) + { + v.setProperty (type, "image", undoManager); + + jassertfalse; //xxx todo + + v.removeProperty (x1, undoManager); + v.removeProperty (x2, undoManager); + v.removeProperty (y1, undoManager); + v.removeProperty (y2, undoManager); + v.removeProperty (radial, undoManager); + v.removeProperty (colours, undoManager); + v.removeProperty (colour, undoManager); + } + else + { + jassertfalse; + } +} + END_JUCE_NAMESPACE /*** End of inlined file: juce_Drawable.cpp ***/ @@ -83814,8 +83984,21 @@ BEGIN_JUCE_NAMESPACE DrawableComposite::DrawableComposite() { - controlPoints[1].setXY (1.0f, 0.0f); - controlPoints[2].setXY (0.0f, 1.0f); + controlPoints[1] = RelativePoint (Point (1.0f, 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, 1.0f)); +} + +DrawableComposite::DrawableComposite (const DrawableComposite& other) +{ + int i; + for (i = 0; i < 3; ++i) + controlPoints[i] = other.controlPoints[i]; + + for (i = 0; i < drawables.size(); ++i) + drawables.add (other.drawables.getUnchecked(i)->createCopy()); + + for (i = 0; i < markers.size(); ++i) + markers.add (new Marker (*other.markers.getUnchecked(i))); } DrawableComposite::~DrawableComposite() @@ -83827,7 +84010,9 @@ void DrawableComposite::insertDrawable (Drawable* drawable, const int index) if (drawable != 0) { jassert (! drawables.contains (drawable)); // trying to add a drawable that's already in here! + jassert (drawable->parent == 0); // A drawable can only live inside one parent at a time! drawables.insert (index, drawable); + drawable->parent = this; } } @@ -83847,20 +84032,77 @@ void DrawableComposite::bringToFront (const int index) drawables.move (index, -1); } -void DrawableComposite::setTransform (const Point& targetPositionForOrigin, - const Point& targetPositionForX1Y0, - const Point& targetPositionForX0Y1) +void DrawableComposite::setTransform (const RelativePoint& targetPositionForOrigin, + const RelativePoint& targetPositionForX1Y0, + const RelativePoint& targetPositionForX0Y1) { controlPoints[0] = targetPositionForOrigin; controlPoints[1] = targetPositionForX1Y0; controlPoints[2] = targetPositionForX0Y1; } -const AffineTransform DrawableComposite::getTransform() const +DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) + : name (other.name), position (other.position), isOnXAxis (other.isOnXAxis) { - return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), - controlPoints[1].getX(), controlPoints[1].getY(), - controlPoints[2].getX(), controlPoints[2].getY()); +} + +DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_, const bool isOnXAxis_) + : name (name_), position (position_), isOnXAxis (isOnXAxis_) +{ +} + +bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() +{ + return name != other.name || position != other.position || isOnXAxis != other.isOnXAxis; +} + +int DrawableComposite::getNumMarkers (bool xAxis) const throw() +{ + return markers.size(); +} + +const DrawableComposite::Marker* DrawableComposite::getMarker (int index) const throw() +{ + return markers [index]; +} + +void DrawableComposite::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position) +{ + for (int i = 0; i < markers.size(); ++i) + { + Marker* const m = markers.getUnchecked(i); + if (m->name == name) + { + jassert (m->isOnXAxis == xAxis); // trying to either have two markers with the same name on different axes? + + if (m->position != position) + { + m->position = position; + invalidatePoints(); + } + + return; + } + } + + markers.add (new Marker (name, position, xAxis)); + invalidatePoints(); +} + +void DrawableComposite::removeMarker (int index) +{ + markers.remove (index); +} + +const AffineTransform DrawableComposite::calculateTransform() const +{ + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); + + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), + resolved[1].getX(), resolved[1].getY(), + resolved[2].getX(), resolved[2].getY()); } void DrawableComposite::render (const Drawable::RenderingContext& context) const @@ -83870,7 +84112,7 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const if (context.opacity >= 1.0f || drawables.size() == 1) { Drawable::RenderingContext contextCopy (context); - contextCopy.transform = getTransform().followedBy (context.transform); + contextCopy.transform = calculateTransform().followedBy (context.transform); for (int i = 0; i < drawables.size(); ++i) drawables.getUnchecked(i)->render (contextCopy); @@ -83896,6 +84138,33 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const } } +const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& objectName, const String& edge) const +{ + if (objectName == RelativeCoordinate::Strings::parent) + { + if (edge == RelativeCoordinate::Strings::right) + { + jassertfalse; // a Drawable doesn't have a fixed right-hand edge - use a marker instead if you need a point of reference. + return RelativeCoordinate (100.0, true); + } + + if (edge == RelativeCoordinate::Strings::bottom) + { + jassertfalse; // a Drawable doesn't have a fixed bottom edge - use a marker instead if you need a point of reference. + return RelativeCoordinate (100.0, false); + } + } + + for (int i = 0; i < markers.size(); ++i) + { + Marker* const m = markers.getUnchecked(i); + if (m->name == objectName) + return m->position; + } + + return RelativeCoordinate(); +} + const Rectangle DrawableComposite::getUntransformedBounds() const { Rectangle bounds; @@ -83908,12 +84177,12 @@ const Rectangle DrawableComposite::getUntransformedBounds() const const Rectangle DrawableComposite::getBounds() const { - return getUntransformedBounds().transformed (getTransform()); + return getUntransformedBounds().transformed (calculateTransform()); } bool DrawableComposite::hitTest (float x, float y) const { - getTransform().inverted().transformPoint (x, y); + calculateTransform().inverted().transformPoint (x, y); for (int i = 0; i < drawables.size(); ++i) if (drawables.getUnchecked(i)->hitTest (x, y)) @@ -83924,124 +84193,279 @@ bool DrawableComposite::hitTest (float x, float y) const Drawable* DrawableComposite::createCopy() const { - DrawableComposite* const dc = new DrawableComposite(); - - for (int i = 0; i < 3; ++i) - dc->controlPoints[i] = controlPoints[i]; + return new DrawableComposite (*this); +} +void DrawableComposite::invalidatePoints() +{ for (int i = 0; i < drawables.size(); ++i) - dc->drawables.add (drawables.getUnchecked(i)->createCopy()); - - return dc; + drawables.getUnchecked(i)->invalidatePoints(); } const Identifier DrawableComposite::valueTreeType ("Group"); -namespace DrawableCompositeHelpers +const Identifier DrawableComposite::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableComposite::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft"); +const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables"); +const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTag ("Markers"); +const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker"); +const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name"); +const Identifier DrawableComposite::ValueTreeWrapper::xAxisProperty ("xAxis"); +const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position"); + +DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) { - static const Identifier topLeft ("topLeft"); - static const Identifier topRight ("topRight"); - static const Identifier bottomLeft ("bottomLeft"); + jassert (state.hasType (valueTreeType)); +} - static void stringToPoint (const String& coords, Point& point) +ValueTree DrawableComposite::ValueTreeWrapper::getChildList() const +{ + return state.getChildWithName (childGroupTag); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager* undoManager) +{ + const ValueTree childList (getChildList()); + if (childList.isValid()) + return childList; + + state.addChild (ValueTree (childGroupTag), 0, undoManager); + return getChildList(); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList() const +{ + return state.getChildWithName (markerGroupTag); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (UndoManager* undoManager) +{ + const ValueTree markerList (getMarkerList()); + if (markerList.isValid()) + return markerList; + + state.addChild (ValueTree (markerGroupTag), -1, undoManager); + return getMarkerList(); +} + +int DrawableComposite::ValueTreeWrapper::getNumDrawables() const +{ + return getChildList().getNumChildren(); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getDrawableState (int index) const +{ + return getChildList().getChild (index); +} + +void DrawableComposite::ValueTreeWrapper::addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager) +{ + getChildListCreating (undoManager).addChild (newDrawableState, index, undoManager); +} + +void DrawableComposite::ValueTreeWrapper::moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager) +{ + getChildListCreating (undoManager).moveChild (currentIndex, newIndex, undoManager); +} + +void DrawableComposite::ValueTreeWrapper::removeDrawable (int index, UndoManager* undoManager) +{ + getChildList().removeChild (index, undoManager); +} + +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForOrigin() const +{ + const String pos (state [topLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topLeft, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX1Y0() const +{ + const String pos (state [topRight].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (1.0f, 0.0f)); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topRight, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX0Y1() const +{ + const String pos (state [bottomLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (0.0f, 1.0f)); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (bottomLeft, newPoint.toString(), undoManager); +} + +int DrawableComposite::ValueTreeWrapper::getNumMarkers() const +{ + return getMarkerList().getNumChildren(); +} + +const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (int index) const +{ + const ValueTree marker (getMarkerList().getChild (index)); + const bool isXAxis = marker [xAxisProperty]; + + return Marker (marker [nameProperty], + RelativeCoordinate (marker [posProperty].toString(), isXAxis), + isXAxis); +} + +void DrawableComposite::ValueTreeWrapper::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager) +{ + ValueTree markerList (getMarkerListCreating (undoManager)); + ValueTree marker (markerList.getChildWithProperty (nameProperty, name)); + + if (marker.isValid()) { - if (coords.isNotEmpty()) - { - const int comma = coords.indexOfChar (','); - point.setXY (coords.substring (0, comma).getFloatValue(), - coords.substring (comma + 1).getFloatValue()); - } + jassert ((bool) marker [xAxisProperty] == xAxis); // shouldn't change the axis of a marker after it has been created! + marker.setProperty (posProperty, position.toString(), undoManager); } - - static const var pointToString (const Point& point) + else { - return String (point.getX()) + ", " + String (point.getY()); + marker = ValueTree (markerTag); + marker.setProperty (nameProperty, name, 0); + marker.setProperty (xAxisProperty, xAxis, 0); + marker.setProperty (posProperty, position.toString(), 0); + markerList.addChild (marker, -1, undoManager); } } -const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableComposite::ValueTreeWrapper::removeMarker (int index, UndoManager* undoManager) { - jassert (tree.hasType (valueTreeType)); + return getMarkerList().removeChild (index, undoManager); +} +const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ Rectangle damageRect; + const ValueTreeWrapper controller (tree); + setName (controller.getID()); - setName (tree [idProperty]); + RelativePoint newControlPoint[3] = { controller.getTargetPositionForOrigin(), + controller.getTargetPositionForX1Y0(), + controller.getTargetPositionForX0Y1() }; - Point newControlPoint[3]; - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topLeft].toString(), newControlPoint[0]); - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topRight].toString(), newControlPoint[1]); - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::bottomLeft].toString(), newControlPoint[2]); - bool controlPointsChanged = false; + bool redrawAll = false; if (controlPoints[0] != newControlPoint[0] || controlPoints[1] != newControlPoint[1] || controlPoints[2] != newControlPoint[2]) { - controlPointsChanged = true; + redrawAll = true; damageRect = getUntransformedBounds(); controlPoints[0] = newControlPoint[0]; controlPoints[1] = newControlPoint[1]; controlPoints[2] = newControlPoint[2]; } + // Remove deleted markers... int i; - for (i = drawables.size(); --i >= tree.getNumChildren();) + for (i = markers.size(); --i >= controller.getNumMarkers();) + { + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + removeMarker (i); + } + + // Update markers and add new ones.. + for (i = 0; i < controller.getNumMarkers(); ++i) + { + const Marker newMarker (controller.getMarker (i)); + Marker* m = markers[i]; + + if (m == 0 || newMarker != *m) + { + redrawAll = true; + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + if (m == 0) + markers.add (new Marker (newMarker)); + else + *m = newMarker; + } + } + + // Remove deleted drawables.. + for (i = drawables.size(); --i >= controller.getNumDrawables();) { - damageRect = damageRect.getUnion (drawables.getUnchecked(i)->getBounds()); + Drawable* const d = drawables.getUnchecked(i); + damageRect = damageRect.getUnion (d->getBounds()); + d->parent = 0; drawables.remove (i); } - for (int i = 0; i < tree.getNumChildren(); ++i) + // Update drawables and add new ones.. + for (i = 0; i < controller.getNumDrawables(); ++i) { - const ValueTree childTree (tree.getChild (i)); + const ValueTree newDrawable (controller.getDrawableState (i)); Drawable* d = drawables[i]; if (d != 0) { - if (childTree.hasType (d->getValueTreeType())) + if (newDrawable.hasType (d->getValueTreeType())) { - damageRect = damageRect.getUnion (d->refreshFromValueTree (childTree, imageProvider)); + damageRect = damageRect.getUnion (d->refreshFromValueTree (newDrawable, imageProvider)); } else { damageRect = damageRect.getUnion (d->getBounds()); - d = createFromValueTree (childTree, imageProvider); + d = createFromValueTree (newDrawable, imageProvider); + d->parent = this; drawables.set (i, d); damageRect = damageRect.getUnion (d->getBounds()); } } else { - d = createFromValueTree (childTree, imageProvider); + d = createFromValueTree (newDrawable, imageProvider); + d->parent = this; drawables.set (i, d); damageRect = damageRect.getUnion (d->getBounds()); } } - if (controlPointsChanged) + if (redrawAll) damageRect = damageRect.getUnion (getUntransformedBounds()); - return damageRect.transformed (getTransform()); + return damageRect.transformed (calculateTransform()); } const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); + + v.setID (getName(), 0); + v.setTargetPositionForOrigin (controlPoints[0], 0); + v.setTargetPositionForX1Y0 (controlPoints[1], 0); + v.setTargetPositionForX0Y1 (controlPoints[2], 0); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + int i; + for (i = 0; i < drawables.size(); ++i) + v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); - if (! getTransform().isIdentity()) + for (i = 0; i < markers.size(); ++i) { - v.setProperty (DrawableCompositeHelpers::topLeft, DrawableCompositeHelpers::pointToString (controlPoints[0]), 0); - v.setProperty (DrawableCompositeHelpers::topRight, DrawableCompositeHelpers::pointToString (controlPoints[1]), 0); - v.setProperty (DrawableCompositeHelpers::bottomLeft, DrawableCompositeHelpers::pointToString (controlPoints[2]), 0); + const Marker* m = markers.getUnchecked(i); + v.setMarker (m->name, m->isOnXAxis, m->position, 0); } - for (int i = 0; i < drawables.size(); ++i) - v.addChild (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); - - return v; + return tree; } END_JUCE_NAMESPACE @@ -84057,46 +84481,57 @@ DrawableImage::DrawableImage() opacity (1.0f), overlayColour (0x00000000) { - controlPoints[1].setXY (1.0f, 0.0f); - controlPoints[2].setXY (0.0f, 1.0f); + controlPoints[1] = RelativePoint (Point (1.0f, 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, 1.0f)); } -DrawableImage::~DrawableImage() +DrawableImage::DrawableImage (const DrawableImage& other) + : image (0), + canDeleteImage (false), + opacity (other.opacity), + overlayColour (other.overlayColour) { - clearImage(); + for (int i = 0; i < numElementsInArray (controlPoints); ++i) + controlPoints[i] = other.controlPoints[i]; + + if (other.image != 0) + { + if ((! other.canDeleteImage) || ! ImageCache::isImageInCache (other.image)) + { + setImage (*other.image); + } + else + { + ImageCache::incReferenceCount (other.image); + setImage (other.image, true); + } + } } -void DrawableImage::clearImage() +DrawableImage::~DrawableImage() { - if (canDeleteImage && image != 0) - ImageCache::releaseOrDelete (image); - - image = 0; + setImage (0, false); } void DrawableImage::setImage (const Image& imageToCopy) { - clearImage(); - image = new Image (imageToCopy); - canDeleteImage = true; - - controlPoints[0].setXY (0.0f, 0.0f); - controlPoints[1].setXY ((float) image->getWidth(), 0.0f); - controlPoints[2].setXY (0.0f, (float) image->getHeight()); + setImage (new Image (imageToCopy), true); } void DrawableImage::setImage (Image* imageToUse, const bool releaseWhenNotNeeded) { - clearImage(); + if (canDeleteImage) + ImageCache::releaseOrDelete (image); + image = imageToUse; canDeleteImage = releaseWhenNotNeeded; if (image != 0) { - controlPoints[0].setXY (0.0f, 0.0f); - controlPoints[1].setXY ((float) image->getWidth(), 0.0f); - controlPoints[2].setXY (0.0f, (float) image->getHeight()); + controlPoints[0] = RelativePoint (Point (0.0f, 0.0f)); + controlPoints[1] = RelativePoint (Point ((float) image->getWidth(), 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, (float) image->getHeight())); } } @@ -84110,24 +84545,28 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) overlayColour = newOverlayColour; } -void DrawableImage::setTransform (const Point& imageTopLeftPosition, - const Point& imageTopRightPosition, - const Point& imageBottomLeftPosition) +void DrawableImage::setTransform (const RelativePoint& imageTopLeftPosition, + const RelativePoint& imageTopRightPosition, + const RelativePoint& imageBottomLeftPosition) { controlPoints[0] = imageTopLeftPosition; controlPoints[1] = imageTopRightPosition; controlPoints[2] = imageBottomLeftPosition; } -const AffineTransform DrawableImage::getTransform() const +const AffineTransform DrawableImage::calculateTransform() const { if (image == 0) return AffineTransform::identity; - const Point tr (controlPoints[0] + (controlPoints[1] - controlPoints[0]) / (float) image->getWidth()); - const Point bl (controlPoints[0] + (controlPoints[2] - controlPoints[0]) / (float) image->getHeight()); + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); + + const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image->getWidth()); + const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image->getHeight()); - return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), tr.getX(), tr.getY(), bl.getX(), bl.getY()); } @@ -84136,7 +84575,7 @@ void DrawableImage::render (const Drawable::RenderingContext& context) const { if (image != 0) { - const AffineTransform t (getTransform().followedBy (context.transform)); + const AffineTransform t (calculateTransform().followedBy (context.transform)); if (opacity > 0.0f && ! overlayColour.isOpaque()) { @@ -84157,7 +84596,11 @@ const Rectangle DrawableImage::getBounds() const if (image == 0) return Rectangle(); - const Point bottomRight (controlPoints[1] + (controlPoints[2] - controlPoints[0])); + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); + + const Point bottomRight (resolved[1] + (resolved[2] - resolved[0])); float minX = bottomRight.getX(); float maxX = minX; float minY = bottomRight.getY(); @@ -84165,10 +84608,10 @@ const Rectangle DrawableImage::getBounds() const for (int i = 0; i < 3; ++i) { - minX = jmin (minX, controlPoints[i].getX()); - maxX = jmax (maxX, controlPoints[i].getX()); - minY = jmin (minY, controlPoints[i].getY()); - maxY = jmax (maxY, controlPoints[i].getY()); + minX = jmin (minX, resolved[i].getX()); + maxX = jmax (maxX, resolved[i].getX()); + minY = jmin (minY, resolved[i].getY()); + maxY = jmax (maxY, resolved[i].getY()); } return Rectangle (minX, minY, maxX - minX, maxY - minY); @@ -84179,7 +84622,7 @@ bool DrawableImage::hitTest (float x, float y) const if (image == 0) return false; - getTransform().inverted().transformPoint (x, y); + calculateTransform().inverted().transformPoint (x, y); const int ix = roundToInt (x); const int iy = roundToInt (y); @@ -84193,80 +84636,113 @@ bool DrawableImage::hitTest (float x, float y) const Drawable* DrawableImage::createCopy() const { - DrawableImage* const di = new DrawableImage(); + return new DrawableImage (*this); +} - di->opacity = opacity; - di->overlayColour = overlayColour; +void DrawableImage::invalidatePoints() +{ +} - for (int i = 0; i < 4; ++i) - di->controlPoints[i] = controlPoints[i]; +const Identifier DrawableImage::valueTreeType ("Image"); - if (image != 0) - { - if ((! canDeleteImage) || ! ImageCache::isImageInCache (image)) - { - di->setImage (*image); - } - else - { - ImageCache::incReferenceCount (image); - di->setImage (image, true); - } - } +const Identifier DrawableImage::ValueTreeWrapper::opacity ("opacity"); +const Identifier DrawableImage::ValueTreeWrapper::overlay ("overlay"); +const Identifier DrawableImage::ValueTreeWrapper::image ("image"); +const Identifier DrawableImage::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableImage::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableImage::ValueTreeWrapper::bottomLeft ("bottomLeft"); - return di; +DrawableImage::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); } -const Identifier DrawableImage::valueTreeType ("Image"); +const var DrawableImage::ValueTreeWrapper::getImageIdentifier() const +{ + return state [image]; +} -namespace DrawableImageHelpers +void DrawableImage::ValueTreeWrapper::setImageIdentifier (const var& newIdentifier, UndoManager* undoManager) { - static const Identifier opacity ("opacity"); - static const Identifier overlay ("overlay"); - static const Identifier image ("image"); - static const Identifier topLeft ("topLeft"); - static const Identifier topRight ("topRight"); - static const Identifier bottomLeft ("bottomLeft"); + state.setProperty (image, newIdentifier, undoManager); +} - static void stringToPoint (const String& coords, Point& point) - { - if (coords.isNotEmpty()) - { - const int comma = coords.indexOfChar (','); - point.setXY (coords.substring (0, comma).getFloatValue(), - coords.substring (comma + 1).getFloatValue()); - } - } +float DrawableImage::ValueTreeWrapper::getOpacity() const +{ + return (float) state.getProperty (opacity, 1.0); +} - static const var pointToString (const Point& point) - { - return String (point.getX()) + ", " + String (point.getY()); - } +void DrawableImage::ValueTreeWrapper::setOpacity (float newOpacity, UndoManager* undoManager) +{ + state.setProperty (opacity, newOpacity, undoManager); } -const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +const Colour DrawableImage::ValueTreeWrapper::getOverlayColour() const { - jassert (tree.hasType (valueTreeType)); + return Colour (state [overlay].toString().getHexValue32()); +} + +void DrawableImage::ValueTreeWrapper::setOverlayColour (const Colour& newColour, UndoManager* undoManager) +{ + if (newColour.isTransparent()) + state.removeProperty (overlay, undoManager); + else + state.setProperty (overlay, String::toHexString ((int) newColour.getARGB()), undoManager); +} - setName (tree [idProperty]); +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopLeft() const +{ + const String pos (state [topLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint(); +} - const float newOpacity = tree.getProperty (DrawableImageHelpers::opacity, 1.0); - const Colour newOverlayColour (tree [DrawableImageHelpers::overlay].toString().getHexValue32()); +void DrawableImage::ValueTreeWrapper::setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topLeft, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopRight() const +{ + const String pos (state [topRight].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (100.0f, 0.0f)); +} + +void DrawableImage::ValueTreeWrapper::setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topRight, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForBottomLeft() const +{ + const String pos (state [bottomLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (0.0f, 100.0f)); +} + +void DrawableImage::ValueTreeWrapper::setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (bottomLeft, newPoint.toString(), undoManager); +} + +const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ + const ValueTreeWrapper controller (tree); + setName (controller.getID()); + + const float newOpacity = controller.getOpacity(); + const Colour newOverlayColour (controller.getOverlayColour()); Image* newImage = 0; - const String imageIdentifier (tree [DrawableImageHelpers::image].toString()); - if (imageIdentifier.isNotEmpty()) - { - jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! + const var imageIdentifier (controller.getImageIdentifier()); - if (imageProvider != 0) - newImage = imageProvider->getImageForIdentifier (imageIdentifier); - } + jassert (imageProvider != 0 || imageIdentifier.isVoid()); // if you're using images, you need to provide something that can load and save them! - Point newControlPoint[3]; - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topLeft].toString(), newControlPoint[0]); - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topRight].toString(), newControlPoint[1]); - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::bottomLeft].toString(), newControlPoint[2]); + if (imageProvider != 0) + newImage = imageProvider->getImageForIdentifier (imageIdentifier); + + RelativePoint newControlPoint[3] = { controller.getTargetPositionForTopLeft(), + controller.getTargetPositionForTopRight(), + controller.getTargetPositionForBottomLeft() }; if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage || controlPoints[0] != newControlPoint[0] @@ -84281,7 +84757,10 @@ const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tre if (image != newImage) { - ImageCache::release (image); + if (canDeleteImage) + ImageCache::releaseOrDelete (image); + + canDeleteImage = true; image = newImage; } @@ -84294,33 +84773,25 @@ const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tre const ValueTree DrawableImage::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); - - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (opacity < 1.0f) - v.setProperty (DrawableImageHelpers::opacity, (double) opacity, 0); - - if (! overlayColour.isTransparent()) - v.setProperty (DrawableImageHelpers::overlay, String::toHexString ((int) overlayColour.getARGB()), 0); - - if (! getTransform().isIdentity()) - { - v.setProperty (DrawableImageHelpers::topLeft, DrawableImageHelpers::pointToString (controlPoints[0]), 0); - v.setProperty (DrawableImageHelpers::topRight, DrawableImageHelpers::pointToString (controlPoints[1]), 0); - v.setProperty (DrawableImageHelpers::bottomLeft, DrawableImageHelpers::pointToString (controlPoints[2]), 0); - } + v.setID (getName(), 0); + v.setOpacity (opacity, 0); + v.setOverlayColour (overlayColour, 0); + v.setTargetPositionForTopLeft (controlPoints[0], 0); + v.setTargetPositionForTopRight (controlPoints[1], 0); + v.setTargetPositionForBottomLeft (controlPoints[2], 0); if (image != 0) { jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! if (imageProvider != 0) - v.setProperty (DrawableImageHelpers::image, imageProvider->getIdentifierForImage (image), 0); + v.setImageIdentifier (imageProvider->getIdentifierForImage (image), 0); } - return v; + return tree; } END_JUCE_NAMESPACE @@ -84333,10 +84804,25 @@ BEGIN_JUCE_NAMESPACE DrawablePath::DrawablePath() : mainFill (Colours::black), strokeFill (Colours::transparentBlack), - strokeType (0.0f) + strokeType (0.0f), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) { } +DrawablePath::DrawablePath (const DrawablePath& other) + : mainFill (other.mainFill), + strokeFill (other.strokeFill), + strokeType (other.strokeType), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ + if (other.relativePath != 0) + relativePath = new RelativePointPath (*other.relativePath); + else + path = other.path; +} + DrawablePath::~DrawablePath() { } @@ -84344,7 +84830,7 @@ DrawablePath::~DrawablePath() void DrawablePath::setPath (const Path& newPath) { path = newPath; - updateOutline(); + strokeNeedsUpdating = true; } void DrawablePath::setFill (const FillType& newFill) @@ -84360,7 +84846,7 @@ void DrawablePath::setStrokeFill (const FillType& newFill) void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) { strokeType = newStrokeType; - updateOutline(); + strokeNeedsUpdating = true; } void DrawablePath::setStrokeThickness (const float newThickness) @@ -84368,6 +84854,55 @@ void DrawablePath::setStrokeThickness (const float newThickness) setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); } +void DrawablePath::updatePath() const +{ + if (pathNeedsUpdating) + { + pathNeedsUpdating = false; + + if (relativePath != 0) + { + path.clear(); + relativePath->createPath (path, parent); + strokeNeedsUpdating = true; + } + } +} + +void DrawablePath::updateStroke() const +{ + if (strokeNeedsUpdating) + { + strokeNeedsUpdating = false; + updatePath(); + stroke.clear(); + strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); + } +} + +const Path& DrawablePath::getPath() const +{ + updatePath(); + return path; +} + +const Path& DrawablePath::getStrokePath() const +{ + updateStroke(); + return stroke; +} + +bool DrawablePath::isStrokeVisible() const throw() +{ + return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); +} + +void DrawablePath::invalidatePoints() +{ + pathNeedsUpdating = true; + strokeNeedsUpdating = true; +} + void DrawablePath::render (const Drawable::RenderingContext& context) const { { @@ -84377,10 +84912,10 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const f.transform = f.transform.followedBy (context.transform); context.g.setFillType (f); - context.g.fillPath (path, context.transform); + context.g.fillPath (getPath(), context.transform); } - if (strokeType.getStrokeThickness() > 0.0f) + if (isStrokeVisible()) { FillType f (strokeFill); if (f.isGradient()) @@ -84388,161 +84923,131 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const f.transform = f.transform.followedBy (context.transform); context.g.setFillType (f); - context.g.fillPath (stroke, context.transform); + context.g.fillPath (getStrokePath(), context.transform); } } -void DrawablePath::updateOutline() -{ - stroke.clear(); - strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); -} - const Rectangle DrawablePath::getBounds() const { - if (strokeType.getStrokeThickness() > 0.0f) - return stroke.getBounds(); + if (isStrokeVisible()) + return getStrokePath().getBounds(); else - return path.getBounds(); + return getPath().getBounds(); } bool DrawablePath::hitTest (float x, float y) const { - return path.contains (x, y) - || stroke.contains (x, y); + return getPath().contains (x, y) + || (isStrokeVisible() && getStrokePath().contains (x, y)); } Drawable* DrawablePath::createCopy() const { - DrawablePath* const dp = new DrawablePath(); - - dp->path = path; - dp->stroke = stroke; - dp->mainFill = mainFill; - dp->strokeFill = strokeFill; - dp->strokeType = strokeType; - return dp; + return new DrawablePath (*this); } const Identifier DrawablePath::valueTreeType ("Path"); -namespace DrawablePathHelpers -{ - static const Identifier type ("type"); - static const Identifier solid ("solid"); - static const Identifier colour ("colour"); - static const Identifier gradient ("gradient"); - static const Identifier x1 ("x1"); - static const Identifier x2 ("x2"); - static const Identifier y1 ("y1"); - static const Identifier y2 ("y2"); - static const Identifier radial ("radial"); - static const Identifier colours ("colours"); - static const Identifier fill ("fill"); - static const Identifier stroke ("stroke"); - static const Identifier jointStyle ("jointStyle"); - static const Identifier capStyle ("capStyle"); - static const Identifier strokeWidth ("strokeWidth"); - static const Identifier path ("path"); - - static bool updateFillType (const ValueTree& v, FillType& fillType) - { - const String type (v[type].toString()); - - if (type.equalsIgnoreCase (solid)) - { - const String colourString (v [colour].toString()); - const Colour newColour (colourString.isEmpty() ? (uint32) 0xff000000 - : (uint32) colourString.getHexValue32()); - - if (fillType.isColour() && fillType.colour == newColour) - return false; - - fillType.setColour (newColour); - return true; - } - else if (type.equalsIgnoreCase (gradient)) - { - ColourGradient g; - g.point1.setXY (v[x1], v[y1]); - g.point2.setXY (v[x2], v[y2]); - g.isRadial = v[radial]; +const Identifier DrawablePath::ValueTreeWrapper::fill ("fill"); +const Identifier DrawablePath::ValueTreeWrapper::stroke ("stroke"); +const Identifier DrawablePath::ValueTreeWrapper::jointStyle ("jointStyle"); +const Identifier DrawablePath::ValueTreeWrapper::capStyle ("capStyle"); +const Identifier DrawablePath::ValueTreeWrapper::strokeWidth ("strokeWidth"); +const Identifier DrawablePath::ValueTreeWrapper::path ("path"); - StringArray colourSteps; - colourSteps.addTokens (v[colours].toString(), false); +DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); +} - for (int i = 0; i < colourSteps.size() / 2; ++i) - g.addColour (colourSteps[i * 2].getDoubleValue(), - Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); +const FillType DrawablePath::ValueTreeWrapper::getMainFill() const +{ + return readFillType (state.getChildWithName (fill)); +} - if (fillType.isGradient() && *fillType.gradient == g) - return false; +void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, UndoManager* undoManager) +{ + replaceFillType (fill, newFill, undoManager); +} - fillType.setGradient (g); - return true; - } +const FillType DrawablePath::ValueTreeWrapper::getStrokeFill() const +{ + return readFillType (state.getChildWithName (stroke)); +} - jassertfalse; - return false; - } +void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, UndoManager* undoManager) +{ + replaceFillType (stroke, newFill, undoManager); +} - static ValueTree createFillType (const Identifier& tagName, const FillType& fillType) - { - ValueTree v (tagName); +const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const +{ + const String jointStyleString (state [jointStyle].toString()); + const String capStyleString (state [capStyle].toString()); - if (fillType.isColour()) - { - v.setProperty (type, "solid", 0); - v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), 0); - } - else if (fillType.isGradient()) - { - v.setProperty (type, "gradient", 0); - v.setProperty (x1, fillType.gradient->point1.getX(), 0); - v.setProperty (y1, fillType.gradient->point1.getY(), 0); - v.setProperty (x2, fillType.gradient->point2.getX(), 0); - v.setProperty (y2, fillType.gradient->point2.getY(), 0); - v.setProperty (radial, fillType.gradient->isRadial, 0); + return PathStrokeType (state [strokeWidth], + jointStyleString == "curved" ? PathStrokeType::curved + : (jointStyleString == "bevel" ? PathStrokeType::beveled + : PathStrokeType::mitered), + capStyleString == "square" ? PathStrokeType::square + : (capStyleString == "round" ? PathStrokeType::rounded + : PathStrokeType::butt)); +} - String s; - for (int i = 0; i < fillType.gradient->getNumColours(); ++i) - s << " " << fillType.gradient->getColourPosition (i) - << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); +void DrawablePath::ValueTreeWrapper::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) +{ + state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); + state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered + ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); + state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt + ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); +} - v.setProperty (colours, s.trimStart(), 0); - } - else - { - jassertfalse; //xxx - } +void DrawablePath::ValueTreeWrapper::getPath (RelativePointPath& p) const +{ + RelativePointPath newPath (state [path]); + p.swapWith (newPath); +} - return v; - } +void DrawablePath::ValueTreeWrapper::setPath (const String& newPath, UndoManager* undoManager) +{ + state.setProperty (path, newPath, undoManager); } const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - jassert (tree.hasType (valueTreeType)); - Rectangle damageRect; - setName (tree [idProperty]); + ValueTreeWrapper v (tree); + setName (v.getID()); - bool needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::fill), mainFill); - needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::stroke), strokeFill) || needsRedraw; + bool needsRedraw = false; + const FillType newFill (v.getMainFill()); - const String jointStyle (tree [DrawablePathHelpers::jointStyle].toString()); - const String endStyle (tree [DrawablePathHelpers::capStyle].toString()); + if (mainFill != newFill) + { + needsRedraw = true; + mainFill = newFill; + } - PathStrokeType newStroke (tree [DrawablePathHelpers::strokeWidth], - jointStyle == "curved" ? PathStrokeType::curved - : (jointStyle == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - endStyle == "square" ? PathStrokeType::square - : (endStyle == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); + const FillType newStrokeFill (v.getStrokeFill()); + + if (strokeFill != newStrokeFill) + { + needsRedraw = true; + strokeFill = newStrokeFill; + } + + const PathStrokeType newStroke (v.getStrokeType()); + + ScopedPointer newRelativePath (new RelativePointPath()); + v.getPath (*newRelativePath); Path newPath; - newPath.restoreFromString (tree [DrawablePathHelpers::path]); + newRelativePath->createPath (newPath, parent); + + if (! newRelativePath->containsAnyDynamicPoints()) + newRelativePath = 0; if (strokeType != newStroke || path != newPath) { @@ -84552,6 +85057,8 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree needsRedraw = true; } + relativePath = newRelativePath.release(); + if (needsRedraw) damageRect = damageRect.getUnion (getBounds()); @@ -84560,22 +85067,20 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); - - v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::fill, mainFill), -1, 0); - v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::stroke, strokeFill), -1, 0); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + v.setID (getName(), 0); + v.setMainFill (mainFill, 0); + v.setStrokeFill (strokeFill, 0); + v.setStrokeType (strokeType, 0); - v.setProperty (DrawablePathHelpers::strokeWidth, (double) strokeType.getStrokeThickness(), 0); - v.setProperty (DrawablePathHelpers::jointStyle, strokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (strokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), 0); - v.setProperty (DrawablePathHelpers::capStyle, strokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (strokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), 0); - v.setProperty (DrawablePathHelpers::path, path.toString(), 0); + if (relativePath != 0) + v.setPath (relativePath->toString(), 0); + else + v.setPath (path.toString(), 0); - return v; + return tree; } END_JUCE_NAMESPACE @@ -84590,6 +85095,12 @@ DrawableText::DrawableText() { } +DrawableText::DrawableText (const DrawableText& other) + : text (other.text), + colour (other.colour) +{ +} + DrawableText::~DrawableText() { } @@ -84628,20 +85139,27 @@ bool DrawableText::hitTest (float x, float y) const Drawable* DrawableText::createCopy() const { - DrawableText* const dt = new DrawableText(); - - dt->text = text; - dt->colour = colour; + return new DrawableText (*this); +} - return dt; +void DrawableText::invalidatePoints() +{ } const Identifier DrawableText::valueTreeType ("Text"); +const Identifier DrawableText::ValueTreeWrapper::text ("text"); + +DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); +} + const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - jassert (tree.hasType (valueTreeType)); - setName (tree [idProperty]); + ValueTreeWrapper v (tree); + setName (v.getID()); jassertfalse; // xxx not finished! @@ -84650,13 +85168,14 @@ const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + v.setID (getName(), 0); jassertfalse; // xxx not finished! - return v; + + return tree; } END_JUCE_NAMESPACE @@ -88361,12 +88880,7 @@ namespace PathHelpers while (*t != 0 && ! CharacterFunctions::isWhitespace (*t)) ++t; - const int length = (int) (t - start); - - while (CharacterFunctions::isWhitespace (*t)) - ++t; - - return String (start, length); + return String (start, (int) (t - start)); } } @@ -89753,12 +90267,15 @@ void Path::restoreFromString (const String& stringVersion) int numValues = 2; float values [6]; - while (*t != 0) + for (;;) { const String token (PathHelpers::nextToken (t)); const juce_wchar firstChar = token[0]; int startNum = 0; + if (firstChar == 0) + break; + if (firstChar == 'm' || firstChar == 'l') { marker = firstChar; @@ -91657,9 +92174,10 @@ namespace RelativeCoordinateHelpers return fullName.fromFirstOccurrenceOf (".", false, false); } - static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) + static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { - return nameFinder.findNamedCoordinate (getObjectName (name), getEdgeName (name)); + return nameFinder != 0 ? nameFinder->findNamedCoordinate (getObjectName (name), getEdgeName (name)) + : RelativeCoordinate(); } struct RecursionException : public std::runtime_error @@ -91675,6 +92193,13 @@ namespace RelativeCoordinateHelpers ++i; } + static void skipComma (const String& s, int& i) + { + skipWhitespace (s, i); + if (s[i] == ',') + ++i; + } + static const String readAnchorName (const String& s, int& i) { skipWhitespace (s, i); @@ -91720,10 +92245,89 @@ namespace RelativeCoordinateHelpers return value; } + static const RelativeCoordinate readNextCoordinate (const String& s, int& i, const bool isHorizontal) + { + String anchor1 (readAnchorName (s, i)); + double value = 0; + + if (anchor1.isNotEmpty()) + { + skipWhitespace (s, i); + + if (s[i] == '+') + value = readNumber (s, ++i); + else if (s[i] == '-') + value = -readNumber (s, ++i); + + return RelativeCoordinate (value, anchor1); + } + else + { + value = readNumber (s, i); + skipWhitespace (s, i); + + if (s[i] == '%') + { + value /= 100.0; + skipWhitespace (s, ++i); + String anchor2; + + if (s[i] == '*') + { + anchor1 = readAnchorName (s, ++i); + + if (anchor1.isEmpty()) + anchor1 = getOriginAnchorName (isHorizontal); + + skipWhitespace (s, i); + + if (s[i] == '-' && s[i + 1] == '>') + { + i += 2; + anchor2 = readAnchorName (s, i); + } + else + { + anchor2 = anchor1; + anchor1 = getOriginAnchorName (isHorizontal); + } + } + else + { + anchor1 = getOriginAnchorName (isHorizontal); + anchor2 = getExtentAnchorName (isHorizontal); + } + + return RelativeCoordinate (value, anchor1, anchor2); + } + + return RelativeCoordinate (value, isHorizontal); + } + } + static const String limitedAccuracyString (const double n) { return String (n, 3).trimCharactersAtEnd ("0").trimCharactersAtEnd ("."); } + + static bool couldBeMistakenForPathCommand (const String& s) + { + switch (s[0]) + { + case 'a': + case 'm': + case 'l': + case 'z': + case 'q': + case 'c': + return s[1] == 0 || CharacterFunctions::isWhitespace (s[1]); + + default: + break; + } + + return false; + } } const String RelativeCoordinate::Strings::parent ("parent"); @@ -91763,10 +92367,27 @@ RelativeCoordinate::RelativeCoordinate (const double relativeProportion, const S jassert (anchor2.isNotEmpty()); } +RelativeCoordinate::RelativeCoordinate (const String& s, const bool isHorizontal) + : value (0) +{ + int i = 0; + *this = RelativeCoordinateHelpers::readNextCoordinate (s, i, isHorizontal); +} + RelativeCoordinate::~RelativeCoordinate() { } +bool RelativeCoordinate::operator== (const RelativeCoordinate& other) const throw() +{ + return value == other.value && anchor1 == other.anchor1 && anchor2 == other.anchor2; +} + +bool RelativeCoordinate::operator!= (const RelativeCoordinate& other) const throw() +{ + return ! operator== (other); +} + const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate1() const { return RelativeCoordinate (0.0, anchor1); @@ -91777,7 +92398,7 @@ const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate2() const return RelativeCoordinate (0.0, anchor2); } -double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter) +double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter) { if (RelativeCoordinateHelpers::isOrigin (anchorName)) return 0.0; @@ -91785,7 +92406,7 @@ double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedC return RelativeCoordinateHelpers::findCoordinate (anchorName, nameFinder).resolve (nameFinder, recursionCounter + 1); } -double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const +double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const { if (recursionCounter > 150) { @@ -91799,7 +92420,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int : pos1 + value; } -double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) const +double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder) const { try { @@ -91811,7 +92432,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) con return 0.0; } -bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) const +bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder* nameFinder) const { try { @@ -91825,7 +92446,7 @@ bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) c return false; } -void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder* nameFinder) { try { @@ -91847,7 +92468,7 @@ void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFin {} } -void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal) +void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal) { const double oldValue = resolve (nameFinder); @@ -91858,7 +92479,7 @@ void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nam moveToAbsolute (oldValue, nameFinder); } -bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder& nameFinder) const +bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder* nameFinder) const { using namespace RelativeCoordinateHelpers; @@ -91871,62 +92492,9 @@ bool RelativeCoordinate::references (const String& coordName, const NamedCoordin || (isProportional() && findCoordinate (anchor2, nameFinder).references (coordName, nameFinder)); } -RelativeCoordinate::RelativeCoordinate (const String& s, bool isHorizontal) - : value (0) +bool RelativeCoordinate::isDynamic() const { - using namespace RelativeCoordinateHelpers; - int i = 0; - - anchor1 = readAnchorName (s, i); - - if (anchor1.isNotEmpty()) - { - skipWhitespace (s, i); - - if (s[i] == '+') - value = readNumber (s, ++i); - else if (s[i] == '-') - value = -readNumber (s, ++i); - } - else - { - anchor1 = getOriginAnchorName (isHorizontal); - - value = readNumber (s, i); - skipWhitespace (s, i); - - if (s[i] == '%') - { - value /= 100.0; - skipWhitespace (s, ++i); - - if (s[i] == '*') - { - anchor1 = readAnchorName (s, ++i); - - if (anchor1.isEmpty()) - anchor1 = getOriginAnchorName (isHorizontal); - - skipWhitespace (s, i); - - if (s[i] == '-' && s[i + 1] == '>') - { - i += 2; - anchor2 = readAnchorName (s, i); - } - else - { - anchor2 = anchor1; - anchor1 = getOriginAnchorName (isHorizontal); - } - } - else - { - anchor1 = getOriginAnchorName (isHorizontal); - anchor2 = getExtentAnchorName (isHorizontal); - } - } - } + return anchor2.isNotEmpty() || ! RelativeCoordinateHelpers::isOrigin (anchor1); } const String RelativeCoordinate::toString() const @@ -91970,7 +92538,7 @@ void RelativeCoordinate::setEditableNumber (const double newValue) value = isProportional() ? newValue / 100.0 : newValue; } -void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) { jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); @@ -91979,7 +92547,7 @@ void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const Named moveToAbsolute (oldValue, nameFinder); } -void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) { jassert (isProportional()); jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); @@ -91989,7 +92557,7 @@ void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const Named moveToAbsolute (oldValue, nameFinder); } -void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder* nameFinder) { using namespace RelativeCoordinateHelpers; jassert (oldName.isNotEmpty()); @@ -92025,21 +92593,36 @@ RelativePoint::RelativePoint (const Point& absolutePoint) { } -RelativePoint::RelativePoint (const String& stringVersion) +RelativePoint::RelativePoint (const RelativeCoordinate& x_, const RelativeCoordinate& y_) + : x (x_), y (y_) +{ +} + +RelativePoint::RelativePoint (const String& s) +{ + int i = 0; + x = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + y = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); +} + +bool RelativePoint::operator== (const RelativePoint& other) const throw() { - const int separator = stringVersion.indexOfChar (','); + return x == other.x && y == other.y; +} - x = RelativeCoordinate (stringVersion.substring (0, separator), true); - y = RelativeCoordinate (stringVersion.substring (separator + 1), false); +bool RelativePoint::operator!= (const RelativePoint& other) const throw() +{ + return ! operator== (other); } -const Point RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const +const Point RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { return Point ((float) x.resolve (nameFinder), (float) y.resolve (nameFinder)); } -void RelativePoint::moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativePoint::moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { x.moveToAbsolute (newPos.getX(), nameFinder); y.moveToAbsolute (newPos.getY(), nameFinder); @@ -92050,12 +92633,17 @@ const String RelativePoint::toString() const return x.toString() + ", " + y.toString(); } -void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { x.renameAnchorIfUsed (oldName, newName, nameFinder); y.renameAnchorIfUsed (oldName, newName, nameFinder); } +bool RelativePoint::isDynamic() const +{ + return x.isDynamic() || y.isDynamic(); +} + RelativeRectangle::RelativeRectangle() { } @@ -92068,18 +92656,29 @@ RelativeRectangle::RelativeRectangle (const Rectangle& rect, const String { } -RelativeRectangle::RelativeRectangle (const String& stringVersion) +RelativeRectangle::RelativeRectangle (const String& s) { - StringArray tokens; - tokens.addTokens (stringVersion, ",", String::empty); + int i = 0; + left = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + top = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); + RelativeCoordinateHelpers::skipComma (s, i); + right = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + bottom = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); +} - left = RelativeCoordinate (tokens [0], true); - top = RelativeCoordinate (tokens [1], false); - right = RelativeCoordinate (tokens [2], true); - bottom = RelativeCoordinate (tokens [3], false); +bool RelativeRectangle::operator== (const RelativeRectangle& other) const throw() +{ + return left == other.left && top == other.top && right == other.right && bottom == other.bottom; +} + +bool RelativeRectangle::operator!= (const RelativeRectangle& other) const throw() +{ + return ! operator== (other); } -const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const +const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { const double l = left.resolve (nameFinder); const double r = right.resolve (nameFinder); @@ -92089,7 +92688,7 @@ const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::Nam return Rectangle ((float) l, (float) t, (float) (r - l), (float) (b - t)); } -void RelativeRectangle::moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativeRectangle::moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { left.moveToAbsolute (newPos.getX(), nameFinder); right.moveToAbsolute (newPos.getRight(), nameFinder); @@ -92103,7 +92702,7 @@ const String RelativeRectangle::toString() const } void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder) + const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { left.renameAnchorIfUsed (oldName, newName, nameFinder); right.renameAnchorIfUsed (oldName, newName, nameFinder); @@ -92111,6 +92710,258 @@ void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& bottom.renameAnchorIfUsed (oldName, newName, nameFinder); } +RelativePointPath::RelativePointPath() + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ +} + +RelativePointPath::RelativePointPath (const RelativePointPath& other) + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ + parseString (other.toString()); +} + +RelativePointPath::RelativePointPath (const String& s) + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ + parseString (s); +} + +void RelativePointPath::parseString (const String& s) +{ + int i = 0; + juce_wchar marker = 'm'; + int numValues = 2; + RelativePoint points [3]; + + for (;;) + { + RelativeCoordinateHelpers::skipWhitespace (s, i); + const juce_wchar firstChar = s[i]; + + if (firstChar == 0) + break; + + const juce_wchar secondChar = s[i + 1]; + + if (secondChar == 0 || CharacterFunctions::isWhitespace (secondChar)) + { + if (firstChar == 'm' || firstChar == 'l') + { + ++i; + marker = firstChar; + numValues = 1; + } + else if (firstChar == 'q') + { + ++i; + marker = firstChar; + numValues = 2; + } + else if (firstChar == 'c') + { + ++i; + marker = firstChar; + numValues = 3; + } + else if (firstChar == 'z') + { + ++i; + marker = 'm'; + numValues = 2; + elements.add (new CloseSubPath()); + continue; + } + else if (firstChar == 'a') + { + ++i; + usesNonZeroWinding = false; + continue; + } + } + + if (firstChar == '#') + ++i; + + for (int j = 0; j < numValues; ++j) + { + const RelativeCoordinate x (RelativeCoordinateHelpers::readNextCoordinate (s, i, true)); + const RelativeCoordinate y (RelativeCoordinateHelpers::readNextCoordinate (s, i, false)); + points[j] = RelativePoint (x, y); + containsDynamicPoints = containsDynamicPoints || points[j].isDynamic(); + } + + switch (marker) + { + case 'm': elements.add (new StartSubPath (points[0])); break; + case 'l': elements.add (new LineTo (points[0])); break; + case 'q': elements.add (new QuadraticTo (points[0], points[1])); break; + case 'c': elements.add (new CubicTo (points[0], points[1], points[2])); break; + default: jassertfalse; break; // illegal string format? + } + } +} + +RelativePointPath::~RelativePointPath() +{ +} + +void RelativePointPath::swapWith (RelativePointPath& other) throw() +{ + elements.swapWithArray (other.elements); + swapVariables (usesNonZeroWinding, other.usesNonZeroWinding); +} + +void RelativePointPath::createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) +{ + for (int i = 0; i < elements.size(); ++i) + elements.getUnchecked(i)->addToPath (path, coordFinder); +} + +bool RelativePointPath::containsAnyDynamicPoints() const +{ + return containsDynamicPoints; +} + +const String RelativePointPath::toString() const +{ + ElementType lastType = nullElement; + MemoryOutputStream out; + + if (! usesNonZeroWinding) + out << 'a'; + + for (int i = 0; i < elements.size(); ++i) + { + if (out.getDataSize() > 0) + out << ' '; + + const ElementBase* const e = elements.getUnchecked(i); + e->write (out, lastType); + lastType = e->type; + } + + return out.toUTF8(); +} + +RelativePointPath::ElementBase::ElementBase (const ElementType type_) : type (type_) +{ +} + +RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos) + : ElementBase (startSubPathElement), startPos (pos) +{ +} + +void RelativePointPath::StartSubPath::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p (startPos.toString()); + + if (lastTypeWritten != startSubPathElement) + out << "m "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) + out << '#'; + + out << p; +} + +void RelativePointPath::StartSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p (startPos.resolve (coordFinder)); + path.startNewSubPath (p.getX(), p.getY()); +} + +RelativePointPath::CloseSubPath::CloseSubPath() + : ElementBase (closeSubPathElement) +{ +} + +void RelativePointPath::CloseSubPath::write (OutputStream& out, ElementType lastTypeWritten) const +{ + if (lastTypeWritten != closeSubPathElement) + out << 'z'; +} + +void RelativePointPath::CloseSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder*) const +{ + path.closeSubPath(); +} + +RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_) + : ElementBase (lineToElement), endPoint (endPoint_) +{ +} + +void RelativePointPath::LineTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p (endPoint.toString()); + + if (lastTypeWritten != lineToElement) + out << "l "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) + out << '#'; + + out << p; +} + +void RelativePointPath::LineTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p (endPoint.resolve (coordFinder)); + path.lineTo (p.getX(), p.getY()); +} + +RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint_, const RelativePoint& endPoint_) + : ElementBase (quadraticToElement), controlPoint (controlPoint_), endPoint (endPoint_) +{ +} + +void RelativePointPath::QuadraticTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p1 (controlPoint.toString()); + + if (lastTypeWritten != quadraticToElement) + out << "q "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) + out << '#'; + + out << p1 << ' ' << endPoint.toString(); +} + +void RelativePointPath::QuadraticTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p1 (controlPoint.resolve (coordFinder)); + const Point p2 (endPoint.resolve (coordFinder)); + path.quadraticTo (p1.getX(), p1.getY(), p2.getX(), p2.getY()); +} + +RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1_, const RelativePoint& controlPoint2_, const RelativePoint& endPoint_) + : ElementBase (cubicToElement), controlPoint1 (controlPoint1_), controlPoint2 (controlPoint2_), endPoint (endPoint_) +{ +} + +void RelativePointPath::CubicTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p1 (controlPoint1.toString()); + + if (lastTypeWritten != cubicToElement) + out << "c "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) + out << '#'; + + out << p1 << ' ' << controlPoint2.toString() << ' ' << endPoint.toString(); +} + +void RelativePointPath::CubicTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p1 (controlPoint1.resolve (coordFinder)); + const Point p2 (controlPoint2.resolve (coordFinder)); + const Point p3 (endPoint.resolve (coordFinder)); + path.cubicTo (p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY()); +} + END_JUCE_NAMESPACE /*** End of inlined file: juce_RelativeCoordinate.cpp ***/ @@ -92673,6 +93524,9 @@ void ImageCache::releaseOrDelete (Image* const imageToRelease) bool ImageCache::isImageInCache (Image* const imageToLookFor) { + if (imageToLookFor == 0) + return false; + if (instance != 0) { const ScopedLock sl (instance->lock); @@ -237757,9 +238611,9 @@ public: SetCaretPos (0, 0); } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { - const RECT r = { x, y, x + w, y + h }; + const RECT r = { area.getX(), area.getY(), area.getRight(), area.getBottom() }; InvalidateRect (hwnd, &r, FALSE); } @@ -242012,8 +242866,7 @@ public: void repaint() { - const Rectangle bounds (nativeWindow->getBounds()); - nativeWindow->repaint (0, 0, bounds.getWidth(), bounds.getHeight()); + nativeWindow->repaint (nativeWindow->getBounds().withPosition (Point())); } void swapBuffers() @@ -245824,7 +246677,10 @@ public: Thread::sleep (20); isStarted = false; isOpen_ = false; - close(); + + const String errorCopy (error); + close(); // (this resets the error string) + error = errorCopy; } needToReset = false; @@ -249396,7 +250252,7 @@ public: int getInputLatencyInSamples() { return latencyIn; } const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } - const String getLastError() { return lastError; } + const String getLastError() { return lastError; } const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, double sampleRate, int bufferSizeSamples) @@ -254913,15 +255769,9 @@ public: { } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { - if (Rectangle::intersectRectangles (x, y, w, h, - 0, 0, - getComponent()->getWidth(), - getComponent()->getHeight())) - { - repainter->repaint (x, y, w, h); - } + repainter->repaint (area.getIntersection (getComponent()->getLocalBounds())); } void performAnyPendingRepaintsNow() @@ -255347,8 +256197,8 @@ public: &child); } - repaint (exposeEvent->x, exposeEvent->y, - exposeEvent->width, exposeEvent->height); + repaint (Rectangle (exposeEvent->x, exposeEvent->y, + exposeEvent->width, exposeEvent->height)); while (XEventsQueued (display, QueuedAfterFlush) > 0) { @@ -255358,8 +256208,8 @@ public: XNextEvent (display, (XEvent*) &nextEvent); XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose; - repaint (nextExposeEvent->x, nextExposeEvent->y, - nextExposeEvent->width, nextExposeEvent->height); + repaint (Rectangle (nextExposeEvent->x, nextExposeEvent->y, + nextExposeEvent->width, nextExposeEvent->height)); } break; @@ -255657,12 +256507,12 @@ private: } } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { if (! isTimerRunning()) startTimer (repaintTimerPeriod); - regionsNeedingRepaint.add (x, y, w, h); + regionsNeedingRepaint.add (area); } void performAnyPendingRepaintsNow() @@ -263406,7 +264256,7 @@ public: void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); - void repaint (int x, int y, int w, int h); + void repaint (const Rectangle& area); void performAnyPendingRepaintsNow(); juce_UseDebuggingNewOperator @@ -264100,19 +264950,20 @@ public: void messageCallback() { if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + peer->repaint (rect); } }; -void UIViewComponentPeer::repaint (int x, int y, int w, int h) +void UIViewComponentPeer::repaint (const Rectangle& area) { if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) { - (new AsyncRepaintMessage (this, Rectangle (x, y, w, h)))->post(); + (new AsyncRepaintMessage (this, area))->post(); } else { - [view setNeedsDisplayInRect: CGRectMake ((float) x, (float) y, (float) w, (float) h)]; + [view setNeedsDisplayInRect: CGRectMake ((float) area.getX(), (float) area.getY(), + (float) area.getWidth(), (float) area.getHeight())]; } } @@ -268127,7 +268978,7 @@ public: void grabFocus(); void textInputRequired (const Point& position); - void repaint (int x, int y, int w, int h); + void repaint (const Rectangle& area); void performAnyPendingRepaintsNow(); juce_UseDebuggingNewOperator @@ -269484,20 +270335,20 @@ public: void messageCallback() { if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + peer->repaint (rect); } }; -void NSViewComponentPeer::repaint (int x, int y, int w, int h) +void NSViewComponentPeer::repaint (const Rectangle& area) { if (insideDrawRect) { - (new AsyncRepaintMessage (this, Rectangle (x, y, w, h)))->post(); + (new AsyncRepaintMessage (this, area))->post(); } else { - [view setNeedsDisplayInRect: NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)), - (float) w, (float) h)]; + [view setNeedsDisplayInRect: NSMakeRect ((float) area.getX(), [view frame].size.height - (float) area.getBottom(), + (float) area.getWidth(), (float) area.getHeight())]; } } diff --git a/juce_amalgamated.h b/juce_amalgamated.h index 236f61270f..cdcb8f1b75 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -64,7 +64,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 5 +#define JUCE_BUILDNUMBER 6 /** Current Juce version number. @@ -3541,7 +3541,7 @@ public: return false; for (int i = numUsed; --i >= 0;) - if (data.elements [i] != other.data.elements [i]) + if (! (data.elements [i] == other.data.elements [i])) return false; return true; @@ -5561,6 +5561,9 @@ public: /** Destructor. */ ~NamedValueSet(); + bool operator== (const NamedValueSet& other) const; + bool operator!= (const NamedValueSet& other) const; + /** Returns the total number of values that the set contains. */ int size() const throw(); @@ -5616,6 +5619,7 @@ private: { NamedValue() throw(); NamedValue (const Identifier& name, const var& value); + bool operator== (const NamedValue& other) const throw(); Identifier name; var value; @@ -12934,13 +12938,21 @@ public: Note that this isn't a value comparison - two independently-created trees which contain identical data are not considered equal. */ - bool operator== (const ValueTree& other) const; + bool operator== (const ValueTree& other) const throw(); /** Returns true if this and the other node refer to different underlying structures. Note that this isn't a value comparison - two independently-created trees which contain identical data are not considered equal. */ - bool operator!= (const ValueTree& other) const; + bool operator!= (const ValueTree& other) const throw(); + + /** Performs a deep comparison between the properties and children of two trees. + If all the properties and children of the two trees are the same (recursively), this + returns true. + The normal operator==() only checks whether two trees refer to the same shared data + structure, so use this method if you need to do a proper value comparison. + */ + bool isEquivalentTo (const ValueTree& other) const; /** Returns true if this node refers to some valid data. It's hard to create an invalid node, but you might get one returned, e.g. by an out-of-range @@ -13061,7 +13073,7 @@ public: If the undoManager parameter is non-null, its UndoManager::perform() method will be used, so that this change can be undone. */ - void addChild (ValueTree child, int index, UndoManager* undoManager); + void addChild (const ValueTree& child, int index, UndoManager* undoManager); /** Removes the specified child from this node's child-list. If the undoManager parameter is non-null, its UndoManager::perform() method will be used, @@ -13287,6 +13299,7 @@ private: void removeChild (int childIndex, UndoManager*); void removeAllChildren (UndoManager*); void moveChild (int currentIndex, int newIndex, UndoManager*); + bool isEquivalentTo (const SharedObject& other) const; XmlElement* createXml() const; juce_UseDebuggingNewOperator @@ -23261,6 +23274,12 @@ public: */ float getOpacity() const throw() { return colour.getFloatAlpha(); } + /** Returns true if this fill type is completely transparent. */ + bool isInvisible() const throw(); + + bool operator== (const FillType& other) const; + bool operator!= (const FillType& other) const; + /** The solid colour being used. If the fill type is not a solid colour, the alpha channel of this colour indicates @@ -25142,6 +25161,21 @@ public: */ void repaint (int x, int y, int width, int height); + /** Marks a subsection of this component as needing to be redrawn. + + Calling this will not do any repainting immediately, but will mark the given region + of the component as 'dirty'. At some point in the near future the operating system + will send a paint message, which will redraw all the dirty regions of all components. + There's no guarantee about how soon after calling repaint() the redraw will actually + happen, and other queued events may be delivered before a redraw is done. + + The region that is passed in will be clipped to keep it within the bounds of this + component. + + @see repaint() + */ + void repaint (const Rectangle& area); + /** Makes the component use an internal buffer to optimise its redrawing. Setting this flag to true will cause the component to allocate an @@ -41776,6 +41810,494 @@ private: #ifndef __JUCE_DRAWABLE_JUCEHEADER__ #define __JUCE_DRAWABLE_JUCEHEADER__ + +/*** Start of inlined file: juce_RelativeCoordinate.h ***/ +#ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ +#define __JUCE_RELATIVECOORDINATE_JUCEHEADER__ + +/** + Expresses a coordinate as an absolute or proportional distance from other + named coordinates. + + A RelativeCoordinate represents a position as either: + - an absolute distance from the origin + - an absolute distance from another named RelativeCoordinate + - a proportion of the distance between two other named RelativeCoordinates + + Of course, the coordinates that this one is relative to may themselves be relative + to other coordinates, so complex arrangements can be built up (as long as you're careful + not to create recursive loops!) + + Rather than keeping pointers to the coordinates that this one is dependent on, it + stores their names, and when resolving this coordinate to an absolute value, a + NamedCoordinateFinder class is required to retrieve these coordinates by name. + + @see RelativePoint, RelativeRectangle +*/ +class JUCE_API RelativeCoordinate +{ +public: + + /** Creates a zero coordinate. */ + RelativeCoordinate(); + + /** Creates an absolute position from the parent origin on either the X or Y axis. + + @param absoluteDistanceFromOrigin the distance from the origin + @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. + */ + RelativeCoordinate (double absoluteDistanceFromOrigin, bool isHorizontal); + + /** Creates an absolute position relative to a named coordinate. + + @param absoluteDistanceFromAnchor the distance to add to the named anchor point + @param anchorPoint the name of the coordinate from which this one will be relative. See the constructor + notes for a description of the syntax for coordinate names. + */ + RelativeCoordinate (double absoluteDistanceFromAnchor, const String& anchorPoint); + + /** Creates a relative position between two named points. + + @param relativeProportionBetweenAnchors a value between 0 and 1 indicating this coordinate's relative position + between anchorPoint1 and anchorPoint2. + @param anchorPoint1 the name of the first coordinate from which this one will be relative. See the constructor + notes for a description of the syntax for coordinate names. + @param anchorPoint2 the name of the first coordinate from which this one will be relative. See the constructor + notes for a description of the syntax for coordinate names. + */ + RelativeCoordinate (double relativeProportionBetweenAnchors, const String& anchorPoint1, const String& anchorPoint2); + + /** Recreates a coordinate from a string description. + + The string can be in one of the following formats: + - "123" = 123 pixels from parent origin (this is equivalent to "parent.left + 123" + or "parent.top + 123", depending on which axis the coordinate is using) + - "anchor" = the same position as the coordinate named "anchor" + - "anchor + 123" = the coordinate named "anchor" + 123 pixels + - "anchor - 123" = the coordinate named "anchor" - 123 pixels + - "50%" = 50% of the distance between the coordinate space's top-left origin and its extent + (this is equivalent to "50% * parent.left -> parent.right" or "50% * parent.top -> parent.bottom") + - "50% * anchor" = 50% of the distance between the coordinate space's origin and the coordinate named "anchor" + (this is equivalent to "50% * parent.left -> anchor" or "50% * parent.top -> anchor") + - "50% * anchor1 -> anchor2" = 50% of the distance between the coordinate "anchor1" and the coordinate "anchor2" + + An anchor name can either be just a single identifier (letters, digits and underscores only - no spaces), + e.g. "marker1", or it can be a two-part name in the form "objectName.edge". For example "parent.left" is + the origin, or "myComponent.top" is the top edge of a component called "myComponent". The exact names that + will be recognised are dependent on the NamedCoordinateFinder that you provide for looking them up, but + "parent.left" and "parent.top" are always available, meaning the origin. "parent.right" and "parent.bottom" + may also be available if the coordinate space has a fixed size. + + @param stringVersion the string to parse + @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. + + @see toString + */ + RelativeCoordinate (const String& stringVersion, bool isHorizontal); + + /** Destructor. */ + ~RelativeCoordinate(); + + bool operator== (const RelativeCoordinate& other) const throw(); + bool operator!= (const RelativeCoordinate& other) const throw(); + + /** + Provides an interface for looking up the position of a named anchor when resolving a RelativeCoordinate. + + When using RelativeCoordinates, to resolve their names you need to provide a subclass of this which + can retrieve a coordinate by name. + */ + class JUCE_API NamedCoordinateFinder + { + public: + /** Destructor. */ + virtual ~NamedCoordinateFinder() {} + + /** Returns the coordinate for a given name. + + The objectName parameter will be the first section of the name, and the edge the name of the second part. + E.g. for "parent.right", objectName would be "parent" and edge would be "right". If the name + has no dot, the edge parameter will be an empty string. + + This method must be able to resolve "parent.left", "parent.top", "parent.right" and "parent.bottom", as + well as any other objects that your application uses. + */ + virtual const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const = 0; + }; + + /** Calculates the absolute position of this coordinate. + + You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may + be needed to calculate the result. + */ + double resolve (const NamedCoordinateFinder* nameFinder) const; + + /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. + This will recursively check any coordinates upon which this one depends. + */ + bool references (const String& coordName, const NamedCoordinateFinder* nameFinder) const; + + /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ + bool isRecursive (const NamedCoordinateFinder* nameFinder) const; + + /** Returns true if this coordinate depends on any other coordinates for its position. */ + bool isDynamic() const; + + /** Changes the value of this coord to make it resolve to the specified position. + + Calling this will leave the anchor points unchanged, but will set this coordinate's absolute + or relative position to whatever value is necessary to make its resultant position + match the position that is provided. + */ + void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder* nameFinder); + + /** Returns true if the coordinate is calculated as a proportion of the distance between two other points. + @see toggleProportionality + */ + bool isProportional() const throw() { return anchor2.isNotEmpty(); } + + /** Toggles the coordinate between using a proportional or absolute position. + Note that calling this will reset the names of any anchor points, and just make the + coordinate relative to the parent origin and parent size. + */ + void toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal); + + /** Returns a value that can be edited to set this coordinate's position. + The meaning of this number depends on the coordinate's mode. If the coordinate is + proportional, the number will be a percentage between 0 and 100. If the + coordinate is absolute, then it will be the number of pixels from its anchor point. + @see setEditableNumber + */ + const double getEditableNumber() const; + + /** Sets the value that controls this coordinate's position. + The meaning of this number depends on the coordinate's mode. If the coordinate is + proportional, the number must be a percentage between 0 and 100. If the + coordinate is absolute, then it indicates the number of pixels from its anchor point. + @see setEditableNumber + */ + void setEditableNumber (const double newValue); + + /** Returns the name of the first anchor point from which this coordinate is relative. + */ + const String getAnchorName1() const { return anchor1; } + + /** Returns the name of the second anchor point from which this coordinate is relative. + The second anchor is only valid if the coordinate is in proportional mode. + */ + const String getAnchorName2() const { return anchor2; } + + /** Returns the first anchor point as a coordinate. */ + const RelativeCoordinate getAnchorCoordinate1() const; + + /** Returns the first anchor point as a coordinate. + The second anchor is only valid if the coordinate is in proportional mode. + */ + const RelativeCoordinate getAnchorCoordinate2() const; + + /** Changes the first anchor point, keeping the resultant position of this coordinate in + the same place it was previously. + */ + void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); + + /** Changes the second anchor point, keeping the resultant position of this coordinate in + the same place it was previously. + */ + void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); + + /** Tells the coordinate that an object is changing its name or being deleted. + + If either of this coordinates anchor points match this name, they will be replaced. + If the newName string is empty, it indicates that the object is being removed, so if + this coordinate was using it, the coordinate is changed to be relative to the origin + instead. + */ + void renameAnchorIfUsed (const String& oldName, const String& newName, + const NamedCoordinateFinder* nameFinder); + + /** Returns a string which represents this coordinate. + For details of the string syntax, see the constructor notes. + */ + const String toString() const; + + /** A set of static strings that are commonly used by the RelativeCoordinate class. + + As well as avoiding using string literals in your code, using these preset values + has the advantage that all instances of the same string will share the same, reference-counted + String object, so if you have thousands of points which all refer to the same + anchor points, this can save a significant amount of memory allocation. + */ + struct Strings + { + static const String parent; /**< "parent" */ + static const String left; /**< "left" */ + static const String right; /**< "right" */ + static const String top; /**< "top" */ + static const String bottom; /**< "bottom" */ + static const String parentLeft; /**< "parent.left" */ + static const String parentTop; /**< "parent.top" */ + static const String parentRight; /**< "parent.right" */ + static const String parentBottom; /**< "parent.bottom" */ + }; + +private: + + String anchor1, anchor2; + double value; + + double resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const; + static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter); +}; + +/** + An X-Y position stored as a pair of RelativeCoordinate values. + + @see RelativeCoordinate, RelativeRectangle +*/ +class JUCE_API RelativePoint +{ +public: + /** Creates a point at the origin. */ + RelativePoint(); + + /** Creates an absolute point, relative to the origin. */ + RelativePoint (const Point& absolutePoint); + + /** Creates an absolute point from two coordinates. */ + RelativePoint (const RelativeCoordinate& x, const RelativeCoordinate& y); + + /** Creates a point from a stringified representation. + The string must contain a pair of coordinates, separated by space or a comma. The syntax for the coordinate + strings is explained in the RelativeCoordinate class. + @see toString + */ + RelativePoint (const String& stringVersion); + + bool operator== (const RelativePoint& other) const throw(); + bool operator!= (const RelativePoint& other) const throw(); + + /** Calculates the absolute position of this point. + + You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may + be needed to calculate the result. + */ + const Point resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; + + /** Changes the values of this point's coordinates to make it resolve to the specified position. + + Calling this will leave any anchor points unchanged, but will set any absolute + or relative positions to whatever values are necessary to make the resultant position + match the position that is provided. + */ + void moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); + + /** Returns a string which represents this point. + This returns a comma-separated pair of coordinates. For details of the string syntax used by the + coordinates, see the RelativeCoordinate constructor notes. + The string that is returned can be passed to the RelativePoint constructor to recreate the point. + */ + const String toString() const; + + /** Tells the point that an object is changing its name or being deleted. + This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. + */ + void renameAnchorIfUsed (const String& oldName, const String& newName, + const RelativeCoordinate::NamedCoordinateFinder* nameFinder); + + /** Returns true if this point depends on any other coordinates for its position. */ + bool isDynamic() const; + + // The actual X and Y coords... + RelativeCoordinate x, y; +}; + +/** + An rectangle stored as a set of RelativeCoordinate values. + + The rectangle's top, left, bottom and right edge positions are each stored as a RelativeCoordinate. + + @see RelativeCoordinate, RelativePoint +*/ +class JUCE_API RelativeRectangle +{ +public: + + /** Creates a zero-size rectangle at the origin. */ + RelativeRectangle(); + + /** Creates an absolute rectangle, relative to the origin. */ + explicit RelativeRectangle (const Rectangle& rect, const String& componentName); + + /** Creates a rectangle from a stringified representation. + The string must contain a sequence of 4 coordinates, separated by commas, in the order + left, top, right, bottom. The syntax for the coordinate strings is explained in the + RelativeCoordinate class. + @see toString + */ + explicit RelativeRectangle (const String& stringVersion); + + bool operator== (const RelativeRectangle& other) const throw(); + bool operator!= (const RelativeRectangle& other) const throw(); + + /** Calculates the absolute position of this rectangle. + + You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may + be needed to calculate the result. + */ + const Rectangle resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; + + /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. + + Calling this will leave any anchor points unchanged, but will set any absolute + or relative positions to whatever values are necessary to make the resultant position + match the position that is provided. + */ + void moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); + + /** Returns a string which represents this point. + This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of + the string syntax used by the coordinates, see the RelativeCoordinate constructor notes. + The string that is returned can be passed to the RelativeRectangle constructor to recreate the rectangle. + */ + const String toString() const; + + /** Tells the rectangle that an object is changing its name or being deleted. + This calls RelativeCoordinate::renameAnchorIfUsed() on the rectangle's coordinates. + */ + void renameAnchorIfUsed (const String& oldName, const String& newName, + const RelativeCoordinate::NamedCoordinateFinder* nameFinder); + + // The actual rectangle coords... + RelativeCoordinate left, right, top, bottom; +}; + +/** + A path object that consists of RelativePoint coordinates rather than the normal fixed ones. + + One of these paths can be converted into a Path object for drawing and manipulation, but + unlike a Path, its points can be dynamic instead of just fixed. + + @see RelativePoint, RelativeCoordinate +*/ +class JUCE_API RelativePointPath +{ +public: + + RelativePointPath(); + RelativePointPath (const RelativePointPath& other); + RelativePointPath (const String& stringVersion); + ~RelativePointPath(); + + /** Resolves this points in this path and adds them to a normal Path object. */ + void createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder); + + /** Returns true if the path contains any non-fixed points. */ + bool containsAnyDynamicPoints() const; + + /** Returns a string version of the path. + This has the same format as Path::toString(), but since it can contain RelativeCoordinate + positions, it can't be parsed by the Path class if any of the points are dynamic. + */ + const String toString() const; + + /** Quickly swaps the contents of this path with another. */ + void swapWith (RelativePointPath& other) throw(); + + /** The types of element that may be contained in this path. + @see RelativePointPath::ElementBase + */ + enum ElementType + { + nullElement, + startSubPathElement, + closeSubPathElement, + lineToElement, + quadraticToElement, + cubicToElement + }; + + /** Base class for the elements that make up a RelativePointPath. + */ + class JUCE_API ElementBase + { + public: + ElementBase (ElementType type); + virtual ~ElementBase() {} + virtual void write (OutputStream& out, ElementType lastTypeWritten) const = 0; + virtual void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const = 0; + + const ElementType type; + }; + + class JUCE_API StartSubPath : public ElementBase + { + public: + StartSubPath (const RelativePoint& pos); + ~StartSubPath() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint startPos; + }; + + class JUCE_API CloseSubPath : public ElementBase + { + public: + CloseSubPath(); + ~CloseSubPath() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + }; + + class JUCE_API LineTo : public ElementBase + { + public: + LineTo (const RelativePoint& endPoint); + ~LineTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint endPoint; + }; + + class JUCE_API QuadraticTo : public ElementBase + { + public: + QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); + ~QuadraticTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint controlPoint, endPoint; + }; + + class JUCE_API CubicTo : public ElementBase + { + public: + CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); + ~CubicTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint controlPoint1, controlPoint2, endPoint; + }; + + OwnedArray elements; + bool usesNonZeroWinding; + +private: + bool containsDynamicPoints; + + void parseString (const String& s); + + RelativePointPath& operator= (const RelativePointPath&); +}; + +#endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__ +/*** End of inlined file: juce_RelativeCoordinate.h ***/ + +class DrawableComposite; + /** The base class for objects which can draw themselves, e.g. polygons, images, etc. @@ -41965,10 +42487,32 @@ public: /** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */ virtual const Identifier getValueTreeType() const = 0; + /** Internal class used to manage ValueTrees that represent Drawables. */ + class ValueTreeWrapperBase + { + public: + ValueTreeWrapperBase (const ValueTree& state); + ~ValueTreeWrapperBase(); + + ValueTree& getState() throw() { return state; } + + const String getID() const; + void setID (const String& newID, UndoManager* undoManager); + + protected: + ValueTree state; + static const Identifier idProperty, type, x1, x2, y1, y2, colour, radial, colours; + + static const FillType readFillType (const ValueTree& v); + void replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager); + }; + juce_UseDebuggingNewOperator protected: - static const Identifier idProperty; + friend class DrawableComposite; + DrawableComposite* parent; + virtual void invalidatePoints() = 0; private: String name; @@ -56527,7 +57071,7 @@ public: TextInputTarget* findCurrentTextInputTarget(); /** Invalidates a region of the window to be repainted asynchronously. */ - virtual void repaint (int x, int y, int w, int h) = 0; + virtual void repaint (const Rectangle& area) = 0; /** This can be called (from the message thread) to cause the immediate redrawing of any areas of this window that need repainting. @@ -57168,12 +57712,13 @@ public: x = endX; } + levelAccumulator >>= 8; + if (levelAccumulator > 0) { x >>= 8; jassert (x >= bounds.getX() && x < bounds.getRight()); - levelAccumulator >>= 8; if (levelAccumulator >> 8) iterationCallback.handleEdgeTablePixelFull (x); else @@ -57486,14 +58031,17 @@ protected: @see Drawable */ -class JUCE_API DrawableComposite : public Drawable +class JUCE_API DrawableComposite : public Drawable, + public RelativeCoordinate::NamedCoordinateFinder { public: - /** Creates a composite Drawable. - */ + /** Creates a composite Drawable. */ DrawableComposite(); + /** Creates a copy of a DrawableComposite. */ + DrawableComposite (const DrawableComposite& other); + /** Destructor. */ virtual ~DrawableComposite(); @@ -57572,27 +58120,43 @@ public: @param targetPositionForX0Y1 the position that the local coordinate (0, 1) should be mapped onto when rendering this object. */ - void setTransform (const Point& targetPositionForOrigin, - const Point& targetPositionForX1Y0, - const Point& targetPositionForX0Y1); + void setTransform (const RelativePoint& targetPositionForOrigin, + const RelativePoint& targetPositionForX1Y0, + const RelativePoint& targetPositionForX0Y1); /** Returns the position to which the local coordinate (0, 0) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } + const RelativePoint& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } /** Returns the position to which the local coordinate (1, 0) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } + const RelativePoint& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } /** Returns the position to which the local coordinate (0, 1) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } + const RelativePoint& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } + + struct Marker + { + Marker (const Marker&); + Marker (const String& name, const RelativeCoordinate& position, bool isOnXAxis); + bool operator!= (const Marker&) const throw(); + + String name; + RelativeCoordinate position; + bool isOnXAxis; + }; + + int getNumMarkers (bool xAxis) const throw(); + const Marker* getMarker (int index) const throw(); + void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position); + void removeMarker (int index); /** @internal */ void render (const Drawable::RenderingContext& context) const; @@ -57601,12 +58165,10 @@ public: /** @internal */ bool hitTest (float x, float y) const; /** @internal */ - int getNumControlPoints() const; - /** @internal */ - const Point getControlPoint (int index) const; - /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -57614,17 +58176,55 @@ public: static const Identifier valueTreeType; /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** @internal */ + const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; + + /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + int getNumDrawables() const; + const ValueTree getDrawableState (int index) const; + void addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager); + void moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager); + void removeDrawable (int index, UndoManager* undoManager); + + const RelativePoint getTargetPositionForOrigin() const; + void setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForX1Y0() const; + void setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForX0Y1() const; + void setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager); + + int getNumMarkers() const; + const Marker getMarker (int index) const; + void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager); + void removeMarker (int index, UndoManager* undoManager); + + private: + static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTag, + markerTag, nameProperty, xAxisProperty, posProperty; + + ValueTree getChildList() const; + ValueTree getChildListCreating (UndoManager* undoManager); + ValueTree getMarkerList() const; + ValueTree getMarkerListCreating (UndoManager* undoManager); + }; juce_UseDebuggingNewOperator private: OwnedArray drawables; - Point controlPoints[3]; + RelativePoint controlPoints[3]; + OwnedArray markers; const Rectangle getUntransformedBounds() const; - const AffineTransform getTransform() const; + const AffineTransform calculateTransform() const; - DrawableComposite (const DrawableComposite&); DrawableComposite& operator= (const DrawableComposite&); }; @@ -57649,6 +58249,7 @@ class JUCE_API DrawableImage : public Drawable public: DrawableImage(); + DrawableImage (const DrawableImage& other); /** Destructor. */ virtual ~DrawableImage(); @@ -57667,7 +58268,7 @@ public: with ImageCache and pass it in here with releaseWhenNotNeeded = true, then it'll be released neatly with its reference count being decreased. - @param imageToUse the image to render + @param imageToUse the image to render (may be a null pointer) @param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, then the image will be deleted when this object no longer needs it - unless the image was created by the ImageCache, @@ -57678,9 +58279,6 @@ public: /** Returns the current image. */ Image* getImage() const throw() { return image; } - /** Clears (and possibly deletes) the currently set image. */ - void clearImage(); - /** Sets the opacity to use when drawing the image. */ void setOpacity (float newOpacity); @@ -57711,27 +58309,27 @@ public: @param imageBottomLeftPosition the position that the image's bottom-left corner should be mapped to in the target coordinate space. */ - void setTransform (const Point& imageTopLeftPosition, - const Point& imageTopRightPosition, - const Point& imageBottomLeftPosition); + void setTransform (const RelativePoint& imageTopLeftPosition, + const RelativePoint& imageTopRightPosition, + const RelativePoint& imageBottomLeftPosition); /** Returns the position to which the image's top-left corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } + const RelativePoint& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } /** Returns the position to which the image's top-right corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } + const RelativePoint& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } /** Returns the position to which the image's bottom-left corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } + const RelativePoint& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } /** @internal */ void render (const Drawable::RenderingContext& context) const; @@ -57742,6 +58340,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -57750,6 +58350,34 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + const var getImageIdentifier() const; + void setImageIdentifier (const var& newIdentifier, UndoManager* undoManager); + + float getOpacity() const; + void setOpacity (float newOpacity, UndoManager* undoManager); + + const Colour getOverlayColour() const; + void setOverlayColour (const Colour& newColour, UndoManager* undoManager); + + const RelativePoint getTargetPositionForTopLeft() const; + void setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForTopRight() const; + void setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForBottomLeft() const; + void setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager); + + private: + static const Identifier opacity, overlay, image, topLeft, topRight, bottomLeft; + }; + juce_UseDebuggingNewOperator private: @@ -57757,11 +58385,10 @@ private: bool canDeleteImage; float opacity; Colour overlayColour; - Point controlPoints[3]; + RelativePoint controlPoints[3]; - const AffineTransform getTransform() const; + const AffineTransform calculateTransform() const; - DrawableImage (const DrawableImage&); DrawableImage& operator= (const DrawableImage&); }; @@ -57785,9 +58412,9 @@ class JUCE_API DrawablePath : public Drawable { public: - /** Creates a DrawablePath. - */ + /** Creates a DrawablePath. */ DrawablePath(); + DrawablePath (const DrawablePath& other); /** Destructor. */ virtual ~DrawablePath(); @@ -57798,9 +58425,6 @@ public: */ void setPath (const Path& newPath); - /** Returns the current path. */ - const Path& getPath() const throw() { return path; } - /** Sets a fill type for the path. This colour is used to fill the path - if you don't want the path to be @@ -57840,6 +58464,12 @@ public: /** Returns the current outline style. */ const PathStrokeType& getStrokeType() const throw() { return strokeType; } + /** Returns the current path. */ + const Path& getPath() const; + + /** Returns the current path for the outline. */ + const Path& getStrokePath() const; + /** @internal */ void render (const Drawable::RenderingContext& context) const; /** @internal */ @@ -57849,6 +58479,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -57857,16 +58489,41 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + const FillType getMainFill() const; + void setMainFill (const FillType& newFill, UndoManager* undoManager); + + const FillType getStrokeFill() const; + void setStrokeFill (const FillType& newFill, UndoManager* undoManager); + + const PathStrokeType getStrokeType() const; + void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); + + void getPath (RelativePointPath& path) const; + void setPath (const String& newPath, UndoManager* undoManager); + + private: + static const Identifier fill, stroke, jointStyle, capStyle, strokeWidth, path; + }; + juce_UseDebuggingNewOperator private: - Path path, stroke; FillType mainFill, strokeFill; PathStrokeType strokeType; + ScopedPointer relativePath; + mutable Path path, stroke; + mutable bool pathNeedsUpdating, strokeNeedsUpdating; - void updateOutline(); + void updatePath() const; + void updateStroke() const; + bool isStrokeVisible() const throw(); - DrawablePath (const DrawablePath&); DrawablePath& operator= (const DrawablePath&); }; @@ -57892,6 +58549,7 @@ public: /** Creates a DrawableText object. */ DrawableText(); + DrawableText (const DrawableText& other); /** Destructor. */ virtual ~DrawableText(); @@ -57925,6 +58583,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -57933,13 +58593,24 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + //xxx todo + + private: + static const Identifier text; + }; + juce_UseDebuggingNewOperator private: GlyphArrangement text; Colour colour; - DrawableText (const DrawableText&); DrawableText& operator= (const DrawableText&); }; @@ -58495,352 +59166,6 @@ private: #endif #ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ -/*** Start of inlined file: juce_RelativeCoordinate.h ***/ -#ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ -#define __JUCE_RELATIVECOORDINATE_JUCEHEADER__ - -/** - Expresses a coordinate as an absolute or proportional distance from other - named coordinates. - - A RelativeCoordinate represents a position as either: - - an absolute distance from the origin - - an absolute distance from another named RelativeCoordinate - - a proportion of the distance between two other named RelativeCoordinates - - Of course, the coordinates that this one is relative to may themselves be relative - to other coordinates, so complex arrangements can be built up (as long as you're careful - not to create recursive loops!) - - Rather than keeping pointers to the coordinates that this one is dependent on, it - stores their names, and when resolving this coordinate to an absolute value, a - NamedCoordinateFinder class is required to retrieve these coordinates by name. - - @see RelativePoint, RelativeRectangle -*/ -class JUCE_API RelativeCoordinate -{ -public: - - /** Creates a zero coordinate. */ - RelativeCoordinate(); - - /** Creates an absolute position from the parent origin on either the X or Y axis. - - @param absoluteDistanceFromOrigin the distance from the origin - @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. - */ - RelativeCoordinate (double absoluteDistanceFromOrigin, bool isHorizontal); - - /** Creates an absolute position relative to a named coordinate. - - @param absoluteDistanceFromAnchor the distance to add to the named anchor point - @param anchorPoint the name of the coordinate from which this one will be relative. See the constructor - notes for a description of the syntax for coordinate names. - */ - RelativeCoordinate (double absoluteDistanceFromAnchor, const String& anchorPoint); - - /** Creates a relative position between two named points. - - @param relativeProportionBetweenAnchors a value between 0 and 1 indicating this coordinate's relative position - between anchorPoint1 and anchorPoint2. - @param anchorPoint1 the name of the first coordinate from which this one will be relative. See the constructor - notes for a description of the syntax for coordinate names. - @param anchorPoint2 the name of the first coordinate from which this one will be relative. See the constructor - notes for a description of the syntax for coordinate names. - */ - RelativeCoordinate (double relativeProportionBetweenAnchors, const String& anchorPoint1, const String& anchorPoint2); - - /** Recreates a coordinate from a string description. - - The string can be in one of the following formats: - - "123" = 123 pixels from parent origin (this is equivalent to "parent.left + 123" - or "parent.top + 123", depending on which axis the coordinate is using) - - "anchor" = the same position as the coordinate named "anchor" - - "anchor + 123" = the coordinate named "anchor" + 123 pixels - - "anchor - 123" = the coordinate named "anchor" - 123 pixels - - "50%" = 50% of the distance between the coordinate space's top-left origin and its extent - (this is equivalent to "50% * parent.left -> parent.right" or "50% * parent.top -> parent.bottom") - - "50% * anchor" = 50% of the distance between the coordinate space's origin and the coordinate named "anchor" - (this is equivalent to "50% * parent.left -> anchor" or "50% * parent.top -> anchor") - - "50% * anchor1 -> anchor2" = 50% of the distance between the coordinate "anchor1" and the coordinate "anchor2" - - An anchor name can either be just a single identifier (letters, digits and underscores only - no spaces), - e.g. "marker1", or it can be a two-part name in the form "objectName.edge". For example "parent.left" is - the origin, or "myComponent.top" is the top edge of a component called "myComponent". The exact names that - will be recognised are dependent on the NamedCoordinateFinder that you provide for looking them up, but - "parent.left", "parent.top", "parent.right" and "parent.bottom" are always available, representing the - extents of the target coordinate space. - - @param stringVersion the string to parse - @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. - - @see toString - */ - RelativeCoordinate (const String& stringVersion, bool isHorizontal); - - /** Destructor. */ - ~RelativeCoordinate(); - - /** - Provides an interface for looking up the position of a named anchor when resolving a RelativeCoordinate. - - When using RelativeCoordinates, to resolve their names you need to provide a subclass of this which - can retrieve a coordinate by name. - */ - class JUCE_API NamedCoordinateFinder - { - public: - /** Destructor. */ - virtual ~NamedCoordinateFinder() {} - - /** Returns the coordinate for a given name. - - The objectName parameter will be the first section of the name, and the edge the name of the second part. - E.g. for "parent.right", objectName would be "parent" and edge would be "right". If the name - has no dot, the edge parameter will be an empty string. - - This method must be able to resolve "parent.left", "parent.top", "parent.right" and "parent.bottom", as - well as any other objects that your application uses. - */ - virtual const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const = 0; - }; - - /** Calculates the absolute position of this coordinate. - - You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may - be needed to calculate the result. - */ - double resolve (const NamedCoordinateFinder& nameFinder) const; - - /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. - This will recursively check any coordinates upon which this one depends. - */ - bool references (const String& coordName, const NamedCoordinateFinder& nameFinder) const; - - /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ - bool isRecursive (const NamedCoordinateFinder& nameFinder) const; - - /** Changes the value of this coord to make it resolve to the specified position. - - Calling this will leave the anchor points unchanged, but will set this coordinate's absolute - or relative position to whatever value is necessary to make its resultant position - match the position that is provided. - */ - void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder& nameFinder); - - /** Returns true if the coordinate is calculated as a proportion of the distance between two other points. - @see toggleProportionality - */ - bool isProportional() const throw() { return anchor2.isNotEmpty(); } - - /** Toggles the coordinate between using a proportional or absolute position. - Note that calling this will reset the names of any anchor points, and just make the - coordinate relative to the parent origin and parent size. - */ - void toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal); - - /** Returns a value that can be edited to set this coordinate's position. - The meaning of this number depends on the coordinate's mode. If the coordinate is - proportional, the number will be a percentage between 0 and 100. If the - coordinate is absolute, then it will be the number of pixels from its anchor point. - @see setEditableNumber - */ - const double getEditableNumber() const; - - /** Sets the value that controls this coordinate's position. - The meaning of this number depends on the coordinate's mode. If the coordinate is - proportional, the number must be a percentage between 0 and 100. If the - coordinate is absolute, then it indicates the number of pixels from its anchor point. - @see setEditableNumber - */ - void setEditableNumber (const double newValue); - - /** Returns the name of the first anchor point from which this coordinate is relative. - */ - const String getAnchorName1() const { return anchor1; } - - /** Returns the name of the second anchor point from which this coordinate is relative. - The second anchor is only valid if the coordinate is in proportional mode. - */ - const String getAnchorName2() const { return anchor2; } - - /** Returns the first anchor point as a coordinate. */ - const RelativeCoordinate getAnchorCoordinate1() const; - - /** Returns the first anchor point as a coordinate. - The second anchor is only valid if the coordinate is in proportional mode. - */ - const RelativeCoordinate getAnchorCoordinate2() const; - - /** Changes the first anchor point, keeping the resultant position of this coordinate in - the same place it was previously. - */ - void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); - - /** Changes the second anchor point, keeping the resultant position of this coordinate in - the same place it was previously. - */ - void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); - - /** Tells the coordinate that an object is changing its name or being deleted. - - If either of this coordinates anchor points match this name, they will be replaced. - If the newName string is empty, it indicates that the object is being removed, so if - this coordinate was using it, the coordinate is changed to be relative to the origin - instead. - */ - void renameAnchorIfUsed (const String& oldName, const String& newName, - const NamedCoordinateFinder& nameFinder); - - /** Returns a string which represents this coordinate. - For details of the string syntax, see the constructor notes. - */ - const String toString() const; - - /** A set of static strings that are commonly used by the RelativeCoordinate class. - - As well as avoiding using string literals in your code, using these preset values - has the advantage that all instances of the same string will share the same, reference-counted - String object, so if you have thousands of points which all refer to the same - anchor points, this can save a significant amount of memory allocation. - */ - struct Strings - { - static const String parent; /**< "parent" */ - static const String left; /**< "left" */ - static const String right; /**< "right" */ - static const String top; /**< "top" */ - static const String bottom; /**< "bottom" */ - static const String parentLeft; /**< "parent.left" */ - static const String parentTop; /**< "parent.top" */ - static const String parentRight; /**< "parent.right" */ - static const String parentBottom; /**< "parent.bottom" */ - }; - -private: - - String anchor1, anchor2; - double value; - - double resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const; - static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter); -}; - -/** - An X-Y position stored as a pair of RelativeCoordinate values. - - @see RelativeCoordinate, RelativeRectangle -*/ -class JUCE_API RelativePoint -{ -public: - /** Creates a point at the origin. */ - RelativePoint(); - - /** Creates an absolute point, relative to the origin. */ - RelativePoint (const Point& absolutePoint); - - /** Creates a point from a stringified representation. - The string must contain a pair of coordinates, separated by a comma. The syntax for the coordinate - strings is explained in the RelativeCoordinate class. - @see toString - */ - RelativePoint (const String& stringVersion); - - /** Calculates the absolute position of this point. - - You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may - be needed to calculate the result. - */ - const Point resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; - - /** Changes the values of this point's coordinates to make it resolve to the specified position. - - Calling this will leave any anchor points unchanged, but will set any absolute - or relative positions to whatever values are necessary to make the resultant position - match the position that is provided. - */ - void moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); - - /** Returns a string which represents this point. - This returns a comma-separated pair of coordinates. For details of the string syntax used by the - coordinates, see the RelativeCoordinate constructor notes. - The string that is returned can be passed to the RelativePoint constructor to recreate the point. - */ - const String toString() const; - - /** Tells the point that an object is changing its name or being deleted. - This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. - */ - void renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder); - - // The actual X and Y coords... - RelativeCoordinate x, y; -}; - -/** - An rectangle stored as a set of RelativeCoordinate values. - - The rectangle's top, left, bottom and right edge positions are each stored as a RelativeCoordinate. - - @see RelativeCoordinate, RelativePoint -*/ -class JUCE_API RelativeRectangle -{ -public: - - /** Creates a zero-size rectangle at the origin. */ - RelativeRectangle(); - - /** Creates an absolute rectangle, relative to the origin. */ - explicit RelativeRectangle (const Rectangle& rect, const String& componentName); - - /** Creates a rectangle from a stringified representation. - The string must contain a sequence of 4 coordinates, separated by commas, in the order - left, top, right, bottom. The syntax for the coordinate strings is explained in the - RelativeCoordinate class. - @see toString - */ - explicit RelativeRectangle (const String& stringVersion); - - /** Calculates the absolute position of this rectangle. - - You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may - be needed to calculate the result. - */ - const Rectangle resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; - - /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. - - Calling this will leave any anchor points unchanged, but will set any absolute - or relative positions to whatever values are necessary to make the resultant position - match the position that is provided. - */ - void moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); - - /** Returns a string which represents this point. - This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of - the string syntax used by the coordinates, see the RelativeCoordinate constructor notes. - The string that is returned can be passed to the RelativeRectangle constructor to recreate the rectangle. - */ - const String toString() const; - - /** Tells the rectangle that an object is changing its name or being deleted. - This calls RelativeCoordinate::renameAnchorIfUsed() on the rectangle's coordinates. - */ - void renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder); - - // The actual rectangle coords... - RelativeCoordinate left, right, top, bottom; -}; - -#endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__ -/*** End of inlined file: juce_RelativeCoordinate.h ***/ - - #endif #ifndef __JUCE_CAMERADEVICE_JUCEHEADER__ diff --git a/src/containers/juce_Array.h b/src/containers/juce_Array.h index 799cc9fab2..fe7ff9e3ea 100644 --- a/src/containers/juce_Array.h +++ b/src/containers/juce_Array.h @@ -150,7 +150,7 @@ public: return false; for (int i = numUsed; --i >= 0;) - if (data.elements [i] != other.data.elements [i]) + if (! (data.elements [i] == other.data.elements [i])) return false; return true; diff --git a/src/containers/juce_NamedValueSet.cpp b/src/containers/juce_NamedValueSet.cpp index e6ae1c033e..c8bbedde1d 100644 --- a/src/containers/juce_NamedValueSet.cpp +++ b/src/containers/juce_NamedValueSet.cpp @@ -40,6 +40,11 @@ inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var { } +bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const throw() +{ + return name == other.name && value == other.value; +} + //============================================================================== NamedValueSet::NamedValueSet() throw() { @@ -60,6 +65,16 @@ NamedValueSet::~NamedValueSet() { } +bool NamedValueSet::operator== (const NamedValueSet& other) const +{ + return values == other.values; +} + +bool NamedValueSet::operator!= (const NamedValueSet& other) const +{ + return ! operator== (other); +} + int NamedValueSet::size() const throw() { return values.size(); diff --git a/src/containers/juce_NamedValueSet.h b/src/containers/juce_NamedValueSet.h index 1edf78d4fb..51651a21ef 100644 --- a/src/containers/juce_NamedValueSet.h +++ b/src/containers/juce_NamedValueSet.h @@ -51,6 +51,9 @@ public: /** Destructor. */ ~NamedValueSet(); + bool operator== (const NamedValueSet& other) const; + bool operator!= (const NamedValueSet& other) const; + //============================================================================== /** Returns the total number of values that the set contains. */ int size() const throw(); @@ -108,6 +111,7 @@ private: { NamedValue() throw(); NamedValue (const Identifier& name, const var& value); + bool operator== (const NamedValue& other) const throw(); Identifier name; var value; diff --git a/src/containers/juce_ValueTree.cpp b/src/containers/juce_ValueTree.cpp index 298f568215..a4d1f4d714 100644 --- a/src/containers/juce_ValueTree.cpp +++ b/src/containers/juce_ValueTree.cpp @@ -500,6 +500,22 @@ void ValueTree::SharedObject::moveChild (int currentIndex, int newIndex, UndoMan } } +bool ValueTree::SharedObject::isEquivalentTo (const SharedObject& other) const +{ + if (type != other.type + || properties.size() != other.properties.size() + || children.size() != other.children.size() + || properties != other.properties) + return false; + + for (int i = 0; i < children.size(); ++i) + if (! children.getUnchecked(i)->isEquivalentTo (*other.children.getUnchecked(i))) + return false; + + return true; +} + + //============================================================================== ValueTree::ValueTree() throw() : object (0) @@ -546,16 +562,22 @@ ValueTree::~ValueTree() object->valueTreesWithListeners.removeValue (this); } -bool ValueTree::operator== (const ValueTree& other) const +bool ValueTree::operator== (const ValueTree& other) const throw() { return object == other.object; } -bool ValueTree::operator!= (const ValueTree& other) const +bool ValueTree::operator!= (const ValueTree& other) const throw() { return object != other.object; } +bool ValueTree::isEquivalentTo (const ValueTree& other) const +{ + return object == other.object + || (object != 0 && other.object != 0 && object->isEquivalentTo (*other.object)); +} + ValueTree ValueTree::createCopy() const { return ValueTree (object != 0 ? new SharedObject (*object) : 0); @@ -710,7 +732,7 @@ int ValueTree::indexOf (const ValueTree& child) const return object != 0 ? object->indexOf (child) : -1; } -void ValueTree::addChild (ValueTree child, int index, UndoManager* const undoManager) +void ValueTree::addChild (const ValueTree& child, int index, UndoManager* const undoManager) { if (object != 0) object->addChild (child.object, index, undoManager); diff --git a/src/containers/juce_ValueTree.h b/src/containers/juce_ValueTree.h index d486c0f77e..e6067b6ea3 100644 --- a/src/containers/juce_ValueTree.h +++ b/src/containers/juce_ValueTree.h @@ -102,13 +102,21 @@ public: Note that this isn't a value comparison - two independently-created trees which contain identical data are not considered equal. */ - bool operator== (const ValueTree& other) const; + bool operator== (const ValueTree& other) const throw(); /** Returns true if this and the other node refer to different underlying structures. Note that this isn't a value comparison - two independently-created trees which contain identical data are not considered equal. */ - bool operator!= (const ValueTree& other) const; + bool operator!= (const ValueTree& other) const throw(); + + /** Performs a deep comparison between the properties and children of two trees. + If all the properties and children of the two trees are the same (recursively), this + returns true. + The normal operator==() only checks whether two trees refer to the same shared data + structure, so use this method if you need to do a proper value comparison. + */ + bool isEquivalentTo (const ValueTree& other) const; //============================================================================== /** Returns true if this node refers to some valid data. @@ -233,7 +241,7 @@ public: If the undoManager parameter is non-null, its UndoManager::perform() method will be used, so that this change can be undone. */ - void addChild (ValueTree child, int index, UndoManager* undoManager); + void addChild (const ValueTree& child, int index, UndoManager* undoManager); /** Removes the specified child from this node's child-list. If the undoManager parameter is non-null, its UndoManager::perform() method will be used, @@ -464,6 +472,7 @@ private: void removeChild (int childIndex, UndoManager*); void removeAllChildren (UndoManager*); void moveChild (int currentIndex, int newIndex, UndoManager*); + bool isEquivalentTo (const SharedObject& other) const; XmlElement* createXml() const; juce_UseDebuggingNewOperator diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 4a8c113a4a..0a4dcc70ae 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 52 -#define JUCE_BUILDNUMBER 5 +#define JUCE_BUILDNUMBER 6 /** Current Juce version number. diff --git a/src/gui/components/controls/juce_ListBox.cpp b/src/gui/components/controls/juce_ListBox.cpp index 0b87b9c69f..d0651f1a03 100644 --- a/src/gui/components/controls/juce_ListBox.cpp +++ b/src/gui/components/controls/juce_ListBox.cpp @@ -877,8 +877,7 @@ void ListBox::setHeaderComponent (Component* const newHeaderComponent) void ListBox::repaintRow (const int rowNumber) throw() { - const Rectangle r (getRowPosition (rowNumber, true)); - repaint (r.getX(), r.getY(), r.getWidth(), r.getHeight()); + repaint (getRowPosition (rowNumber, true)); } Image* ListBox::createSnapshotOfSelectedRows (int& imageX, int& imageY) diff --git a/src/gui/components/controls/juce_TreeView.cpp b/src/gui/components/controls/juce_TreeView.cpp index ac61f0c461..bbaacfdcd1 100644 --- a/src/gui/components/controls/juce_TreeView.cpp +++ b/src/gui/components/controls/juce_TreeView.cpp @@ -1338,8 +1338,9 @@ void TreeViewItem::repaintItem() const { if (ownerView != 0 && areAllParentsOpen()) { - const Rectangle r (getItemPosition (true)); - ownerView->viewport->repaint (0, r.getY(), r.getRight(), r.getHeight()); + Rectangle r (getItemPosition (true)); + r.setLeft (0); + ownerView->viewport->repaint (r); } } diff --git a/src/gui/components/juce_Component.cpp b/src/gui/components/juce_Component.cpp index eca866f7da..0be02f9cf7 100644 --- a/src/gui/components/juce_Component.cpp +++ b/src/gui/components/juce_Component.cpp @@ -1555,6 +1555,11 @@ void Component::repaint (const int x, const int y, internalRepaint (x, y, w, h); } +void Component::repaint (const Rectangle& area) +{ + repaint (area.getX(), area.getY(), area.getWidth(), area.getHeight()); +} + void Component::internalRepaint (int x, int y, int w, int h) { // if component methods are being called from threads other than the message @@ -1596,7 +1601,7 @@ void Component::internalRepaint (int x, int y, int w, int h) ComponentPeer* const peer = getPeer(); if (peer != 0) - peer->repaint (x, y, w, h); + peer->repaint (Rectangle (x, y, w, h)); } } } diff --git a/src/gui/components/juce_Component.h b/src/gui/components/juce_Component.h index 1cb0984943..9e9c6c9f25 100644 --- a/src/gui/components/juce_Component.h +++ b/src/gui/components/juce_Component.h @@ -819,6 +819,21 @@ public: */ void repaint (int x, int y, int width, int height); + /** Marks a subsection of this component as needing to be redrawn. + + Calling this will not do any repainting immediately, but will mark the given region + of the component as 'dirty'. At some point in the near future the operating system + will send a paint message, which will redraw all the dirty regions of all components. + There's no guarantee about how soon after calling repaint() the redraw will actually + happen, and other queued events may be delivered before a redraw is done. + + The region that is passed in will be clipped to keep it within the bounds of this + component. + + @see repaint() + */ + void repaint (const Rectangle& area); + //============================================================================== /** Makes the component use an internal buffer to optimise its redrawing. diff --git a/src/gui/components/special/juce_MagnifierComponent.cpp b/src/gui/components/special/juce_MagnifierComponent.cpp index dcfb15bdd8..82c8496951 100644 --- a/src/gui/components/special/juce_MagnifierComponent.cpp +++ b/src/gui/components/special/juce_MagnifierComponent.cpp @@ -117,14 +117,14 @@ public: && ((unsigned int) position.getY()) < (unsigned int) magnifierComp->getHeight(); } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { const double zoom = magnifierComp->getScaleFactor(); - magnifierComp->repaint ((int) (x * zoom), - (int) (y * zoom), - roundToInt (w * zoom) + 1, - roundToInt (h * zoom) + 1); + magnifierComp->repaint ((int) (area.getX() * zoom), + (int) (area.getY() * zoom), + roundToInt (area.getWidth() * zoom) + 1, + roundToInt (area.getHeight() * zoom) + 1); } void performAnyPendingRepaintsNow() diff --git a/src/gui/components/windows/juce_ComponentPeer.h b/src/gui/components/windows/juce_ComponentPeer.h index 89ae594060..753544c9b3 100644 --- a/src/gui/components/windows/juce_ComponentPeer.h +++ b/src/gui/components/windows/juce_ComponentPeer.h @@ -281,7 +281,7 @@ public: //============================================================================== /** Invalidates a region of the window to be repainted asynchronously. */ - virtual void repaint (int x, int y, int w, int h) = 0; + virtual void repaint (const Rectangle& area) = 0; /** This can be called (from the message thread) to cause the immediate redrawing of any areas of this window that need repainting. diff --git a/src/gui/components/windows/juce_DocumentWindow.cpp b/src/gui/components/windows/juce_DocumentWindow.cpp index c1ca71b48a..d11add29ce 100644 --- a/src/gui/components/windows/juce_DocumentWindow.cpp +++ b/src/gui/components/windows/juce_DocumentWindow.cpp @@ -95,9 +95,7 @@ DocumentWindow::~DocumentWindow() //============================================================================== void DocumentWindow::repaintTitleBar() { - const Rectangle titleBarArea (getTitleBarArea()); - repaint (titleBarArea.getX(), titleBarArea.getY(), - titleBarArea.getWidth(), titleBarArea.getHeight()); + repaint (getTitleBarArea()); } void DocumentWindow::setName (const String& newName) diff --git a/src/gui/graphics/contexts/juce_EdgeTable.h b/src/gui/graphics/contexts/juce_EdgeTable.h index 29a312eaa5..da971b1e20 100644 --- a/src/gui/graphics/contexts/juce_EdgeTable.h +++ b/src/gui/graphics/contexts/juce_EdgeTable.h @@ -177,12 +177,13 @@ public: x = endX; } + levelAccumulator >>= 8; + if (levelAccumulator > 0) { x >>= 8; jassert (x >= bounds.getX() && x < bounds.getRight()); - levelAccumulator >>= 8; if (levelAccumulator >> 8) iterationCallback.handleEdgeTablePixelFull (x); else diff --git a/src/gui/graphics/contexts/juce_FillType.cpp b/src/gui/graphics/contexts/juce_FillType.cpp index db52d7522f..09f008d78a 100644 --- a/src/gui/graphics/contexts/juce_FillType.cpp +++ b/src/gui/graphics/contexts/juce_FillType.cpp @@ -76,6 +76,16 @@ FillType::~FillType() throw() { } +bool FillType::operator== (const FillType& other) const +{ + return colour == other.colour && gradient == other.gradient && image == other.image; +} + +bool FillType::operator!= (const FillType& other) const +{ + return ! operator== (other); +} + void FillType::setColour (const Colour& newColour) throw() { gradient = 0; @@ -110,4 +120,10 @@ void FillType::setOpacity (const float newOpacity) throw() colour = colour.withAlpha (newOpacity); } +bool FillType::isInvisible() const throw() +{ + return colour.isTransparent() || (gradient != 0 && gradient->isInvisible()); +} + + END_JUCE_NAMESPACE diff --git a/src/gui/graphics/contexts/juce_FillType.h b/src/gui/graphics/contexts/juce_FillType.h index 1a5d1fbfbf..45eaf94a64 100644 --- a/src/gui/graphics/contexts/juce_FillType.h +++ b/src/gui/graphics/contexts/juce_FillType.h @@ -103,6 +103,12 @@ public: */ float getOpacity() const throw() { return colour.getFloatAlpha(); } + /** Returns true if this fill type is completely transparent. */ + bool isInvisible() const throw(); + + bool operator== (const FillType& other) const; + bool operator!= (const FillType& other) const; + /** The solid colour being used. If the fill type is not a solid colour, the alpha channel of this colour indicates diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index de32266f3d..25937be6d4 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -1899,41 +1899,38 @@ public: shapeToFill = clip->applyClipTo (shapeToFill); if (shapeToFill != 0) - fillShapeWithoutClipping (image, shapeToFill, replaceContents); - } + { + Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); - void fillShapeWithoutClipping (Image& image, const SoftwareRendererClasses::ClipRegionBase::Ptr& shapeToFill, const bool replaceContents) - { - Image::BitmapData destData (image, 0, 0, image.getWidth(), image.getHeight(), true); + if (fillType.isGradient()) + { + jassert (! replaceContents); // that option is just for solid colours - if (fillType.isGradient()) - { - jassert (! replaceContents); // that option is just for solid colours + ColourGradient g2 (*(fillType.gradient)); + g2.multiplyOpacity (fillType.getOpacity()); + g2.point1.addXY (-0.5f, -0.5f); + g2.point2.addXY (-0.5f, -0.5f); + AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); + const bool isIdentity = transform.isOnlyTranslation(); - ColourGradient g2 (*(fillType.gradient)); - g2.multiplyOpacity (fillType.getOpacity()); - g2.point1.addXY (-0.5f, -0.5f); - g2.point2.addXY (-0.5f, -0.5f); - AffineTransform transform (fillType.transform.translated ((float) xOffset, (float) yOffset)); - const bool isIdentity = transform.isOnlyTranslation(); + if (isIdentity) + { + // If our translation doesn't involve any distortion, we can speed it up.. + g2.point1.applyTransform (transform); + g2.point2.applyTransform (transform); + transform = AffineTransform::identity; + } - if (isIdentity) + shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); + } + else if (fillType.isTiledImage()) { - // If our translation doesn't involve any distortion, we can speed it up.. - g2.point1.applyTransform (transform); - g2.point2.applyTransform (transform); - transform = AffineTransform::identity; + renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); + } + else + { + shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); } - - shapeToFill->fillAllWithGradient (destData, g2, transform, isIdentity); - } - else if (fillType.isTiledImage()) - { - renderImage (image, *(fillType.image), fillType.image->getBounds(), fillType.transform, shapeToFill); - } - else - { - shapeToFill->fillAllWithColour (destData, fillType.colour.getPixelARGB(), replaceContents); } } diff --git a/src/gui/graphics/drawables/juce_Drawable.cpp b/src/gui/graphics/drawables/juce_Drawable.cpp index db551443b5..3f5f0a089e 100644 --- a/src/gui/graphics/drawables/juce_Drawable.cpp +++ b/src/gui/graphics/drawables/juce_Drawable.cpp @@ -36,7 +36,6 @@ BEGIN_JUCE_NAMESPACE #include "../../../text/juce_XmlDocument.h" #include "../../../io/files/juce_FileInputStream.h" -const Identifier Drawable::idProperty ("id"); //============================================================================== Drawable::RenderingContext::RenderingContext (Graphics& g_, @@ -50,6 +49,7 @@ Drawable::RenderingContext::RenderingContext (Graphics& g_, //============================================================================== Drawable::Drawable() + : parent (0) { } @@ -57,8 +57,7 @@ Drawable::~Drawable() { } -void Drawable::draw (Graphics& g, const float opacity, - const AffineTransform& transform) const +void Drawable::draw (Graphics& g, const float opacity, const AffineTransform& transform) const { render (RenderingContext (g, transform, opacity)); } @@ -156,4 +155,131 @@ Drawable* Drawable::createFromValueTree (const ValueTree& tree, ImageProvider* i } +//============================================================================== +const Identifier Drawable::ValueTreeWrapperBase::idProperty ("id"); +const Identifier Drawable::ValueTreeWrapperBase::type ("type"); +const Identifier Drawable::ValueTreeWrapperBase::x1 ("x1"); +const Identifier Drawable::ValueTreeWrapperBase::x2 ("x2"); +const Identifier Drawable::ValueTreeWrapperBase::y1 ("y1"); +const Identifier Drawable::ValueTreeWrapperBase::y2 ("y2"); +const Identifier Drawable::ValueTreeWrapperBase::colour ("colour"); +const Identifier Drawable::ValueTreeWrapperBase::radial ("radial"); +const Identifier Drawable::ValueTreeWrapperBase::colours ("colours"); + +Drawable::ValueTreeWrapperBase::ValueTreeWrapperBase (const ValueTree& state_) + : state (state_) +{ +} + +Drawable::ValueTreeWrapperBase::~ValueTreeWrapperBase() +{ +} + +const String Drawable::ValueTreeWrapperBase::getID() const +{ + return state [idProperty]; +} + +void Drawable::ValueTreeWrapperBase::setID (const String& newID, UndoManager* undoManager) +{ + if (newID.isEmpty()) + state.removeProperty (idProperty, undoManager); + else + state.setProperty (idProperty, newID, undoManager); +} + +const FillType Drawable::ValueTreeWrapperBase::readFillType (const ValueTree& v) +{ + const String newType (v[type].toString()); + + if (newType == "solid") + { + const String colourString (v [colour].toString()); + return FillType (Colour (colourString.isEmpty() ? (uint32) 0xff000000 + : (uint32) colourString.getHexValue32())); + } + else if (newType == "gradient") + { + ColourGradient g; + g.point1.setXY (v[x1], v[y1]); + g.point2.setXY (v[x2], v[y2]); + g.isRadial = v[radial]; + + StringArray colourSteps; + colourSteps.addTokens (v[colours].toString(), false); + + for (int i = 0; i < colourSteps.size() / 2; ++i) + g.addColour (colourSteps[i * 2].getDoubleValue(), + Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); + + return FillType (g); + } + else if (newType == "image") + { + jassertfalse; //xxx todo + } + + jassertfalse; + return FillType(); +} + +void Drawable::ValueTreeWrapperBase::replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager) +{ + ValueTree v (state.getChildWithName (tag)); + + if (! v.isValid()) + { + state.addChild (ValueTree (tag), -1, undoManager); + v = state.getChildWithName (tag); + } + + if (fillType.isColour()) + { + v.setProperty (type, "solid", undoManager); + v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), undoManager); + v.removeProperty (x1, undoManager); + v.removeProperty (x2, undoManager); + v.removeProperty (y1, undoManager); + v.removeProperty (y2, undoManager); + v.removeProperty (radial, undoManager); + v.removeProperty (colours, undoManager); + } + else if (fillType.isGradient()) + { + v.setProperty (type, "gradient", undoManager); + v.setProperty (x1, fillType.gradient->point1.getX(), undoManager); + v.setProperty (y1, fillType.gradient->point1.getY(), undoManager); + v.setProperty (x2, fillType.gradient->point2.getX(), undoManager); + v.setProperty (y2, fillType.gradient->point2.getY(), undoManager); + v.setProperty (radial, fillType.gradient->isRadial, undoManager); + + String s; + for (int i = 0; i < fillType.gradient->getNumColours(); ++i) + s << " " << fillType.gradient->getColourPosition (i) + << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); + + v.setProperty (colours, s.trimStart(), undoManager); + v.removeProperty (colour, undoManager); + } + else if (fillType.isTiledImage()) + { + v.setProperty (type, "image", undoManager); + + jassertfalse; //xxx todo + + v.removeProperty (x1, undoManager); + v.removeProperty (x2, undoManager); + v.removeProperty (y1, undoManager); + v.removeProperty (y2, undoManager); + v.removeProperty (radial, undoManager); + v.removeProperty (colours, undoManager); + v.removeProperty (colour, undoManager); + } + else + { + jassertfalse; + } +} + + END_JUCE_NAMESPACE diff --git a/src/gui/graphics/drawables/juce_Drawable.h b/src/gui/graphics/drawables/juce_Drawable.h index e8469b9ca0..be16e60540 100644 --- a/src/gui/graphics/drawables/juce_Drawable.h +++ b/src/gui/graphics/drawables/juce_Drawable.h @@ -27,8 +27,10 @@ #define __JUCE_DRAWABLE_JUCEHEADER__ #include "../contexts/juce_Graphics.h" +#include "../geometry/juce_RelativeCoordinate.h" #include "../../../text/juce_XmlElement.h" #include "../../../containers/juce_ValueTree.h" +class DrawableComposite; //============================================================================== @@ -229,11 +231,34 @@ public: /** Returns the tag ID that is used for a ValueTree that stores this type of drawable. */ virtual const Identifier getValueTreeType() const = 0; + //============================================================================== + /** Internal class used to manage ValueTrees that represent Drawables. */ + class ValueTreeWrapperBase + { + public: + ValueTreeWrapperBase (const ValueTree& state); + ~ValueTreeWrapperBase(); + + ValueTree& getState() throw() { return state; } + + const String getID() const; + void setID (const String& newID, UndoManager* undoManager); + + protected: + ValueTree state; + static const Identifier idProperty, type, x1, x2, y1, y2, colour, radial, colours; + + static const FillType readFillType (const ValueTree& v); + void replaceFillType (const Identifier& tag, const FillType& fillType, UndoManager* undoManager); + }; + //============================================================================== juce_UseDebuggingNewOperator protected: - static const Identifier idProperty; + friend class DrawableComposite; + DrawableComposite* parent; + virtual void invalidatePoints() = 0; private: String name; diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.cpp b/src/gui/graphics/drawables/juce_DrawableComposite.cpp index f42a9d7dc3..a906ee5786 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.cpp +++ b/src/gui/graphics/drawables/juce_DrawableComposite.cpp @@ -37,8 +37,21 @@ BEGIN_JUCE_NAMESPACE //============================================================================== DrawableComposite::DrawableComposite() { - controlPoints[1].setXY (1.0f, 0.0f); - controlPoints[2].setXY (0.0f, 1.0f); + controlPoints[1] = RelativePoint (Point (1.0f, 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, 1.0f)); +} + +DrawableComposite::DrawableComposite (const DrawableComposite& other) +{ + int i; + for (i = 0; i < 3; ++i) + controlPoints[i] = other.controlPoints[i]; + + for (i = 0; i < drawables.size(); ++i) + drawables.add (other.drawables.getUnchecked(i)->createCopy()); + + for (i = 0; i < markers.size(); ++i) + markers.add (new Marker (*other.markers.getUnchecked(i))); } DrawableComposite::~DrawableComposite() @@ -51,7 +64,9 @@ void DrawableComposite::insertDrawable (Drawable* drawable, const int index) if (drawable != 0) { jassert (! drawables.contains (drawable)); // trying to add a drawable that's already in here! + jassert (drawable->parent == 0); // A drawable can only live inside one parent at a time! drawables.insert (index, drawable); + drawable->parent = this; } } @@ -71,9 +86,9 @@ void DrawableComposite::bringToFront (const int index) drawables.move (index, -1); } -void DrawableComposite::setTransform (const Point& targetPositionForOrigin, - const Point& targetPositionForX1Y0, - const Point& targetPositionForX0Y1) +void DrawableComposite::setTransform (const RelativePoint& targetPositionForOrigin, + const RelativePoint& targetPositionForX1Y0, + const RelativePoint& targetPositionForX0Y1) { controlPoints[0] = targetPositionForOrigin; controlPoints[1] = targetPositionForX1Y0; @@ -81,11 +96,70 @@ void DrawableComposite::setTransform (const Point& targetPositionForOrigi } //============================================================================== -const AffineTransform DrawableComposite::getTransform() const +DrawableComposite::Marker::Marker (const DrawableComposite::Marker& other) + : name (other.name), position (other.position), isOnXAxis (other.isOnXAxis) +{ +} + +DrawableComposite::Marker::Marker (const String& name_, const RelativeCoordinate& position_, const bool isOnXAxis_) + : name (name_), position (position_), isOnXAxis (isOnXAxis_) +{ +} + +bool DrawableComposite::Marker::operator!= (const DrawableComposite::Marker& other) const throw() +{ + return name != other.name || position != other.position || isOnXAxis != other.isOnXAxis; +} + +//============================================================================== +int DrawableComposite::getNumMarkers (bool xAxis) const throw() +{ + return markers.size(); +} + +const DrawableComposite::Marker* DrawableComposite::getMarker (int index) const throw() +{ + return markers [index]; +} + +void DrawableComposite::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position) +{ + for (int i = 0; i < markers.size(); ++i) + { + Marker* const m = markers.getUnchecked(i); + if (m->name == name) + { + jassert (m->isOnXAxis == xAxis); // trying to either have two markers with the same name on different axes? + + if (m->position != position) + { + m->position = position; + invalidatePoints(); + } + + return; + } + } + + markers.add (new Marker (name, position, xAxis)); + invalidatePoints(); +} + +void DrawableComposite::removeMarker (int index) { - return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), - controlPoints[1].getX(), controlPoints[1].getY(), - controlPoints[2].getX(), controlPoints[2].getY()); + markers.remove (index); +} + +//============================================================================== +const AffineTransform DrawableComposite::calculateTransform() const +{ + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); + + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), + resolved[1].getX(), resolved[1].getY(), + resolved[2].getX(), resolved[2].getY()); } void DrawableComposite::render (const Drawable::RenderingContext& context) const @@ -95,7 +169,7 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const if (context.opacity >= 1.0f || drawables.size() == 1) { Drawable::RenderingContext contextCopy (context); - contextCopy.transform = getTransform().followedBy (context.transform); + contextCopy.transform = calculateTransform().followedBy (context.transform); for (int i = 0; i < drawables.size(); ++i) drawables.getUnchecked(i)->render (contextCopy); @@ -121,6 +195,33 @@ void DrawableComposite::render (const Drawable::RenderingContext& context) const } } +const RelativeCoordinate DrawableComposite::findNamedCoordinate (const String& objectName, const String& edge) const +{ + if (objectName == RelativeCoordinate::Strings::parent) + { + if (edge == RelativeCoordinate::Strings::right) + { + jassertfalse; // a Drawable doesn't have a fixed right-hand edge - use a marker instead if you need a point of reference. + return RelativeCoordinate (100.0, true); + } + + if (edge == RelativeCoordinate::Strings::bottom) + { + jassertfalse; // a Drawable doesn't have a fixed bottom edge - use a marker instead if you need a point of reference. + return RelativeCoordinate (100.0, false); + } + } + + for (int i = 0; i < markers.size(); ++i) + { + Marker* const m = markers.getUnchecked(i); + if (m->name == objectName) + return m->position; + } + + return RelativeCoordinate(); +} + const Rectangle DrawableComposite::getUntransformedBounds() const { Rectangle bounds; @@ -133,12 +234,12 @@ const Rectangle DrawableComposite::getUntransformedBounds() const const Rectangle DrawableComposite::getBounds() const { - return getUntransformedBounds().transformed (getTransform()); + return getUntransformedBounds().transformed (calculateTransform()); } bool DrawableComposite::hitTest (float x, float y) const { - getTransform().inverted().transformPoint (x, y); + calculateTransform().inverted().transformPoint (x, y); for (int i = 0; i < drawables.size(); ++i) if (drawables.getUnchecked(i)->hitTest (x, y)) @@ -149,125 +250,282 @@ bool DrawableComposite::hitTest (float x, float y) const Drawable* DrawableComposite::createCopy() const { - DrawableComposite* const dc = new DrawableComposite(); - - for (int i = 0; i < 3; ++i) - dc->controlPoints[i] = controlPoints[i]; + return new DrawableComposite (*this); +} +void DrawableComposite::invalidatePoints() +{ for (int i = 0; i < drawables.size(); ++i) - dc->drawables.add (drawables.getUnchecked(i)->createCopy()); - - return dc; + drawables.getUnchecked(i)->invalidatePoints(); } //============================================================================== const Identifier DrawableComposite::valueTreeType ("Group"); -namespace DrawableCompositeHelpers +const Identifier DrawableComposite::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableComposite::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableComposite::ValueTreeWrapper::bottomLeft ("bottomLeft"); +const Identifier DrawableComposite::ValueTreeWrapper::childGroupTag ("Drawables"); +const Identifier DrawableComposite::ValueTreeWrapper::markerGroupTag ("Markers"); +const Identifier DrawableComposite::ValueTreeWrapper::markerTag ("Marker"); +const Identifier DrawableComposite::ValueTreeWrapper::nameProperty ("name"); +const Identifier DrawableComposite::ValueTreeWrapper::xAxisProperty ("xAxis"); +const Identifier DrawableComposite::ValueTreeWrapper::posProperty ("position"); + +//============================================================================== +DrawableComposite::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getChildList() const +{ + return state.getChildWithName (childGroupTag); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getChildListCreating (UndoManager* undoManager) +{ + const ValueTree childList (getChildList()); + if (childList.isValid()) + return childList; + + state.addChild (ValueTree (childGroupTag), 0, undoManager); + return getChildList(); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerList() const { - static const Identifier topLeft ("topLeft"); - static const Identifier topRight ("topRight"); - static const Identifier bottomLeft ("bottomLeft"); + return state.getChildWithName (markerGroupTag); +} + +ValueTree DrawableComposite::ValueTreeWrapper::getMarkerListCreating (UndoManager* undoManager) +{ + const ValueTree markerList (getMarkerList()); + if (markerList.isValid()) + return markerList; + + state.addChild (ValueTree (markerGroupTag), -1, undoManager); + return getMarkerList(); +} + +int DrawableComposite::ValueTreeWrapper::getNumDrawables() const +{ + return getChildList().getNumChildren(); +} + +const ValueTree DrawableComposite::ValueTreeWrapper::getDrawableState (int index) const +{ + return getChildList().getChild (index); +} + +void DrawableComposite::ValueTreeWrapper::addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager) +{ + getChildListCreating (undoManager).addChild (newDrawableState, index, undoManager); +} + +void DrawableComposite::ValueTreeWrapper::moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager) +{ + getChildListCreating (undoManager).moveChild (currentIndex, newIndex, undoManager); +} + +void DrawableComposite::ValueTreeWrapper::removeDrawable (int index, UndoManager* undoManager) +{ + getChildList().removeChild (index, undoManager); +} + +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForOrigin() const +{ + const String pos (state [topLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topLeft, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX1Y0() const +{ + const String pos (state [topRight].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (1.0f, 0.0f)); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topRight, newPoint.toString(), undoManager); +} - static void stringToPoint (const String& coords, Point& point) +const RelativePoint DrawableComposite::ValueTreeWrapper::getTargetPositionForX0Y1() const +{ + const String pos (state [bottomLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (0.0f, 1.0f)); +} + +void DrawableComposite::ValueTreeWrapper::setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (bottomLeft, newPoint.toString(), undoManager); +} + +int DrawableComposite::ValueTreeWrapper::getNumMarkers() const +{ + return getMarkerList().getNumChildren(); +} + +const DrawableComposite::Marker DrawableComposite::ValueTreeWrapper::getMarker (int index) const +{ + const ValueTree marker (getMarkerList().getChild (index)); + const bool isXAxis = marker [xAxisProperty]; + + return Marker (marker [nameProperty], + RelativeCoordinate (marker [posProperty].toString(), isXAxis), + isXAxis); +} + +void DrawableComposite::ValueTreeWrapper::setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager) +{ + ValueTree markerList (getMarkerListCreating (undoManager)); + ValueTree marker (markerList.getChildWithProperty (nameProperty, name)); + + if (marker.isValid()) { - if (coords.isNotEmpty()) - { - const int comma = coords.indexOfChar (','); - point.setXY (coords.substring (0, comma).getFloatValue(), - coords.substring (comma + 1).getFloatValue()); - } + jassert ((bool) marker [xAxisProperty] == xAxis); // shouldn't change the axis of a marker after it has been created! + marker.setProperty (posProperty, position.toString(), undoManager); } - - static const var pointToString (const Point& point) + else { - return String (point.getX()) + ", " + String (point.getY()); + marker = ValueTree (markerTag); + marker.setProperty (nameProperty, name, 0); + marker.setProperty (xAxisProperty, xAxis, 0); + marker.setProperty (posProperty, position.toString(), 0); + markerList.addChild (marker, -1, undoManager); } } -const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableComposite::ValueTreeWrapper::removeMarker (int index, UndoManager* undoManager) { - jassert (tree.hasType (valueTreeType)); + return getMarkerList().removeChild (index, undoManager); +} +//============================================================================== +const Rectangle DrawableComposite::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ Rectangle damageRect; + const ValueTreeWrapper controller (tree); + setName (controller.getID()); - setName (tree [idProperty]); + RelativePoint newControlPoint[3] = { controller.getTargetPositionForOrigin(), + controller.getTargetPositionForX1Y0(), + controller.getTargetPositionForX0Y1() }; - Point newControlPoint[3]; - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topLeft].toString(), newControlPoint[0]); - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::topRight].toString(), newControlPoint[1]); - DrawableCompositeHelpers::stringToPoint (tree [DrawableCompositeHelpers::bottomLeft].toString(), newControlPoint[2]); - bool controlPointsChanged = false; + bool redrawAll = false; if (controlPoints[0] != newControlPoint[0] || controlPoints[1] != newControlPoint[1] || controlPoints[2] != newControlPoint[2]) { - controlPointsChanged = true; + redrawAll = true; damageRect = getUntransformedBounds(); controlPoints[0] = newControlPoint[0]; controlPoints[1] = newControlPoint[1]; controlPoints[2] = newControlPoint[2]; } + // Remove deleted markers... int i; - for (i = drawables.size(); --i >= tree.getNumChildren();) + for (i = markers.size(); --i >= controller.getNumMarkers();) + { + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + removeMarker (i); + } + + // Update markers and add new ones.. + for (i = 0; i < controller.getNumMarkers(); ++i) { - damageRect = damageRect.getUnion (drawables.getUnchecked(i)->getBounds()); + const Marker newMarker (controller.getMarker (i)); + Marker* m = markers[i]; + + if (m == 0 || newMarker != *m) + { + redrawAll = true; + if (damageRect.isEmpty()) + damageRect = getUntransformedBounds(); + + if (m == 0) + markers.add (new Marker (newMarker)); + else + *m = newMarker; + } + } + + // Remove deleted drawables.. + for (i = drawables.size(); --i >= controller.getNumDrawables();) + { + Drawable* const d = drawables.getUnchecked(i); + damageRect = damageRect.getUnion (d->getBounds()); + d->parent = 0; drawables.remove (i); } - for (int i = 0; i < tree.getNumChildren(); ++i) + // Update drawables and add new ones.. + for (i = 0; i < controller.getNumDrawables(); ++i) { - const ValueTree childTree (tree.getChild (i)); + const ValueTree newDrawable (controller.getDrawableState (i)); Drawable* d = drawables[i]; if (d != 0) { - if (childTree.hasType (d->getValueTreeType())) + if (newDrawable.hasType (d->getValueTreeType())) { - damageRect = damageRect.getUnion (d->refreshFromValueTree (childTree, imageProvider)); + damageRect = damageRect.getUnion (d->refreshFromValueTree (newDrawable, imageProvider)); } else { damageRect = damageRect.getUnion (d->getBounds()); - d = createFromValueTree (childTree, imageProvider); + d = createFromValueTree (newDrawable, imageProvider); + d->parent = this; drawables.set (i, d); damageRect = damageRect.getUnion (d->getBounds()); } } else { - d = createFromValueTree (childTree, imageProvider); + d = createFromValueTree (newDrawable, imageProvider); + d->parent = this; drawables.set (i, d); damageRect = damageRect.getUnion (d->getBounds()); } } - if (controlPointsChanged) + if (redrawAll) damageRect = damageRect.getUnion (getUntransformedBounds()); - return damageRect.transformed (getTransform()); + return damageRect.transformed (calculateTransform()); } const ValueTree DrawableComposite::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + v.setID (getName(), 0); + v.setTargetPositionForOrigin (controlPoints[0], 0); + v.setTargetPositionForX1Y0 (controlPoints[1], 0); + v.setTargetPositionForX0Y1 (controlPoints[2], 0); - if (! getTransform().isIdentity()) + int i; + for (i = 0; i < drawables.size(); ++i) + v.addDrawable (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); + + for (i = 0; i < markers.size(); ++i) { - v.setProperty (DrawableCompositeHelpers::topLeft, DrawableCompositeHelpers::pointToString (controlPoints[0]), 0); - v.setProperty (DrawableCompositeHelpers::topRight, DrawableCompositeHelpers::pointToString (controlPoints[1]), 0); - v.setProperty (DrawableCompositeHelpers::bottomLeft, DrawableCompositeHelpers::pointToString (controlPoints[2]), 0); + const Marker* m = markers.getUnchecked(i); + v.setMarker (m->name, m->isOnXAxis, m->position, 0); } - for (int i = 0; i < drawables.size(); ++i) - v.addChild (drawables.getUnchecked(i)->createValueTree (imageProvider), -1, 0); - - return v; + return tree; } diff --git a/src/gui/graphics/drawables/juce_DrawableComposite.h b/src/gui/graphics/drawables/juce_DrawableComposite.h index 3fb70925c3..25bf4a64dc 100644 --- a/src/gui/graphics/drawables/juce_DrawableComposite.h +++ b/src/gui/graphics/drawables/juce_DrawableComposite.h @@ -35,14 +35,17 @@ @see Drawable */ -class JUCE_API DrawableComposite : public Drawable +class JUCE_API DrawableComposite : public Drawable, + public RelativeCoordinate::NamedCoordinateFinder { public: //============================================================================== - /** Creates a composite Drawable. - */ + /** Creates a composite Drawable. */ DrawableComposite(); + /** Creates a copy of a DrawableComposite. */ + DrawableComposite (const DrawableComposite& other); + /** Destructor. */ virtual ~DrawableComposite(); @@ -122,27 +125,44 @@ public: @param targetPositionForX0Y1 the position that the local coordinate (0, 1) should be mapped onto when rendering this object. */ - void setTransform (const Point& targetPositionForOrigin, - const Point& targetPositionForX1Y0, - const Point& targetPositionForX0Y1); + void setTransform (const RelativePoint& targetPositionForOrigin, + const RelativePoint& targetPositionForX1Y0, + const RelativePoint& targetPositionForX0Y1); /** Returns the position to which the local coordinate (0, 0) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } + const RelativePoint& getTargetPositionForOrigin() const throw() { return controlPoints[0]; } /** Returns the position to which the local coordinate (1, 0) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } + const RelativePoint& getTargetPositionForX1Y0() const throw() { return controlPoints[1]; } /** Returns the position to which the local coordinate (0, 1) should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } + const RelativePoint& getTargetPositionForX0Y1() const throw() { return controlPoints[2]; } + + //============================================================================== + struct Marker + { + Marker (const Marker&); + Marker (const String& name, const RelativeCoordinate& position, bool isOnXAxis); + bool operator!= (const Marker&) const throw(); + + String name; + RelativeCoordinate position; + bool isOnXAxis; + }; + + int getNumMarkers (bool xAxis) const throw(); + const Marker* getMarker (int index) const throw(); + void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position); + void removeMarker (int index); //============================================================================== /** @internal */ @@ -152,12 +172,10 @@ public: /** @internal */ bool hitTest (float x, float y) const; /** @internal */ - int getNumControlPoints() const; - /** @internal */ - const Point getControlPoint (int index) const; - /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -165,18 +183,57 @@ public: static const Identifier valueTreeType; /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + /** @internal */ + const RelativeCoordinate findNamedCoordinate (const String& objectName, const String& edge) const; + + //============================================================================== + /** Internally-used class for wrapping a DrawableComposite's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + int getNumDrawables() const; + const ValueTree getDrawableState (int index) const; + void addDrawable (const ValueTree& newDrawableState, int index, UndoManager* undoManager); + void moveDrawableOrder (int currentIndex, int newIndex, UndoManager* undoManager); + void removeDrawable (int index, UndoManager* undoManager); + + const RelativePoint getTargetPositionForOrigin() const; + void setTargetPositionForOrigin (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForX1Y0() const; + void setTargetPositionForX1Y0 (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForX0Y1() const; + void setTargetPositionForX0Y1 (const RelativePoint& newPoint, UndoManager* undoManager); + + int getNumMarkers() const; + const Marker getMarker (int index) const; + void setMarker (const String& name, bool xAxis, const RelativeCoordinate& position, UndoManager* undoManager); + void removeMarker (int index, UndoManager* undoManager); + + private: + static const Identifier topLeft, topRight, bottomLeft, childGroupTag, markerGroupTag, + markerTag, nameProperty, xAxisProperty, posProperty; + + ValueTree getChildList() const; + ValueTree getChildListCreating (UndoManager* undoManager); + ValueTree getMarkerList() const; + ValueTree getMarkerListCreating (UndoManager* undoManager); + }; //============================================================================== juce_UseDebuggingNewOperator private: OwnedArray drawables; - Point controlPoints[3]; + RelativePoint controlPoints[3]; + OwnedArray markers; const Rectangle getUntransformedBounds() const; - const AffineTransform getTransform() const; + const AffineTransform calculateTransform() const; - DrawableComposite (const DrawableComposite&); DrawableComposite& operator= (const DrawableComposite&); }; diff --git a/src/gui/graphics/drawables/juce_DrawableImage.cpp b/src/gui/graphics/drawables/juce_DrawableImage.cpp index 7fa0d2ae1d..583a620810 100644 --- a/src/gui/graphics/drawables/juce_DrawableImage.cpp +++ b/src/gui/graphics/drawables/juce_DrawableImage.cpp @@ -27,8 +27,8 @@ BEGIN_JUCE_NAMESPACE - #include "juce_DrawableImage.h" +#include "juce_DrawableComposite.h" #include "../imaging/juce_ImageCache.h" @@ -39,47 +39,58 @@ DrawableImage::DrawableImage() opacity (1.0f), overlayColour (0x00000000) { - controlPoints[1].setXY (1.0f, 0.0f); - controlPoints[2].setXY (0.0f, 1.0f); + controlPoints[1] = RelativePoint (Point (1.0f, 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, 1.0f)); } -DrawableImage::~DrawableImage() +DrawableImage::DrawableImage (const DrawableImage& other) + : image (0), + canDeleteImage (false), + opacity (other.opacity), + overlayColour (other.overlayColour) { - clearImage(); + for (int i = 0; i < numElementsInArray (controlPoints); ++i) + controlPoints[i] = other.controlPoints[i]; + + if (other.image != 0) + { + if ((! other.canDeleteImage) || ! ImageCache::isImageInCache (other.image)) + { + setImage (*other.image); + } + else + { + ImageCache::incReferenceCount (other.image); + setImage (other.image, true); + } + } } -//============================================================================== -void DrawableImage::clearImage() +DrawableImage::~DrawableImage() { - if (canDeleteImage && image != 0) - ImageCache::releaseOrDelete (image); - - image = 0; + setImage (0, false); } +//============================================================================== void DrawableImage::setImage (const Image& imageToCopy) { - clearImage(); - image = new Image (imageToCopy); - canDeleteImage = true; - - controlPoints[0].setXY (0.0f, 0.0f); - controlPoints[1].setXY ((float) image->getWidth(), 0.0f); - controlPoints[2].setXY (0.0f, (float) image->getHeight()); + setImage (new Image (imageToCopy), true); } void DrawableImage::setImage (Image* imageToUse, const bool releaseWhenNotNeeded) { - clearImage(); + if (canDeleteImage) + ImageCache::releaseOrDelete (image); + image = imageToUse; canDeleteImage = releaseWhenNotNeeded; if (image != 0) { - controlPoints[0].setXY (0.0f, 0.0f); - controlPoints[1].setXY ((float) image->getWidth(), 0.0f); - controlPoints[2].setXY (0.0f, (float) image->getHeight()); + controlPoints[0] = RelativePoint (Point (0.0f, 0.0f)); + controlPoints[1] = RelativePoint (Point ((float) image->getWidth(), 0.0f)); + controlPoints[2] = RelativePoint (Point (0.0f, (float) image->getHeight())); } } @@ -93,9 +104,9 @@ void DrawableImage::setOverlayColour (const Colour& newOverlayColour) overlayColour = newOverlayColour; } -void DrawableImage::setTransform (const Point& imageTopLeftPosition, - const Point& imageTopRightPosition, - const Point& imageBottomLeftPosition) +void DrawableImage::setTransform (const RelativePoint& imageTopLeftPosition, + const RelativePoint& imageTopRightPosition, + const RelativePoint& imageBottomLeftPosition) { controlPoints[0] = imageTopLeftPosition; controlPoints[1] = imageTopRightPosition; @@ -103,15 +114,19 @@ void DrawableImage::setTransform (const Point& imageTopLeftPosition, } //============================================================================== -const AffineTransform DrawableImage::getTransform() const +const AffineTransform DrawableImage::calculateTransform() const { if (image == 0) return AffineTransform::identity; - const Point tr (controlPoints[0] + (controlPoints[1] - controlPoints[0]) / (float) image->getWidth()); - const Point bl (controlPoints[0] + (controlPoints[2] - controlPoints[0]) / (float) image->getHeight()); + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); - return AffineTransform::fromTargetPoints (controlPoints[0].getX(), controlPoints[0].getY(), + const Point tr (resolved[0] + (resolved[1] - resolved[0]) / (float) image->getWidth()); + const Point bl (resolved[0] + (resolved[2] - resolved[0]) / (float) image->getHeight()); + + return AffineTransform::fromTargetPoints (resolved[0].getX(), resolved[0].getY(), tr.getX(), tr.getY(), bl.getX(), bl.getY()); } @@ -120,7 +135,7 @@ void DrawableImage::render (const Drawable::RenderingContext& context) const { if (image != 0) { - const AffineTransform t (getTransform().followedBy (context.transform)); + const AffineTransform t (calculateTransform().followedBy (context.transform)); if (opacity > 0.0f && ! overlayColour.isOpaque()) { @@ -141,7 +156,11 @@ const Rectangle DrawableImage::getBounds() const if (image == 0) return Rectangle(); - const Point bottomRight (controlPoints[1] + (controlPoints[2] - controlPoints[0])); + Point resolved[3]; + for (int i = 0; i < 3; ++i) + resolved[i] = controlPoints[i].resolve (parent); + + const Point bottomRight (resolved[1] + (resolved[2] - resolved[0])); float minX = bottomRight.getX(); float maxX = minX; float minY = bottomRight.getY(); @@ -149,10 +168,10 @@ const Rectangle DrawableImage::getBounds() const for (int i = 0; i < 3; ++i) { - minX = jmin (minX, controlPoints[i].getX()); - maxX = jmax (maxX, controlPoints[i].getX()); - minY = jmin (minY, controlPoints[i].getY()); - maxY = jmax (maxY, controlPoints[i].getY()); + minX = jmin (minX, resolved[i].getX()); + maxX = jmax (maxX, resolved[i].getX()); + minY = jmin (minY, resolved[i].getY()); + maxY = jmax (maxY, resolved[i].getY()); } return Rectangle (minX, minY, maxX - minX, maxY - minY); @@ -163,7 +182,7 @@ bool DrawableImage::hitTest (float x, float y) const if (image == 0) return false; - getTransform().inverted().transformPoint (x, y); + calculateTransform().inverted().transformPoint (x, y); const int ix = roundToInt (x); const int iy = roundToInt (y); @@ -177,81 +196,117 @@ bool DrawableImage::hitTest (float x, float y) const Drawable* DrawableImage::createCopy() const { - DrawableImage* const di = new DrawableImage(); + return new DrawableImage (*this); +} - di->opacity = opacity; - di->overlayColour = overlayColour; +void DrawableImage::invalidatePoints() +{ +} - for (int i = 0; i < 4; ++i) - di->controlPoints[i] = controlPoints[i]; +//============================================================================== +const Identifier DrawableImage::valueTreeType ("Image"); - if (image != 0) - { - if ((! canDeleteImage) || ! ImageCache::isImageInCache (image)) - { - di->setImage (*image); - } - else - { - ImageCache::incReferenceCount (image); - di->setImage (image, true); - } - } +const Identifier DrawableImage::ValueTreeWrapper::opacity ("opacity"); +const Identifier DrawableImage::ValueTreeWrapper::overlay ("overlay"); +const Identifier DrawableImage::ValueTreeWrapper::image ("image"); +const Identifier DrawableImage::ValueTreeWrapper::topLeft ("topLeft"); +const Identifier DrawableImage::ValueTreeWrapper::topRight ("topRight"); +const Identifier DrawableImage::ValueTreeWrapper::bottomLeft ("bottomLeft"); - return di; +//============================================================================== +DrawableImage::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); } -//============================================================================== -const Identifier DrawableImage::valueTreeType ("Image"); +const var DrawableImage::ValueTreeWrapper::getImageIdentifier() const +{ + return state [image]; +} -namespace DrawableImageHelpers +void DrawableImage::ValueTreeWrapper::setImageIdentifier (const var& newIdentifier, UndoManager* undoManager) { - static const Identifier opacity ("opacity"); - static const Identifier overlay ("overlay"); - static const Identifier image ("image"); - static const Identifier topLeft ("topLeft"); - static const Identifier topRight ("topRight"); - static const Identifier bottomLeft ("bottomLeft"); - - static void stringToPoint (const String& coords, Point& point) - { - if (coords.isNotEmpty()) - { - const int comma = coords.indexOfChar (','); - point.setXY (coords.substring (0, comma).getFloatValue(), - coords.substring (comma + 1).getFloatValue()); - } - } + state.setProperty (image, newIdentifier, undoManager); +} - static const var pointToString (const Point& point) - { - return String (point.getX()) + ", " + String (point.getY()); - } +float DrawableImage::ValueTreeWrapper::getOpacity() const +{ + return (float) state.getProperty (opacity, 1.0); } -const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +void DrawableImage::ValueTreeWrapper::setOpacity (float newOpacity, UndoManager* undoManager) +{ + state.setProperty (opacity, newOpacity, undoManager); +} + +const Colour DrawableImage::ValueTreeWrapper::getOverlayColour() const +{ + return Colour (state [overlay].toString().getHexValue32()); +} + +void DrawableImage::ValueTreeWrapper::setOverlayColour (const Colour& newColour, UndoManager* undoManager) +{ + if (newColour.isTransparent()) + state.removeProperty (overlay, undoManager); + else + state.setProperty (overlay, String::toHexString ((int) newColour.getARGB()), undoManager); +} + +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopLeft() const +{ + const String pos (state [topLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint(); +} + +void DrawableImage::ValueTreeWrapper::setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topLeft, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForTopRight() const +{ + const String pos (state [topRight].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (100.0f, 0.0f)); +} + +void DrawableImage::ValueTreeWrapper::setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager) +{ + state.setProperty (topRight, newPoint.toString(), undoManager); +} + +const RelativePoint DrawableImage::ValueTreeWrapper::getTargetPositionForBottomLeft() const +{ + const String pos (state [bottomLeft].toString()); + return pos.isNotEmpty() ? RelativePoint (pos) : RelativePoint (Point (0.0f, 100.0f)); +} + +void DrawableImage::ValueTreeWrapper::setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager) { - jassert (tree.hasType (valueTreeType)); + state.setProperty (bottomLeft, newPoint.toString(), undoManager); +} + - setName (tree [idProperty]); +//============================================================================== +const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) +{ + const ValueTreeWrapper controller (tree); + setName (controller.getID()); - const float newOpacity = tree.getProperty (DrawableImageHelpers::opacity, 1.0); - const Colour newOverlayColour (tree [DrawableImageHelpers::overlay].toString().getHexValue32()); + const float newOpacity = controller.getOpacity(); + const Colour newOverlayColour (controller.getOverlayColour()); Image* newImage = 0; - const String imageIdentifier (tree [DrawableImageHelpers::image].toString()); - if (imageIdentifier.isNotEmpty()) - { - jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! + const var imageIdentifier (controller.getImageIdentifier()); - if (imageProvider != 0) - newImage = imageProvider->getImageForIdentifier (imageIdentifier); - } + jassert (imageProvider != 0 || imageIdentifier.isVoid()); // if you're using images, you need to provide something that can load and save them! + + if (imageProvider != 0) + newImage = imageProvider->getImageForIdentifier (imageIdentifier); - Point newControlPoint[3]; - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topLeft].toString(), newControlPoint[0]); - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::topRight].toString(), newControlPoint[1]); - DrawableImageHelpers::stringToPoint (tree [DrawableImageHelpers::bottomLeft].toString(), newControlPoint[2]); + RelativePoint newControlPoint[3] = { controller.getTargetPositionForTopLeft(), + controller.getTargetPositionForTopRight(), + controller.getTargetPositionForBottomLeft() }; if (newOpacity != opacity || overlayColour != newOverlayColour || image != newImage || controlPoints[0] != newControlPoint[0] @@ -266,7 +321,10 @@ const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tre if (image != newImage) { - ImageCache::release (image); + if (canDeleteImage) + ImageCache::releaseOrDelete (image); + + canDeleteImage = true; image = newImage; } @@ -279,33 +337,25 @@ const Rectangle DrawableImage::refreshFromValueTree (const ValueTree& tre const ValueTree DrawableImage::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); - - if (opacity < 1.0f) - v.setProperty (DrawableImageHelpers::opacity, (double) opacity, 0); - - if (! overlayColour.isTransparent()) - v.setProperty (DrawableImageHelpers::overlay, String::toHexString ((int) overlayColour.getARGB()), 0); - - if (! getTransform().isIdentity()) - { - v.setProperty (DrawableImageHelpers::topLeft, DrawableImageHelpers::pointToString (controlPoints[0]), 0); - v.setProperty (DrawableImageHelpers::topRight, DrawableImageHelpers::pointToString (controlPoints[1]), 0); - v.setProperty (DrawableImageHelpers::bottomLeft, DrawableImageHelpers::pointToString (controlPoints[2]), 0); - } + v.setID (getName(), 0); + v.setOpacity (opacity, 0); + v.setOverlayColour (overlayColour, 0); + v.setTargetPositionForTopLeft (controlPoints[0], 0); + v.setTargetPositionForTopRight (controlPoints[1], 0); + v.setTargetPositionForBottomLeft (controlPoints[2], 0); if (image != 0) { jassert (imageProvider != 0); // if you're using images, you need to provide something that can load and save them! if (imageProvider != 0) - v.setProperty (DrawableImageHelpers::image, imageProvider->getIdentifierForImage (image), 0); + v.setImageIdentifier (imageProvider->getIdentifierForImage (image), 0); } - return v; + return tree; } diff --git a/src/gui/graphics/drawables/juce_DrawableImage.h b/src/gui/graphics/drawables/juce_DrawableImage.h index 3a1f11b996..30c5ccdae8 100644 --- a/src/gui/graphics/drawables/juce_DrawableImage.h +++ b/src/gui/graphics/drawables/juce_DrawableImage.h @@ -40,6 +40,7 @@ class JUCE_API DrawableImage : public Drawable public: //============================================================================== DrawableImage(); + DrawableImage (const DrawableImage& other); /** Destructor. */ virtual ~DrawableImage(); @@ -59,7 +60,7 @@ public: with ImageCache and pass it in here with releaseWhenNotNeeded = true, then it'll be released neatly with its reference count being decreased. - @param imageToUse the image to render + @param imageToUse the image to render (may be a null pointer) @param releaseWhenNotNeeded if false, a simple pointer is kept to the image; if true, then the image will be deleted when this object no longer needs it - unless the image was created by the ImageCache, @@ -70,9 +71,6 @@ public: /** Returns the current image. */ Image* getImage() const throw() { return image; } - /** Clears (and possibly deletes) the currently set image. */ - void clearImage(); - /** Sets the opacity to use when drawing the image. */ void setOpacity (float newOpacity); @@ -103,27 +101,27 @@ public: @param imageBottomLeftPosition the position that the image's bottom-left corner should be mapped to in the target coordinate space. */ - void setTransform (const Point& imageTopLeftPosition, - const Point& imageTopRightPosition, - const Point& imageBottomLeftPosition); + void setTransform (const RelativePoint& imageTopLeftPosition, + const RelativePoint& imageTopRightPosition, + const RelativePoint& imageBottomLeftPosition); /** Returns the position to which the image's top-left corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } + const RelativePoint& getTargetPositionForTopLeft() const throw() { return controlPoints[0]; } /** Returns the position to which the image's top-right corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } + const RelativePoint& getTargetPositionForTopRight() const throw() { return controlPoints[1]; } /** Returns the position to which the image's bottom-left corner should be remapped in the target coordinate space when rendering this object. @see setTransform */ - const Point& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } + const RelativePoint& getTargetPositionForBottomLeft() const throw() { return controlPoints[2]; } //============================================================================== /** @internal */ @@ -135,6 +133,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -143,6 +143,35 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + //============================================================================== + /** Internally-used class for wrapping a DrawableImage's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + const var getImageIdentifier() const; + void setImageIdentifier (const var& newIdentifier, UndoManager* undoManager); + + float getOpacity() const; + void setOpacity (float newOpacity, UndoManager* undoManager); + + const Colour getOverlayColour() const; + void setOverlayColour (const Colour& newColour, UndoManager* undoManager); + + const RelativePoint getTargetPositionForTopLeft() const; + void setTargetPositionForTopLeft (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForTopRight() const; + void setTargetPositionForTopRight (const RelativePoint& newPoint, UndoManager* undoManager); + + const RelativePoint getTargetPositionForBottomLeft() const; + void setTargetPositionForBottomLeft (const RelativePoint& newPoint, UndoManager* undoManager); + + private: + static const Identifier opacity, overlay, image, topLeft, topRight, bottomLeft; + }; + //============================================================================== juce_UseDebuggingNewOperator @@ -151,11 +180,10 @@ private: bool canDeleteImage; float opacity; Colour overlayColour; - Point controlPoints[3]; + RelativePoint controlPoints[3]; - const AffineTransform getTransform() const; + const AffineTransform calculateTransform() const; - DrawableImage (const DrawableImage&); DrawableImage& operator= (const DrawableImage&); }; diff --git a/src/gui/graphics/drawables/juce_DrawablePath.cpp b/src/gui/graphics/drawables/juce_DrawablePath.cpp index 4a689e8c87..e537b7cfe0 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.cpp +++ b/src/gui/graphics/drawables/juce_DrawablePath.cpp @@ -28,6 +28,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_DrawablePath.h" +#include "juce_DrawableComposite.h" #include "../../../io/streams/juce_MemoryOutputStream.h" @@ -35,10 +36,25 @@ BEGIN_JUCE_NAMESPACE DrawablePath::DrawablePath() : mainFill (Colours::black), strokeFill (Colours::transparentBlack), - strokeType (0.0f) + strokeType (0.0f), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) { } +DrawablePath::DrawablePath (const DrawablePath& other) + : mainFill (other.mainFill), + strokeFill (other.strokeFill), + strokeType (other.strokeType), + pathNeedsUpdating (true), + strokeNeedsUpdating (true) +{ + if (other.relativePath != 0) + relativePath = new RelativePointPath (*other.relativePath); + else + path = other.path; +} + DrawablePath::~DrawablePath() { } @@ -47,7 +63,7 @@ DrawablePath::~DrawablePath() void DrawablePath::setPath (const Path& newPath) { path = newPath; - updateOutline(); + strokeNeedsUpdating = true; } void DrawablePath::setFill (const FillType& newFill) @@ -63,7 +79,7 @@ void DrawablePath::setStrokeFill (const FillType& newFill) void DrawablePath::setStrokeType (const PathStrokeType& newStrokeType) { strokeType = newStrokeType; - updateOutline(); + strokeNeedsUpdating = true; } void DrawablePath::setStrokeThickness (const float newThickness) @@ -71,6 +87,55 @@ void DrawablePath::setStrokeThickness (const float newThickness) setStrokeType (PathStrokeType (newThickness, strokeType.getJointStyle(), strokeType.getEndStyle())); } +void DrawablePath::updatePath() const +{ + if (pathNeedsUpdating) + { + pathNeedsUpdating = false; + + if (relativePath != 0) + { + path.clear(); + relativePath->createPath (path, parent); + strokeNeedsUpdating = true; + } + } +} + +void DrawablePath::updateStroke() const +{ + if (strokeNeedsUpdating) + { + strokeNeedsUpdating = false; + updatePath(); + stroke.clear(); + strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); + } +} + +const Path& DrawablePath::getPath() const +{ + updatePath(); + return path; +} + +const Path& DrawablePath::getStrokePath() const +{ + updateStroke(); + return stroke; +} + +bool DrawablePath::isStrokeVisible() const throw() +{ + return strokeType.getStrokeThickness() > 0.0f && ! strokeFill.isInvisible(); +} + +void DrawablePath::invalidatePoints() +{ + pathNeedsUpdating = true; + strokeNeedsUpdating = true; +} + //============================================================================== void DrawablePath::render (const Drawable::RenderingContext& context) const { @@ -81,10 +146,10 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const f.transform = f.transform.followedBy (context.transform); context.g.setFillType (f); - context.g.fillPath (path, context.transform); + context.g.fillPath (getPath(), context.transform); } - if (strokeType.getStrokeThickness() > 0.0f) + if (isStrokeVisible()) { FillType f (strokeFill); if (f.isGradient()) @@ -92,162 +157,133 @@ void DrawablePath::render (const Drawable::RenderingContext& context) const f.transform = f.transform.followedBy (context.transform); context.g.setFillType (f); - context.g.fillPath (stroke, context.transform); + context.g.fillPath (getStrokePath(), context.transform); } } -void DrawablePath::updateOutline() -{ - stroke.clear(); - strokeType.createStrokedPath (stroke, path, AffineTransform::identity, 4.0f); -} - const Rectangle DrawablePath::getBounds() const { - if (strokeType.getStrokeThickness() > 0.0f) - return stroke.getBounds(); + if (isStrokeVisible()) + return getStrokePath().getBounds(); else - return path.getBounds(); + return getPath().getBounds(); } bool DrawablePath::hitTest (float x, float y) const { - return path.contains (x, y) - || stroke.contains (x, y); + return getPath().contains (x, y) + || (isStrokeVisible() && getStrokePath().contains (x, y)); } Drawable* DrawablePath::createCopy() const { - DrawablePath* const dp = new DrawablePath(); - - dp->path = path; - dp->stroke = stroke; - dp->mainFill = mainFill; - dp->strokeFill = strokeFill; - dp->strokeType = strokeType; - return dp; + return new DrawablePath (*this); } //============================================================================== const Identifier DrawablePath::valueTreeType ("Path"); -namespace DrawablePathHelpers -{ - static const Identifier type ("type"); - static const Identifier solid ("solid"); - static const Identifier colour ("colour"); - static const Identifier gradient ("gradient"); - static const Identifier x1 ("x1"); - static const Identifier x2 ("x2"); - static const Identifier y1 ("y1"); - static const Identifier y2 ("y2"); - static const Identifier radial ("radial"); - static const Identifier colours ("colours"); - static const Identifier fill ("fill"); - static const Identifier stroke ("stroke"); - static const Identifier jointStyle ("jointStyle"); - static const Identifier capStyle ("capStyle"); - static const Identifier strokeWidth ("strokeWidth"); - static const Identifier path ("path"); - - static bool updateFillType (const ValueTree& v, FillType& fillType) - { - const String type (v[type].toString()); - - if (type.equalsIgnoreCase (solid)) - { - const String colourString (v [colour].toString()); - const Colour newColour (colourString.isEmpty() ? (uint32) 0xff000000 - : (uint32) colourString.getHexValue32()); - - if (fillType.isColour() && fillType.colour == newColour) - return false; +const Identifier DrawablePath::ValueTreeWrapper::fill ("fill"); +const Identifier DrawablePath::ValueTreeWrapper::stroke ("stroke"); +const Identifier DrawablePath::ValueTreeWrapper::jointStyle ("jointStyle"); +const Identifier DrawablePath::ValueTreeWrapper::capStyle ("capStyle"); +const Identifier DrawablePath::ValueTreeWrapper::strokeWidth ("strokeWidth"); +const Identifier DrawablePath::ValueTreeWrapper::path ("path"); - fillType.setColour (newColour); - return true; - } - else if (type.equalsIgnoreCase (gradient)) - { - ColourGradient g; - g.point1.setXY (v[x1], v[y1]); - g.point2.setXY (v[x2], v[y2]); - g.isRadial = v[radial]; +//============================================================================== +DrawablePath::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); +} - StringArray colourSteps; - colourSteps.addTokens (v[colours].toString(), false); +const FillType DrawablePath::ValueTreeWrapper::getMainFill() const +{ + return readFillType (state.getChildWithName (fill)); +} - for (int i = 0; i < colourSteps.size() / 2; ++i) - g.addColour (colourSteps[i * 2].getDoubleValue(), - Colour ((uint32) colourSteps[i * 2 + 1].getHexValue32())); +void DrawablePath::ValueTreeWrapper::setMainFill (const FillType& newFill, UndoManager* undoManager) +{ + replaceFillType (fill, newFill, undoManager); +} - if (fillType.isGradient() && *fillType.gradient == g) - return false; +const FillType DrawablePath::ValueTreeWrapper::getStrokeFill() const +{ + return readFillType (state.getChildWithName (stroke)); +} - fillType.setGradient (g); - return true; - } +void DrawablePath::ValueTreeWrapper::setStrokeFill (const FillType& newFill, UndoManager* undoManager) +{ + replaceFillType (stroke, newFill, undoManager); +} - jassertfalse; - return false; - } +const PathStrokeType DrawablePath::ValueTreeWrapper::getStrokeType() const +{ + const String jointStyleString (state [jointStyle].toString()); + const String capStyleString (state [capStyle].toString()); + + return PathStrokeType (state [strokeWidth], + jointStyleString == "curved" ? PathStrokeType::curved + : (jointStyleString == "bevel" ? PathStrokeType::beveled + : PathStrokeType::mitered), + capStyleString == "square" ? PathStrokeType::square + : (capStyleString == "round" ? PathStrokeType::rounded + : PathStrokeType::butt)); +} - static ValueTree createFillType (const Identifier& tagName, const FillType& fillType) - { - ValueTree v (tagName); +void DrawablePath::ValueTreeWrapper::setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager) +{ + state.setProperty (strokeWidth, (double) newStrokeType.getStrokeThickness(), undoManager); + state.setProperty (jointStyle, newStrokeType.getJointStyle() == PathStrokeType::mitered + ? "miter" : (newStrokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), undoManager); + state.setProperty (capStyle, newStrokeType.getEndStyle() == PathStrokeType::butt + ? "butt" : (newStrokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), undoManager); +} - if (fillType.isColour()) - { - v.setProperty (type, "solid", 0); - v.setProperty (colour, String::toHexString ((int) fillType.colour.getARGB()), 0); - } - else if (fillType.isGradient()) - { - v.setProperty (type, "gradient", 0); - v.setProperty (x1, fillType.gradient->point1.getX(), 0); - v.setProperty (y1, fillType.gradient->point1.getY(), 0); - v.setProperty (x2, fillType.gradient->point2.getX(), 0); - v.setProperty (y2, fillType.gradient->point2.getY(), 0); - v.setProperty (radial, fillType.gradient->isRadial, 0); - - String s; - for (int i = 0; i < fillType.gradient->getNumColours(); ++i) - s << " " << fillType.gradient->getColourPosition (i) - << " " << String::toHexString ((int) fillType.gradient->getColour(i).getARGB()); - - v.setProperty (colours, s.trimStart(), 0); - } - else - { - jassertfalse; //xxx - } +void DrawablePath::ValueTreeWrapper::getPath (RelativePointPath& p) const +{ + RelativePointPath newPath (state [path]); + p.swapWith (newPath); +} - return v; - } +void DrawablePath::ValueTreeWrapper::setPath (const String& newPath, UndoManager* undoManager) +{ + state.setProperty (path, newPath, undoManager); } const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - jassert (tree.hasType (valueTreeType)); - Rectangle damageRect; - setName (tree [idProperty]); + ValueTreeWrapper v (tree); + setName (v.getID()); + + bool needsRedraw = false; + const FillType newFill (v.getMainFill()); + + if (mainFill != newFill) + { + needsRedraw = true; + mainFill = newFill; + } + + const FillType newStrokeFill (v.getStrokeFill()); - bool needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::fill), mainFill); - needsRedraw = DrawablePathHelpers::updateFillType (tree.getChildWithName (DrawablePathHelpers::stroke), strokeFill) || needsRedraw; + if (strokeFill != newStrokeFill) + { + needsRedraw = true; + strokeFill = newStrokeFill; + } - const String jointStyle (tree [DrawablePathHelpers::jointStyle].toString()); - const String endStyle (tree [DrawablePathHelpers::capStyle].toString()); + const PathStrokeType newStroke (v.getStrokeType()); - PathStrokeType newStroke (tree [DrawablePathHelpers::strokeWidth], - jointStyle == "curved" ? PathStrokeType::curved - : (jointStyle == "bevel" ? PathStrokeType::beveled - : PathStrokeType::mitered), - endStyle == "square" ? PathStrokeType::square - : (endStyle == "round" ? PathStrokeType::rounded - : PathStrokeType::butt)); + ScopedPointer newRelativePath (new RelativePointPath()); + v.getPath (*newRelativePath); Path newPath; - newPath.restoreFromString (tree [DrawablePathHelpers::path]); + newRelativePath->createPath (newPath, parent); + + if (! newRelativePath->containsAnyDynamicPoints()) + newRelativePath = 0; if (strokeType != newStroke || path != newPath) { @@ -257,6 +293,8 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree needsRedraw = true; } + relativePath = newRelativePath.release(); + if (needsRedraw) damageRect = damageRect.getUnion (getBounds()); @@ -265,22 +303,20 @@ const Rectangle DrawablePath::refreshFromValueTree (const ValueTree& tree const ValueTree DrawablePath::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::fill, mainFill), -1, 0); - v.addChild (DrawablePathHelpers::createFillType (DrawablePathHelpers::stroke, strokeFill), -1, 0); + v.setID (getName(), 0); + v.setMainFill (mainFill, 0); + v.setStrokeFill (strokeFill, 0); + v.setStrokeType (strokeType, 0); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); - - v.setProperty (DrawablePathHelpers::strokeWidth, (double) strokeType.getStrokeThickness(), 0); - v.setProperty (DrawablePathHelpers::jointStyle, strokeType.getJointStyle() == PathStrokeType::mitered - ? "miter" : (strokeType.getJointStyle() == PathStrokeType::curved ? "curved" : "bevel"), 0); - v.setProperty (DrawablePathHelpers::capStyle, strokeType.getEndStyle() == PathStrokeType::butt - ? "butt" : (strokeType.getEndStyle() == PathStrokeType::square ? "square" : "round"), 0); - v.setProperty (DrawablePathHelpers::path, path.toString(), 0); + if (relativePath != 0) + v.setPath (relativePath->toString(), 0); + else + v.setPath (path.toString(), 0); - return v; + return tree; } diff --git a/src/gui/graphics/drawables/juce_DrawablePath.h b/src/gui/graphics/drawables/juce_DrawablePath.h index 4aaef11979..74ff1cd4f1 100644 --- a/src/gui/graphics/drawables/juce_DrawablePath.h +++ b/src/gui/graphics/drawables/juce_DrawablePath.h @@ -40,9 +40,9 @@ class JUCE_API DrawablePath : public Drawable { public: //============================================================================== - /** Creates a DrawablePath. - */ + /** Creates a DrawablePath. */ DrawablePath(); + DrawablePath (const DrawablePath& other); /** Destructor. */ virtual ~DrawablePath(); @@ -54,9 +54,6 @@ public: */ void setPath (const Path& newPath); - /** Returns the current path. */ - const Path& getPath() const throw() { return path; } - /** Sets a fill type for the path. This colour is used to fill the path - if you don't want the path to be @@ -97,6 +94,13 @@ public: const PathStrokeType& getStrokeType() const throw() { return strokeType; } + //============================================================================== + /** Returns the current path. */ + const Path& getPath() const; + + /** Returns the current path for the outline. */ + const Path& getStrokePath() const; + //============================================================================== /** @internal */ void render (const Drawable::RenderingContext& context) const; @@ -107,6 +111,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -115,17 +121,43 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + //============================================================================== + /** Internally-used class for wrapping a DrawablePath's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + const FillType getMainFill() const; + void setMainFill (const FillType& newFill, UndoManager* undoManager); + + const FillType getStrokeFill() const; + void setStrokeFill (const FillType& newFill, UndoManager* undoManager); + + const PathStrokeType getStrokeType() const; + void setStrokeType (const PathStrokeType& newStrokeType, UndoManager* undoManager); + + void getPath (RelativePointPath& path) const; + void setPath (const String& newPath, UndoManager* undoManager); + + private: + static const Identifier fill, stroke, jointStyle, capStyle, strokeWidth, path; + }; + //============================================================================== juce_UseDebuggingNewOperator private: - Path path, stroke; FillType mainFill, strokeFill; PathStrokeType strokeType; + ScopedPointer relativePath; + mutable Path path, stroke; + mutable bool pathNeedsUpdating, strokeNeedsUpdating; - void updateOutline(); + void updatePath() const; + void updateStroke() const; + bool isStrokeVisible() const throw(); - DrawablePath (const DrawablePath&); DrawablePath& operator= (const DrawablePath&); }; diff --git a/src/gui/graphics/drawables/juce_DrawableText.cpp b/src/gui/graphics/drawables/juce_DrawableText.cpp index 1c9a63371e..226c9c6c20 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.cpp +++ b/src/gui/graphics/drawables/juce_DrawableText.cpp @@ -36,6 +36,12 @@ DrawableText::DrawableText() { } +DrawableText::DrawableText (const DrawableText& other) + : text (other.text), + colour (other.colour) +{ +} + DrawableText::~DrawableText() { } @@ -76,21 +82,28 @@ bool DrawableText::hitTest (float x, float y) const Drawable* DrawableText::createCopy() const { - DrawableText* const dt = new DrawableText(); - - dt->text = text; - dt->colour = colour; + return new DrawableText (*this); +} - return dt; +void DrawableText::invalidatePoints() +{ } //============================================================================== const Identifier DrawableText::valueTreeType ("Text"); +const Identifier DrawableText::ValueTreeWrapper::text ("text"); + +DrawableText::ValueTreeWrapper::ValueTreeWrapper (const ValueTree& state_) + : ValueTreeWrapperBase (state_) +{ + jassert (state.hasType (valueTreeType)); +} + const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider) { - jassert (tree.hasType (valueTreeType)); - setName (tree [idProperty]); + ValueTreeWrapper v (tree); + setName (v.getID()); jassertfalse; // xxx not finished! @@ -99,13 +112,14 @@ const Rectangle DrawableText::refreshFromValueTree (const ValueTree& tree const ValueTree DrawableText::createValueTree (ImageProvider* imageProvider) const { - ValueTree v (valueTreeType); + ValueTree tree (valueTreeType); + ValueTreeWrapper v (tree); - if (getName().isNotEmpty()) - v.setProperty (idProperty, getName(), 0); + v.setID (getName(), 0); jassertfalse; // xxx not finished! - return v; + + return tree; } diff --git a/src/gui/graphics/drawables/juce_DrawableText.h b/src/gui/graphics/drawables/juce_DrawableText.h index 324a081593..63ced63342 100644 --- a/src/gui/graphics/drawables/juce_DrawableText.h +++ b/src/gui/graphics/drawables/juce_DrawableText.h @@ -42,6 +42,7 @@ public: //============================================================================== /** Creates a DrawableText object. */ DrawableText(); + DrawableText (const DrawableText& other); /** Destructor. */ virtual ~DrawableText(); @@ -78,6 +79,8 @@ public: /** @internal */ Drawable* createCopy() const; /** @internal */ + void invalidatePoints(); + /** @internal */ const Rectangle refreshFromValueTree (const ValueTree& tree, ImageProvider* imageProvider); /** @internal */ const ValueTree createValueTree (ImageProvider* imageProvider) const; @@ -86,6 +89,19 @@ public: /** @internal */ const Identifier getValueTreeType() const { return valueTreeType; } + //============================================================================== + /** Internally-used class for wrapping a DrawableText's state into a ValueTree. */ + class ValueTreeWrapper : public ValueTreeWrapperBase + { + public: + ValueTreeWrapper (const ValueTree& state); + + //xxx todo + + private: + static const Identifier text; + }; + //============================================================================== juce_UseDebuggingNewOperator @@ -93,7 +109,6 @@ private: GlyphArrangement text; Colour colour; - DrawableText (const DrawableText&); DrawableText& operator= (const DrawableText&); }; diff --git a/src/gui/graphics/geometry/juce_Path.cpp b/src/gui/graphics/geometry/juce_Path.cpp index 9a29f0a4bd..ddd452e5f0 100644 --- a/src/gui/graphics/geometry/juce_Path.cpp +++ b/src/gui/graphics/geometry/juce_Path.cpp @@ -74,12 +74,7 @@ namespace PathHelpers while (*t != 0 && ! CharacterFunctions::isWhitespace (*t)) ++t; - const int length = (int) (t - start); - - while (CharacterFunctions::isWhitespace (*t)) - ++t; - - return String (start, length); + return String (start, (int) (t - start)); } } @@ -1479,12 +1474,15 @@ void Path::restoreFromString (const String& stringVersion) int numValues = 2; float values [6]; - while (*t != 0) + for (;;) { const String token (PathHelpers::nextToken (t)); const juce_wchar firstChar = token[0]; int startNum = 0; + if (firstChar == 0) + break; + if (firstChar == 'm' || firstChar == 'l') { marker = firstChar; diff --git a/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp b/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp index 80bbf95170..29475b19c7 100644 --- a/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp +++ b/src/gui/graphics/geometry/juce_RelativeCoordinate.cpp @@ -28,6 +28,8 @@ BEGIN_JUCE_NAMESPACE #include "juce_RelativeCoordinate.h" +#include "../../../io/streams/juce_MemoryOutputStream.h" + //============================================================================== namespace RelativeCoordinateHelpers @@ -61,9 +63,10 @@ namespace RelativeCoordinateHelpers return fullName.fromFirstOccurrenceOf (".", false, false); } - static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) + static const RelativeCoordinate findCoordinate (const String& name, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { - return nameFinder.findNamedCoordinate (getObjectName (name), getEdgeName (name)); + return nameFinder != 0 ? nameFinder->findNamedCoordinate (getObjectName (name), getEdgeName (name)) + : RelativeCoordinate(); } //============================================================================== @@ -81,6 +84,13 @@ namespace RelativeCoordinateHelpers ++i; } + static void skipComma (const String& s, int& i) + { + skipWhitespace (s, i); + if (s[i] == ',') + ++i; + } + static const String readAnchorName (const String& s, int& i) { skipWhitespace (s, i); @@ -126,10 +136,89 @@ namespace RelativeCoordinateHelpers return value; } + static const RelativeCoordinate readNextCoordinate (const String& s, int& i, const bool isHorizontal) + { + String anchor1 (readAnchorName (s, i)); + double value = 0; + + if (anchor1.isNotEmpty()) + { + skipWhitespace (s, i); + + if (s[i] == '+') + value = readNumber (s, ++i); + else if (s[i] == '-') + value = -readNumber (s, ++i); + + return RelativeCoordinate (value, anchor1); + } + else + { + value = readNumber (s, i); + skipWhitespace (s, i); + + if (s[i] == '%') + { + value /= 100.0; + skipWhitespace (s, ++i); + String anchor2; + + if (s[i] == '*') + { + anchor1 = readAnchorName (s, ++i); + + if (anchor1.isEmpty()) + anchor1 = getOriginAnchorName (isHorizontal); + + skipWhitespace (s, i); + + if (s[i] == '-' && s[i + 1] == '>') + { + i += 2; + anchor2 = readAnchorName (s, i); + } + else + { + anchor2 = anchor1; + anchor1 = getOriginAnchorName (isHorizontal); + } + } + else + { + anchor1 = getOriginAnchorName (isHorizontal); + anchor2 = getExtentAnchorName (isHorizontal); + } + + return RelativeCoordinate (value, anchor1, anchor2); + } + + return RelativeCoordinate (value, isHorizontal); + } + } + static const String limitedAccuracyString (const double n) { return String (n, 3).trimCharactersAtEnd ("0").trimCharactersAtEnd ("."); } + + static bool couldBeMistakenForPathCommand (const String& s) + { + switch (s[0]) + { + case 'a': + case 'm': + case 'l': + case 'z': + case 'q': + case 'c': + return s[1] == 0 || CharacterFunctions::isWhitespace (s[1]); + + default: + break; + } + + return false; + } } //============================================================================== @@ -171,10 +260,27 @@ RelativeCoordinate::RelativeCoordinate (const double relativeProportion, const S jassert (anchor2.isNotEmpty()); } +RelativeCoordinate::RelativeCoordinate (const String& s, const bool isHorizontal) + : value (0) +{ + int i = 0; + *this = RelativeCoordinateHelpers::readNextCoordinate (s, i, isHorizontal); +} + RelativeCoordinate::~RelativeCoordinate() { } +bool RelativeCoordinate::operator== (const RelativeCoordinate& other) const throw() +{ + return value == other.value && anchor1 == other.anchor1 && anchor2 == other.anchor2; +} + +bool RelativeCoordinate::operator!= (const RelativeCoordinate& other) const throw() +{ + return ! operator== (other); +} + //============================================================================== const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate1() const { @@ -186,7 +292,7 @@ const RelativeCoordinate RelativeCoordinate::getAnchorCoordinate2() const return RelativeCoordinate (0.0, anchor2); } -double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter) +double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter) { if (RelativeCoordinateHelpers::isOrigin (anchorName)) return 0.0; @@ -194,7 +300,7 @@ double RelativeCoordinate::resolveAnchor (const String& anchorName, const NamedC return RelativeCoordinateHelpers::findCoordinate (anchorName, nameFinder).resolve (nameFinder, recursionCounter + 1); } -double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const +double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const { if (recursionCounter > 150) { @@ -208,7 +314,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder, int : pos1 + value; } -double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) const +double RelativeCoordinate::resolve (const NamedCoordinateFinder* nameFinder) const { try { @@ -220,7 +326,7 @@ double RelativeCoordinate::resolve (const NamedCoordinateFinder& nameFinder) con return 0.0; } -bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) const +bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder* nameFinder) const { try { @@ -234,7 +340,7 @@ bool RelativeCoordinate::isRecursive (const NamedCoordinateFinder& nameFinder) c return false; } -void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFinder* nameFinder) { try { @@ -256,7 +362,7 @@ void RelativeCoordinate::moveToAbsolute (double newPos, const NamedCoordinateFin {} } -void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal) +void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal) { const double oldValue = resolve (nameFinder); @@ -267,8 +373,7 @@ void RelativeCoordinate::toggleProportionality (const NamedCoordinateFinder& nam moveToAbsolute (oldValue, nameFinder); } -//============================================================================== -bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder& nameFinder) const +bool RelativeCoordinate::references (const String& coordName, const NamedCoordinateFinder* nameFinder) const { using namespace RelativeCoordinateHelpers; @@ -281,65 +386,12 @@ bool RelativeCoordinate::references (const String& coordName, const NamedCoordin || (isProportional() && findCoordinate (anchor2, nameFinder).references (coordName, nameFinder)); } -//============================================================================== -RelativeCoordinate::RelativeCoordinate (const String& s, bool isHorizontal) - : value (0) +bool RelativeCoordinate::isDynamic() const { - using namespace RelativeCoordinateHelpers; - int i = 0; - - anchor1 = readAnchorName (s, i); - - if (anchor1.isNotEmpty()) - { - skipWhitespace (s, i); - - if (s[i] == '+') - value = readNumber (s, ++i); - else if (s[i] == '-') - value = -readNumber (s, ++i); - } - else - { - anchor1 = getOriginAnchorName (isHorizontal); - - value = readNumber (s, i); - skipWhitespace (s, i); - - if (s[i] == '%') - { - value /= 100.0; - skipWhitespace (s, ++i); - - if (s[i] == '*') - { - anchor1 = readAnchorName (s, ++i); - - if (anchor1.isEmpty()) - anchor1 = getOriginAnchorName (isHorizontal); - - skipWhitespace (s, i); - - if (s[i] == '-' && s[i + 1] == '>') - { - i += 2; - anchor2 = readAnchorName (s, i); - } - else - { - anchor2 = anchor1; - anchor1 = getOriginAnchorName (isHorizontal); - } - } - else - { - anchor1 = getOriginAnchorName (isHorizontal); - anchor2 = getExtentAnchorName (isHorizontal); - } - } - } + return anchor2.isNotEmpty() || ! RelativeCoordinateHelpers::isOrigin (anchor1); } +//============================================================================== const String RelativeCoordinate::toString() const { using namespace RelativeCoordinateHelpers; @@ -383,7 +435,7 @@ void RelativeCoordinate::setEditableNumber (const double newValue) } //============================================================================== -void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) { jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); @@ -392,7 +444,7 @@ void RelativeCoordinate::changeAnchor1 (const String& newAnchorName, const Named moveToAbsolute (oldValue, nameFinder); } -void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const NamedCoordinateFinder* nameFinder) { jassert (isProportional()); jassert (newAnchorName.toLowerCase().containsOnly ("abcdefghijklmnopqrstuvwxyz0123456789_.")); @@ -402,7 +454,7 @@ void RelativeCoordinate::changeAnchor2 (const String& newAnchorName, const Named moveToAbsolute (oldValue, nameFinder); } -void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder& nameFinder) +void RelativeCoordinate::renameAnchorIfUsed (const String& oldName, const String& newName, const NamedCoordinateFinder* nameFinder) { using namespace RelativeCoordinateHelpers; jassert (oldName.isNotEmpty()); @@ -439,21 +491,36 @@ RelativePoint::RelativePoint (const Point& absolutePoint) { } -RelativePoint::RelativePoint (const String& stringVersion) +RelativePoint::RelativePoint (const RelativeCoordinate& x_, const RelativeCoordinate& y_) + : x (x_), y (y_) { - const int separator = stringVersion.indexOfChar (','); +} - x = RelativeCoordinate (stringVersion.substring (0, separator), true); - y = RelativeCoordinate (stringVersion.substring (separator + 1), false); +RelativePoint::RelativePoint (const String& s) +{ + int i = 0; + x = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + y = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); } -const Point RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const +bool RelativePoint::operator== (const RelativePoint& other) const throw() +{ + return x == other.x && y == other.y; +} + +bool RelativePoint::operator!= (const RelativePoint& other) const throw() +{ + return ! operator== (other); +} + +const Point RelativePoint::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { return Point ((float) x.resolve (nameFinder), (float) y.resolve (nameFinder)); } -void RelativePoint::moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativePoint::moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { x.moveToAbsolute (newPos.getX(), nameFinder); y.moveToAbsolute (newPos.getY(), nameFinder); @@ -464,12 +531,17 @@ const String RelativePoint::toString() const return x.toString() + ", " + y.toString(); } -void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativePoint::renameAnchorIfUsed (const String& oldName, const String& newName, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { x.renameAnchorIfUsed (oldName, newName, nameFinder); y.renameAnchorIfUsed (oldName, newName, nameFinder); } +bool RelativePoint::isDynamic() const +{ + return x.isDynamic() || y.isDynamic(); +} + //============================================================================== RelativeRectangle::RelativeRectangle() @@ -484,18 +556,29 @@ RelativeRectangle::RelativeRectangle (const Rectangle& rect, const String { } -RelativeRectangle::RelativeRectangle (const String& stringVersion) +RelativeRectangle::RelativeRectangle (const String& s) { - StringArray tokens; - tokens.addTokens (stringVersion, ",", String::empty); + int i = 0; + left = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + top = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); + RelativeCoordinateHelpers::skipComma (s, i); + right = RelativeCoordinateHelpers::readNextCoordinate (s, i, true); + RelativeCoordinateHelpers::skipComma (s, i); + bottom = RelativeCoordinateHelpers::readNextCoordinate (s, i, false); +} - left = RelativeCoordinate (tokens [0], true); - top = RelativeCoordinate (tokens [1], false); - right = RelativeCoordinate (tokens [2], true); - bottom = RelativeCoordinate (tokens [3], false); +bool RelativeRectangle::operator== (const RelativeRectangle& other) const throw() +{ + return left == other.left && top == other.top && right == other.right && bottom == other.bottom; } -const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const +bool RelativeRectangle::operator!= (const RelativeRectangle& other) const throw() +{ + return ! operator== (other); +} + +const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const { const double l = left.resolve (nameFinder); const double r = right.resolve (nameFinder); @@ -505,7 +588,7 @@ const Rectangle RelativeRectangle::resolve (const RelativeCoordinate::Nam return Rectangle ((float) l, (float) t, (float) (r - l), (float) (b - t)); } -void RelativeRectangle::moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder) +void RelativeRectangle::moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { left.moveToAbsolute (newPos.getX(), nameFinder); right.moveToAbsolute (newPos.getRight(), nameFinder); @@ -519,7 +602,7 @@ const String RelativeRectangle::toString() const } void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder) + const RelativeCoordinate::NamedCoordinateFinder* nameFinder) { left.renameAnchorIfUsed (oldName, newName, nameFinder); right.renameAnchorIfUsed (oldName, newName, nameFinder); @@ -528,4 +611,264 @@ void RelativeRectangle::renameAnchorIfUsed (const String& oldName, const String& } +//============================================================================== +RelativePointPath::RelativePointPath() + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ +} + +RelativePointPath::RelativePointPath (const RelativePointPath& other) + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ + parseString (other.toString()); +} + +RelativePointPath::RelativePointPath (const String& s) + : usesNonZeroWinding (true), + containsDynamicPoints (false) +{ + parseString (s); +} + +void RelativePointPath::parseString (const String& s) +{ + int i = 0; + juce_wchar marker = 'm'; + int numValues = 2; + RelativePoint points [3]; + + for (;;) + { + RelativeCoordinateHelpers::skipWhitespace (s, i); + const juce_wchar firstChar = s[i]; + + if (firstChar == 0) + break; + + const juce_wchar secondChar = s[i + 1]; + + if (secondChar == 0 || CharacterFunctions::isWhitespace (secondChar)) + { + if (firstChar == 'm' || firstChar == 'l') + { + ++i; + marker = firstChar; + numValues = 1; + } + else if (firstChar == 'q') + { + ++i; + marker = firstChar; + numValues = 2; + } + else if (firstChar == 'c') + { + ++i; + marker = firstChar; + numValues = 3; + } + else if (firstChar == 'z') + { + ++i; + marker = 'm'; + numValues = 2; + elements.add (new CloseSubPath()); + continue; + } + else if (firstChar == 'a') + { + ++i; + usesNonZeroWinding = false; + continue; + } + } + + if (firstChar == '#') + ++i; + + for (int j = 0; j < numValues; ++j) + { + const RelativeCoordinate x (RelativeCoordinateHelpers::readNextCoordinate (s, i, true)); + const RelativeCoordinate y (RelativeCoordinateHelpers::readNextCoordinate (s, i, false)); + points[j] = RelativePoint (x, y); + containsDynamicPoints = containsDynamicPoints || points[j].isDynamic(); + } + + switch (marker) + { + case 'm': elements.add (new StartSubPath (points[0])); break; + case 'l': elements.add (new LineTo (points[0])); break; + case 'q': elements.add (new QuadraticTo (points[0], points[1])); break; + case 'c': elements.add (new CubicTo (points[0], points[1], points[2])); break; + default: jassertfalse; break; // illegal string format? + } + } +} + +RelativePointPath::~RelativePointPath() +{ +} + +void RelativePointPath::swapWith (RelativePointPath& other) throw() +{ + elements.swapWithArray (other.elements); + swapVariables (usesNonZeroWinding, other.usesNonZeroWinding); +} + +void RelativePointPath::createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) +{ + for (int i = 0; i < elements.size(); ++i) + elements.getUnchecked(i)->addToPath (path, coordFinder); +} + +bool RelativePointPath::containsAnyDynamicPoints() const +{ + return containsDynamicPoints; +} + +const String RelativePointPath::toString() const +{ + ElementType lastType = nullElement; + MemoryOutputStream out; + + if (! usesNonZeroWinding) + out << 'a'; + + for (int i = 0; i < elements.size(); ++i) + { + if (out.getDataSize() > 0) + out << ' '; + + const ElementBase* const e = elements.getUnchecked(i); + e->write (out, lastType); + lastType = e->type; + } + + return out.toUTF8(); +} + +//============================================================================== +RelativePointPath::ElementBase::ElementBase (const ElementType type_) : type (type_) +{ +} + +//============================================================================== +RelativePointPath::StartSubPath::StartSubPath (const RelativePoint& pos) + : ElementBase (startSubPathElement), startPos (pos) +{ +} + +void RelativePointPath::StartSubPath::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p (startPos.toString()); + + if (lastTypeWritten != startSubPathElement) + out << "m "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) + out << '#'; + + out << p; +} + +void RelativePointPath::StartSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p (startPos.resolve (coordFinder)); + path.startNewSubPath (p.getX(), p.getY()); +} + +//============================================================================== +RelativePointPath::CloseSubPath::CloseSubPath() + : ElementBase (closeSubPathElement) +{ +} + +void RelativePointPath::CloseSubPath::write (OutputStream& out, ElementType lastTypeWritten) const +{ + if (lastTypeWritten != closeSubPathElement) + out << 'z'; +} + +void RelativePointPath::CloseSubPath::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder*) const +{ + path.closeSubPath(); +} + +//============================================================================== +RelativePointPath::LineTo::LineTo (const RelativePoint& endPoint_) + : ElementBase (lineToElement), endPoint (endPoint_) +{ +} + +void RelativePointPath::LineTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p (endPoint.toString()); + + if (lastTypeWritten != lineToElement) + out << "l "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p)) + out << '#'; + + out << p; +} + +void RelativePointPath::LineTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p (endPoint.resolve (coordFinder)); + path.lineTo (p.getX(), p.getY()); +} + +//============================================================================== +RelativePointPath::QuadraticTo::QuadraticTo (const RelativePoint& controlPoint_, const RelativePoint& endPoint_) + : ElementBase (quadraticToElement), controlPoint (controlPoint_), endPoint (endPoint_) +{ +} + +void RelativePointPath::QuadraticTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p1 (controlPoint.toString()); + + if (lastTypeWritten != quadraticToElement) + out << "q "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) + out << '#'; + + out << p1 << ' ' << endPoint.toString(); +} + +void RelativePointPath::QuadraticTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p1 (controlPoint.resolve (coordFinder)); + const Point p2 (endPoint.resolve (coordFinder)); + path.quadraticTo (p1.getX(), p1.getY(), p2.getX(), p2.getY()); +} + +//============================================================================== +RelativePointPath::CubicTo::CubicTo (const RelativePoint& controlPoint1_, const RelativePoint& controlPoint2_, const RelativePoint& endPoint_) + : ElementBase (cubicToElement), controlPoint1 (controlPoint1_), controlPoint2 (controlPoint2_), endPoint (endPoint_) +{ +} + +void RelativePointPath::CubicTo::write (OutputStream& out, ElementType lastTypeWritten) const +{ + const String p1 (controlPoint1.toString()); + + if (lastTypeWritten != cubicToElement) + out << "c "; + else if (RelativeCoordinateHelpers::couldBeMistakenForPathCommand (p1)) + out << '#'; + + out << p1 << ' ' << controlPoint2.toString() << ' ' << endPoint.toString(); +} + +void RelativePointPath::CubicTo::addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const +{ + const Point p1 (controlPoint1.resolve (coordFinder)); + const Point p2 (controlPoint2.resolve (coordFinder)); + const Point p3 (endPoint.resolve (coordFinder)); + path.cubicTo (p1.getX(), p1.getY(), p2.getX(), p2.getY(), p3.getX(), p3.getY()); +} + + END_JUCE_NAMESPACE diff --git a/src/gui/graphics/geometry/juce_RelativeCoordinate.h b/src/gui/graphics/geometry/juce_RelativeCoordinate.h index a37abb15b6..d2955c1165 100644 --- a/src/gui/graphics/geometry/juce_RelativeCoordinate.h +++ b/src/gui/graphics/geometry/juce_RelativeCoordinate.h @@ -26,7 +26,9 @@ #ifndef __JUCE_RELATIVECOORDINATE_JUCEHEADER__ #define __JUCE_RELATIVECOORDINATE_JUCEHEADER__ +#include "juce_Path.h" #include "juce_Rectangle.h" +#include "../../../containers/juce_OwnedArray.h" //============================================================================== @@ -101,8 +103,8 @@ public: e.g. "marker1", or it can be a two-part name in the form "objectName.edge". For example "parent.left" is the origin, or "myComponent.top" is the top edge of a component called "myComponent". The exact names that will be recognised are dependent on the NamedCoordinateFinder that you provide for looking them up, but - "parent.left", "parent.top", "parent.right" and "parent.bottom" are always available, representing the - extents of the target coordinate space. + "parent.left" and "parent.top" are always available, meaning the origin. "parent.right" and "parent.bottom" + may also be available if the coordinate space has a fixed size. @param stringVersion the string to parse @param isHorizontal this must be true if this is an X coordinate, or false if it's on the Y axis. @@ -114,6 +116,9 @@ public: /** Destructor. */ ~RelativeCoordinate(); + bool operator== (const RelativeCoordinate& other) const throw(); + bool operator!= (const RelativeCoordinate& other) const throw(); + //============================================================================== /** Provides an interface for looking up the position of a named anchor when resolving a RelativeCoordinate. @@ -145,15 +150,18 @@ public: You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may be needed to calculate the result. */ - double resolve (const NamedCoordinateFinder& nameFinder) const; + double resolve (const NamedCoordinateFinder* nameFinder) const; /** Returns true if this coordinate uses the specified coord name at any level in its evaluation. This will recursively check any coordinates upon which this one depends. */ - bool references (const String& coordName, const NamedCoordinateFinder& nameFinder) const; + bool references (const String& coordName, const NamedCoordinateFinder* nameFinder) const; /** Returns true if there's a recursive loop when trying to resolve this coordinate's position. */ - bool isRecursive (const NamedCoordinateFinder& nameFinder) const; + bool isRecursive (const NamedCoordinateFinder* nameFinder) const; + + /** Returns true if this coordinate depends on any other coordinates for its position. */ + bool isDynamic() const; //============================================================================== /** Changes the value of this coord to make it resolve to the specified position. @@ -162,7 +170,7 @@ public: or relative position to whatever value is necessary to make its resultant position match the position that is provided. */ - void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder& nameFinder); + void moveToAbsolute (double absoluteTargetPosition, const NamedCoordinateFinder* nameFinder); /** Returns true if the coordinate is calculated as a proportion of the distance between two other points. @see toggleProportionality @@ -173,7 +181,7 @@ public: Note that calling this will reset the names of any anchor points, and just make the coordinate relative to the parent origin and parent size. */ - void toggleProportionality (const NamedCoordinateFinder& nameFinder, bool isHorizontal); + void toggleProportionality (const NamedCoordinateFinder* nameFinder, bool isHorizontal); /** Returns a value that can be edited to set this coordinate's position. The meaning of this number depends on the coordinate's mode. If the coordinate is @@ -212,12 +220,12 @@ public: /** Changes the first anchor point, keeping the resultant position of this coordinate in the same place it was previously. */ - void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); + void changeAnchor1 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); /** Changes the second anchor point, keeping the resultant position of this coordinate in the same place it was previously. */ - void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder& nameFinder); + void changeAnchor2 (const String& newAnchor, const NamedCoordinateFinder* nameFinder); /** Tells the coordinate that an object is changing its name or being deleted. @@ -227,7 +235,7 @@ public: instead. */ void renameAnchorIfUsed (const String& oldName, const String& newName, - const NamedCoordinateFinder& nameFinder); + const NamedCoordinateFinder* nameFinder); //============================================================================== /** Returns a string which represents this coordinate. @@ -261,8 +269,8 @@ private: String anchor1, anchor2; double value; - double resolve (const NamedCoordinateFinder& nameFinder, int recursionCounter) const; - static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder& nameFinder, int recursionCounter); + double resolve (const NamedCoordinateFinder* nameFinder, int recursionCounter) const; + static double resolveAnchor (const String& anchorName, const NamedCoordinateFinder* nameFinder, int recursionCounter); }; @@ -281,19 +289,25 @@ public: /** Creates an absolute point, relative to the origin. */ RelativePoint (const Point& absolutePoint); + /** Creates an absolute point from two coordinates. */ + RelativePoint (const RelativeCoordinate& x, const RelativeCoordinate& y); + /** Creates a point from a stringified representation. - The string must contain a pair of coordinates, separated by a comma. The syntax for the coordinate + The string must contain a pair of coordinates, separated by space or a comma. The syntax for the coordinate strings is explained in the RelativeCoordinate class. @see toString */ RelativePoint (const String& stringVersion); + bool operator== (const RelativePoint& other) const throw(); + bool operator!= (const RelativePoint& other) const throw(); + /** Calculates the absolute position of this point. You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may be needed to calculate the result. */ - const Point resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; + const Point resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; /** Changes the values of this point's coordinates to make it resolve to the specified position. @@ -301,7 +315,7 @@ public: or relative positions to whatever values are necessary to make the resultant position match the position that is provided. */ - void moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); + void moveToAbsolute (const Point& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); /** Returns a string which represents this point. This returns a comma-separated pair of coordinates. For details of the string syntax used by the @@ -314,7 +328,10 @@ public: This calls RelativeCoordinate::renameAnchorIfUsed() on its X and Y coordinates. */ void renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder); + const RelativeCoordinate::NamedCoordinateFinder* nameFinder); + + /** Returns true if this point depends on any other coordinates for its position. */ + bool isDynamic() const; // The actual X and Y coords... RelativeCoordinate x, y; @@ -347,13 +364,16 @@ public: */ explicit RelativeRectangle (const String& stringVersion); + bool operator== (const RelativeRectangle& other) const throw(); + bool operator!= (const RelativeRectangle& other) const throw(); + //============================================================================== /** Calculates the absolute position of this rectangle. You'll need to provide a suitable NamedCoordinateFinder for looking up any coordinates that may be needed to calculate the result. */ - const Rectangle resolve (const RelativeCoordinate::NamedCoordinateFinder& nameFinder) const; + const Rectangle resolve (const RelativeCoordinate::NamedCoordinateFinder* nameFinder) const; /** Changes the values of this rectangle's coordinates to make it resolve to the specified position. @@ -361,7 +381,7 @@ public: or relative positions to whatever values are necessary to make the resultant position match the position that is provided. */ - void moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder& nameFinder); + void moveToAbsolute (const Rectangle& newPos, const RelativeCoordinate::NamedCoordinateFinder* nameFinder); /** Returns a string which represents this point. This returns a comma-separated list of coordinates, in the order left, top, right, bottom. For details of @@ -374,11 +394,139 @@ public: This calls RelativeCoordinate::renameAnchorIfUsed() on the rectangle's coordinates. */ void renameAnchorIfUsed (const String& oldName, const String& newName, - const RelativeCoordinate::NamedCoordinateFinder& nameFinder); + const RelativeCoordinate::NamedCoordinateFinder* nameFinder); // The actual rectangle coords... RelativeCoordinate left, right, top, bottom; }; +//============================================================================== +/** + A path object that consists of RelativePoint coordinates rather than the normal fixed ones. + + One of these paths can be converted into a Path object for drawing and manipulation, but + unlike a Path, its points can be dynamic instead of just fixed. + + @see RelativePoint, RelativeCoordinate +*/ +class JUCE_API RelativePointPath +{ +public: + //============================================================================== + RelativePointPath(); + RelativePointPath (const RelativePointPath& other); + RelativePointPath (const String& stringVersion); + ~RelativePointPath(); + + //============================================================================== + /** Resolves this points in this path and adds them to a normal Path object. */ + void createPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder); + + /** Returns true if the path contains any non-fixed points. */ + bool containsAnyDynamicPoints() const; + + /** Returns a string version of the path. + This has the same format as Path::toString(), but since it can contain RelativeCoordinate + positions, it can't be parsed by the Path class if any of the points are dynamic. + */ + const String toString() const; + + /** Quickly swaps the contents of this path with another. */ + void swapWith (RelativePointPath& other) throw(); + + //============================================================================== + /** The types of element that may be contained in this path. + @see RelativePointPath::ElementBase + */ + enum ElementType + { + nullElement, + startSubPathElement, + closeSubPathElement, + lineToElement, + quadraticToElement, + cubicToElement + }; + + //============================================================================== + /** Base class for the elements that make up a RelativePointPath. + */ + class JUCE_API ElementBase + { + public: + ElementBase (ElementType type); + virtual ~ElementBase() {} + virtual void write (OutputStream& out, ElementType lastTypeWritten) const = 0; + virtual void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const = 0; + + const ElementType type; + }; + + class JUCE_API StartSubPath : public ElementBase + { + public: + StartSubPath (const RelativePoint& pos); + ~StartSubPath() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint startPos; + }; + + class JUCE_API CloseSubPath : public ElementBase + { + public: + CloseSubPath(); + ~CloseSubPath() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + }; + + class JUCE_API LineTo : public ElementBase + { + public: + LineTo (const RelativePoint& endPoint); + ~LineTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint endPoint; + }; + + class JUCE_API QuadraticTo : public ElementBase + { + public: + QuadraticTo (const RelativePoint& controlPoint, const RelativePoint& endPoint); + ~QuadraticTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint controlPoint, endPoint; + }; + + class JUCE_API CubicTo : public ElementBase + { + public: + CubicTo (const RelativePoint& controlPoint1, const RelativePoint& controlPoint2, const RelativePoint& endPoint); + ~CubicTo() {} + void write (OutputStream& out, ElementType lastTypeWritten) const; + void addToPath (Path& path, RelativeCoordinate::NamedCoordinateFinder* coordFinder) const; + + RelativePoint controlPoint1, controlPoint2, endPoint; + }; + + //============================================================================== + OwnedArray elements; + bool usesNonZeroWinding; + +private: + bool containsDynamicPoints; + + void parseString (const String& s); + + RelativePointPath& operator= (const RelativePointPath&); +}; + + #endif // __JUCE_RELATIVECOORDINATE_JUCEHEADER__ diff --git a/src/gui/graphics/imaging/juce_ImageCache.cpp b/src/gui/graphics/imaging/juce_ImageCache.cpp index 09514004a9..bedaf3c8b4 100644 --- a/src/gui/graphics/imaging/juce_ImageCache.cpp +++ b/src/gui/graphics/imaging/juce_ImageCache.cpp @@ -131,6 +131,9 @@ void ImageCache::releaseOrDelete (Image* const imageToRelease) bool ImageCache::isImageInCache (Image* const imageToLookFor) { + if (imageToLookFor == 0) + return false; + if (instance != 0) { const ScopedLock sl (instance->lock); diff --git a/src/io/files/juce_DirectoryIterator.cpp b/src/io/files/juce_DirectoryIterator.cpp index 63d9b295b4..2fce8875b9 100644 --- a/src/io/files/juce_DirectoryIterator.cpp +++ b/src/io/files/juce_DirectoryIterator.cpp @@ -35,7 +35,7 @@ DirectoryIterator::DirectoryIterator (const File& directory, bool isRecursive_, const String& wildCard_, const int whatToLookFor_) - : fileFinder (directory, isRecursive ? "*" : wildCard_), + : fileFinder (directory, isRecursive_ ? "*" : wildCard_), wildCard (wildCard_), path (File::addTrailingSeparator (directory.getFullPathName())), index (-1), diff --git a/src/native/linux/juce_linux_Windowing.cpp b/src/native/linux/juce_linux_Windowing.cpp index 732307cfc0..a16b21f4c2 100644 --- a/src/native/linux/juce_linux_Windowing.cpp +++ b/src/native/linux/juce_linux_Windowing.cpp @@ -1091,15 +1091,9 @@ public: { } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { - if (Rectangle::intersectRectangles (x, y, w, h, - 0, 0, - getComponent()->getWidth(), - getComponent()->getHeight())) - { - repainter->repaint (x, y, w, h); - } + repainter->repaint (area.getIntersection (getComponent()->getLocalBounds())); } void performAnyPendingRepaintsNow() @@ -1526,8 +1520,8 @@ public: &child); } - repaint (exposeEvent->x, exposeEvent->y, - exposeEvent->width, exposeEvent->height); + repaint (Rectangle (exposeEvent->x, exposeEvent->y, + exposeEvent->width, exposeEvent->height)); while (XEventsQueued (display, QueuedAfterFlush) > 0) { @@ -1537,8 +1531,8 @@ public: XNextEvent (display, (XEvent*) &nextEvent); XExposeEvent* nextExposeEvent = (XExposeEvent*) &nextEvent.xexpose; - repaint (nextExposeEvent->x, nextExposeEvent->y, - nextExposeEvent->width, nextExposeEvent->height); + repaint (Rectangle (nextExposeEvent->x, nextExposeEvent->y, + nextExposeEvent->width, nextExposeEvent->height)); } break; @@ -1838,12 +1832,12 @@ private: } } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { if (! isTimerRunning()) startTimer (repaintTimerPeriod); - regionsNeedingRepaint.add (x, y, w, h); + regionsNeedingRepaint.add (area); } void performAnyPendingRepaintsNow() diff --git a/src/native/mac/juce_iphone_UIViewComponentPeer.mm b/src/native/mac/juce_iphone_UIViewComponentPeer.mm index 67fcdf97ef..e1d6a664af 100644 --- a/src/native/mac/juce_iphone_UIViewComponentPeer.mm +++ b/src/native/mac/juce_iphone_UIViewComponentPeer.mm @@ -138,7 +138,7 @@ public: void handleTouches (UIEvent* e, bool isDown, bool isUp, bool isCancel); //============================================================================== - void repaint (int x, int y, int w, int h); + void repaint (const Rectangle& area); void performAnyPendingRepaintsNow(); //============================================================================== @@ -849,19 +849,20 @@ public: void messageCallback() { if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + peer->repaint (rect); } }; -void UIViewComponentPeer::repaint (int x, int y, int w, int h) +void UIViewComponentPeer::repaint (const Rectangle& area) { if (insideDrawRect || ! MessageManager::getInstance()->isThisTheMessageThread()) { - (new AsyncRepaintMessage (this, Rectangle (x, y, w, h)))->post(); + (new AsyncRepaintMessage (this, area))->post(); } else { - [view setNeedsDisplayInRect: CGRectMake ((float) x, (float) y, (float) w, (float) h)]; + [view setNeedsDisplayInRect: CGRectMake ((float) area.getX(), (float) area.getY(), + (float) area.getWidth(), (float) area.getHeight())]; } } diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index fc185f3852..69f68d3db7 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -253,7 +253,7 @@ public: void textInputRequired (const Point& position); //============================================================================== - void repaint (int x, int y, int w, int h); + void repaint (const Rectangle& area); void performAnyPendingRepaintsNow(); //============================================================================== @@ -1631,20 +1631,20 @@ public: void messageCallback() { if (ComponentPeer::isValidPeer (peer)) - peer->repaint (rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight()); + peer->repaint (rect); } }; -void NSViewComponentPeer::repaint (int x, int y, int w, int h) +void NSViewComponentPeer::repaint (const Rectangle& area) { if (insideDrawRect) { - (new AsyncRepaintMessage (this, Rectangle (x, y, w, h)))->post(); + (new AsyncRepaintMessage (this, area))->post(); } else { - [view setNeedsDisplayInRect: NSMakeRect ((float) x, (float) ([view frame].size.height - (y + h)), - (float) w, (float) h)]; + [view setNeedsDisplayInRect: NSMakeRect ((float) area.getX(), [view frame].size.height - (float) area.getBottom(), + (float) area.getWidth(), (float) area.getHeight())]; } } diff --git a/src/native/windows/juce_win32_ASIO.cpp b/src/native/windows/juce_win32_ASIO.cpp index 1c4da5413c..ac339e99b2 100644 --- a/src/native/windows/juce_win32_ASIO.cpp +++ b/src/native/windows/juce_win32_ASIO.cpp @@ -597,7 +597,10 @@ public: Thread::sleep (20); isStarted = false; isOpen_ = false; - close(); + + const String errorCopy (error); + close(); // (this resets the error string) + error = errorCopy; } needToReset = false; diff --git a/src/native/windows/juce_win32_OpenGLComponent.cpp b/src/native/windows/juce_win32_OpenGLComponent.cpp index 1c84c9dcc2..9df13b5f7a 100644 --- a/src/native/windows/juce_win32_OpenGLComponent.cpp +++ b/src/native/windows/juce_win32_OpenGLComponent.cpp @@ -288,8 +288,7 @@ public: void repaint() { - const Rectangle bounds (nativeWindow->getBounds()); - nativeWindow->repaint (0, 0, bounds.getWidth(), bounds.getHeight()); + nativeWindow->repaint (nativeWindow->getBounds().withPosition (Point())); } void swapBuffers() diff --git a/src/native/windows/juce_win32_WASAPI.cpp b/src/native/windows/juce_win32_WASAPI.cpp index 56b281832a..2e44320d74 100644 --- a/src/native/windows/juce_win32_WASAPI.cpp +++ b/src/native/windows/juce_win32_WASAPI.cpp @@ -685,7 +685,7 @@ public: int getInputLatencyInSamples() { return latencyIn; } const BigInteger getActiveOutputChannels() const { return outputDevice != 0 ? outputDevice->channels : BigInteger(); } const BigInteger getActiveInputChannels() const { return inputDevice != 0 ? inputDevice->channels : BigInteger(); } - const String getLastError() { return lastError; } + const String getLastError() { return lastError; } const String open (const BigInteger& inputChannels, const BigInteger& outputChannels, diff --git a/src/native/windows/juce_win32_Windowing.cpp b/src/native/windows/juce_win32_Windowing.cpp index c74c078b3b..2d6876e102 100644 --- a/src/native/windows/juce_win32_Windowing.cpp +++ b/src/native/windows/juce_win32_Windowing.cpp @@ -705,9 +705,9 @@ public: SetCaretPos (0, 0); } - void repaint (int x, int y, int w, int h) + void repaint (const Rectangle& area) { - const RECT r = { x, y, x + w, y + h }; + const RECT r = { area.getX(), area.getY(), area.getRight(), area.getBottom() }; InvalidateRect (hwnd, &r, FALSE); } diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index 84a8cc5c86..a05ebfb6c4 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -1055,9 +1055,7 @@ static int indexOfMatch (const juce_wchar* const wildcard, else { if (wc == '*' && (wildcard [i + 1] == 0 - || indexOfMatch (wildcard + i + 1, - test + start + i, - ignoreCase) >= 0)) + || indexOfMatch (wildcard + i + 1, test + start + i, ignoreCase) >= 0)) { return start; } @@ -1093,9 +1091,7 @@ bool String::matchesWildcard (const String& wildcard, const bool ignoreCase) con else { return wc == '*' && (wildcard [i + 1] == 0 - || indexOfMatch (wildcard.text + i + 1, - text + i, - ignoreCase) >= 0); + || indexOfMatch (wildcard.text + i + 1, text + i, ignoreCase) >= 0); } } }