diff --git a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
index 09b23863f4..7ae8d4e55d 100644
--- a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
+++ b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
@@ -3078,6 +3078,14 @@
+
+
+
+
+
+
+
+
diff --git a/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj b/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
index e8b751c6b1..5f20672a3e 100644
--- a/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
+++ b/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
@@ -272,6 +272,7 @@
400E4C67ABCDDB1D49EBB85E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TabbedComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TabbedComponentHandler.h"; sourceTree = "SOURCE_ROOT"; };
4076F14FE0016A4DA9087771 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CPlusPlusCodeTokeniserFunctions.h"; path = "../../../../modules/juce_gui_extra/code_editor/juce_CPlusPlusCodeTokeniserFunctions.h"; sourceTree = "SOURCE_ROOT"; };
40A83A20ED109AAAE6D63AF4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DrawableRectangle.h"; path = "../../../../modules/juce_gui_basics/drawables/juce_DrawableRectangle.h"; sourceTree = "SOURCE_ROOT"; };
+ 40BFF5B7BB816333201855F5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; };
41105E536155E394E54BDD35 = { isa = PBXFileReference; lastKnownFileType = file.xml; name = "colourscheme_dark.xml"; path = "../../Source/BinaryData/colourscheme_dark.xml"; sourceTree = "SOURCE_ROOT"; };
412B48D0F05D78A73064B36B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TopLevelWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_TopLevelWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
41CA95403E264AA7457A61F4 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_PaintElementRoundedRectangle.h"; path = "../../Source/ComponentEditor/paintelements/jucer_PaintElementRoundedRectangle.h"; sourceTree = "SOURCE_ROOT"; };
@@ -401,6 +402,7 @@
6736FDF36413E6445C526C86 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadPool.cpp"; path = "../../../../modules/juce_core/threads/juce_ThreadPool.cpp"; sourceTree = "SOURCE_ROOT"; };
68351D69C94230D1DCDB8345 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Threads.cpp"; path = "../../../../modules/juce_core/native/juce_android_Threads.cpp"; sourceTree = "SOURCE_ROOT"; };
684D88D936EDF46A76EC0538 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Colours.cpp"; path = "../../../../modules/juce_graphics/colour/juce_Colours.cpp"; sourceTree = "SOURCE_ROOT"; };
+ 68B2A7661E219540E9ADB945 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
68C633ECE610641BB1D21C95 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageConvolutionKernel.h"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.h"; sourceTree = "SOURCE_ROOT"; };
68E1CA6424A84D91BEA46175 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_GZIPCompressorOutputStream.h"; path = "../../../../modules/juce_core/zip/juce_GZIPCompressorOutputStream.h"; sourceTree = "SOURCE_ROOT"; };
6920079B91BB1A48F82C7B0A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_RelativePoint.h"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativePoint.h"; sourceTree = "SOURCE_ROOT"; };
@@ -758,6 +760,7 @@
D926E13AB5AD647A7A00F486 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Network.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Network.cpp"; sourceTree = "SOURCE_ROOT"; };
D9342535EA61901A1AD816C6 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_WebBrowserComponent.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
D9B077E2ECDDA94961E134D7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_StringPairArray.h"; path = "../../../../modules/juce_core/text/juce_StringPairArray.h"; sourceTree = "SOURCE_ROOT"; };
+ D9E59DE07A815AB303A297D9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../../../modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
DAF84A553D264705FA6EB6FF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TreeViewHandler.h"; path = "../../Source/ComponentEditor/components/jucer_TreeViewHandler.h"; sourceTree = "SOURCE_ROOT"; };
DB876F7873F42DC685A58CA7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_JPEGLoader.cpp"; path = "../../../../modules/juce_graphics/image_formats/juce_JPEGLoader.cpp"; sourceTree = "SOURCE_ROOT"; };
DBE0CDE1B017190ABBFF557C = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExport_CodeBlocks.h"; path = "../../Source/Project Saving/jucer_ProjectExport_CodeBlocks.h"; sourceTree = "SOURCE_ROOT"; };
@@ -775,7 +778,6 @@
D87FC8F6834E9DC9C8E88B94 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_JustificationProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_JustificationProperty.h"; sourceTree = "SOURCE_ROOT"; };
D92A6E9404A30EED32DCE4ED = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_RelativePositionedRectangle.h"; path = "../../Source/ComponentEditor/ui/jucer_RelativePositionedRectangle.h"; sourceTree = "SOURCE_ROOT"; };
D95D7B49EC6C6BDCB5A1B988 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_ios_MessageManager.mm"; path = "../../../../modules/juce_events/native/juce_ios_MessageManager.mm"; sourceTree = "SOURCE_ROOT"; };
- D9E59DE07A815AB303A297D9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_data_structures.mm"; path = "../../../../modules/juce_data_structures/juce_data_structures.mm"; sourceTree = "SOURCE_ROOT"; };
DA345D5B9DABD049F90DC96F = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GeneratedCode.h"; path = "../../Source/ComponentEditor/jucer_GeneratedCode.h"; sourceTree = "SOURCE_ROOT"; };
DB20268A566DABEAE3F2CBEE = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RectanglePlacement.cpp"; path = "../../../../modules/juce_graphics/placement/juce_RectanglePlacement.cpp"; sourceTree = "SOURCE_ROOT"; };
DC922C6A65D260C18E888E49 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ComponentTemplate.cpp"; path = "../../Source/BinaryData/jucer_ComponentTemplate.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -1805,6 +1807,8 @@
B6D03F8491E288FD4BC31445,
AD44FFB01387088222D0E98F,
971FD8FEAE9A521A6983B8C9,
+ 68B2A7661E219540E9ADB945,
+ 40BFF5B7BB816333201855F5,
25E306BB0D875CB0934C405C,
322A68B4BBEE9CC039B9E024,
6B8796ED91A82AB5A8EB922F,
diff --git a/extras/Introjucer/Builds/VisualStudio2005/The Introjucer.vcproj b/extras/Introjucer/Builds/VisualStudio2005/The Introjucer.vcproj
index 98ad66460c..1503927a71 100644
--- a/extras/Introjucer/Builds/VisualStudio2005/The Introjucer.vcproj
+++ b/extras/Introjucer/Builds/VisualStudio2005/The Introjucer.vcproj
@@ -3650,6 +3650,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2008/The Introjucer.vcproj b/extras/Introjucer/Builds/VisualStudio2008/The Introjucer.vcproj
index 8e954fc14b..e15b43af66 100644
--- a/extras/Introjucer/Builds/VisualStudio2008/The Introjucer.vcproj
+++ b/extras/Introjucer/Builds/VisualStudio2008/The Introjucer.vcproj
@@ -3650,6 +3650,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
index 2eedc6bb47..f883ef166d 100644
--- a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
@@ -973,6 +973,9 @@
true
+
+ true
+
true
@@ -1457,6 +1460,7 @@
+
diff --git a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
index 3e0cecea4f..8f7cb49d36 100644
--- a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
@@ -1222,6 +1222,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
@@ -2616,6 +2619,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
diff --git a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
index 0b763888ae..858ed9834a 100644
--- a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
@@ -979,6 +979,9 @@
true
+
+ true
+
true
@@ -1463,6 +1466,7 @@
+
diff --git a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
index 3e0cecea4f..8f7cb49d36 100644
--- a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
@@ -1222,6 +1222,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
@@ -2616,6 +2619,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
diff --git a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
index 523d2e8637..54ccdb0fff 100644
--- a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
@@ -979,6 +979,9 @@
true
+
+ true
+
true
@@ -1463,6 +1466,7 @@
+
diff --git a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
index e4f8c65a99..9fba265306 100644
--- a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
@@ -1222,6 +1222,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
@@ -2616,6 +2619,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
diff --git a/extras/Introjucer/JuceLibraryCode/AppConfig.h b/extras/Introjucer/JuceLibraryCode/AppConfig.h
index b721cdab16..9089dd5d63 100644
--- a/extras/Introjucer/JuceLibraryCode/AppConfig.h
+++ b/extras/Introjucer/JuceLibraryCode/AppConfig.h
@@ -90,5 +90,9 @@
//#define JUCE_WEB_BROWSER
#endif
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+#endif
+
#endif // __JUCE_APPCONFIG_M70QFTRRK__
diff --git a/extras/audio plugin demo/Builds/MacOSX/JuceDemoPlugin.xcodeproj/project.pbxproj b/extras/audio plugin demo/Builds/MacOSX/JuceDemoPlugin.xcodeproj/project.pbxproj
index efe1d82472..cb5d126006 100644
--- a/extras/audio plugin demo/Builds/MacOSX/JuceDemoPlugin.xcodeproj/project.pbxproj
+++ b/extras/audio plugin demo/Builds/MacOSX/JuceDemoPlugin.xcodeproj/project.pbxproj
@@ -524,6 +524,7 @@
81AC7FA7234FD8DD6D4F647C = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MouseInputSource.cpp"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseInputSource.cpp"; sourceTree = "SOURCE_ROOT"; };
82C8DD36FD45CF3CC8BC2819 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_XmlElement.cpp"; path = "../../../../modules/juce_core/xml/juce_XmlElement.cpp"; sourceTree = "SOURCE_ROOT"; };
82D8099FDD46339EF81ADC57 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MemoryInputStream.cpp"; path = "../../../../modules/juce_core/streams/juce_MemoryInputStream.cpp"; sourceTree = "SOURCE_ROOT"; };
+ 8369433A1004C92903664568 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
837035EBD15D2565B4DB677A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_SystemTrayIcon.cpp"; path = "../../../../modules/juce_gui_extra/native/juce_win32_SystemTrayIcon.cpp"; sourceTree = "SOURCE_ROOT"; };
837FCD576EB86FDB2FB63DAF = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ProgressBar.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_ProgressBar.cpp"; sourceTree = "SOURCE_ROOT"; };
841B6783475386C5471CA039 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_PluginHostType.h"; path = "../../../../modules/juce_audio_plugin_client/utility/juce_PluginHostType.h"; sourceTree = "SOURCE_ROOT"; };
@@ -763,6 +764,7 @@
C97C1ED9A68926C6494837CD = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Path.h"; path = "../../../../modules/juce_graphics/geometry/juce_Path.h"; sourceTree = "SOURCE_ROOT"; };
CA6A796A330E12E920650F7A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_win32_WASAPI.cpp"; path = "../../../../modules/juce_audio_devices/native/juce_win32_WASAPI.cpp"; sourceTree = "SOURCE_ROOT"; };
CAF2236203B78927A4107D7F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_posix_NamedPipe.cpp"; path = "../../../../modules/juce_core/native/juce_posix_NamedPipe.cpp"; sourceTree = "SOURCE_ROOT"; };
+ CBAA0F879FD03402D1DCBDC2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; };
CBFB91131B82AA2F0BDD3EB7 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MessageListener.h"; path = "../../../../modules/juce_events/messages/juce_MessageListener.h"; sourceTree = "SOURCE_ROOT"; };
CC04A3CE3003C0A0AB35A7AF = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_VSTPluginFormat.h"; path = "../../../../modules/juce_audio_processors/format_types/juce_VSTPluginFormat.h"; sourceTree = "SOURCE_ROOT"; };
CC9181E8112D4E033592A78B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileTreeComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileTreeComponent.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1903,6 +1905,8 @@
6615AA3C51D65AA6586812C4,
0148FA619D1F0E5A597356FD,
7368B0046A2F265498F9DD5E,
+ 8369433A1004C92903664568,
+ CBAA0F879FD03402D1DCBDC2,
B6938F0B102875B8B0BEBC44,
8E40EB375F5C4AE1651F3E49,
4B13AFACB5B6B81347E6652D,
diff --git a/extras/audio plugin demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj b/extras/audio plugin demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
index 031e1d20b5..8d2c918a3f 100644
--- a/extras/audio plugin demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
+++ b/extras/audio plugin demo/Builds/VisualStudio2005/JuceDemoPlugin.vcproj
@@ -4173,6 +4173,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/audio plugin demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj b/extras/audio plugin demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
index c87d2db151..6fb250a46f 100644
--- a/extras/audio plugin demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
+++ b/extras/audio plugin demo/Builds/VisualStudio2008/JuceDemoPlugin.vcproj
@@ -4173,6 +4173,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/audio plugin demo/JuceLibraryCode/AppConfig.h b/extras/audio plugin demo/JuceLibraryCode/AppConfig.h
index d22069ea9d..90e23cd3e6 100644
--- a/extras/audio plugin demo/JuceLibraryCode/AppConfig.h
+++ b/extras/audio plugin demo/JuceLibraryCode/AppConfig.h
@@ -168,6 +168,10 @@
//#define JUCE_WEB_BROWSER
#endif
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+#endif
+
//==============================================================================
// Audio plugin settings..
diff --git a/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj b/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj
index 75590501e4..3ca2c6cc5e 100644
--- a/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj
+++ b/extras/audio plugin host/Builds/MacOSX/Plugin Host.xcodeproj/project.pbxproj
@@ -440,6 +440,7 @@
73885C1BF5AC1EEA39ECA545 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_MP3AudioFormat.cpp"; path = "../../../../modules/juce_audio_formats/codecs/juce_MP3AudioFormat.cpp"; sourceTree = "SOURCE_ROOT"; };
7399BECD1499CBFE6CB6C9B5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; };
740BB2D6D4D42F73A8334824 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_FileChooser.mm"; path = "../../../../modules/juce_gui_basics/native/juce_mac_FileChooser.mm"; sourceTree = "SOURCE_ROOT"; };
+ 74119FA71333036A0758086F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
74CAA9C9A8F37A9FF99103F5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Draggable3DOrientation.h"; path = "../../../../modules/juce_opengl/opengl/juce_Draggable3DOrientation.h"; sourceTree = "SOURCE_ROOT"; };
75F290D7B7C53C03DC653FC5 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TimeSliceThread.h"; path = "../../../../modules/juce_core/threads/juce_TimeSliceThread.h"; sourceTree = "SOURCE_ROOT"; };
75FCAA8D3DF24813844D6552 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandTarget.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandTarget.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -658,6 +659,7 @@
B457EE687507BF1DEEA7581F = { isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
B49AAED30299568B2E4A864A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ResizableBorderComponent.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_ResizableBorderComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
B4BFC5F162F99B035930F03A = { isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Info.plist; sourceTree = "SOURCE_ROOT"; };
+ B516D9B5AC00A19188E1CD29 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; };
B5492BAE24B59959545BEB3F = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; };
B55834D8DBE6EC39178A526B = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Viewport.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_Viewport.cpp"; sourceTree = "SOURCE_ROOT"; };
B5C03BAD5EB1BFD2AFE73D33 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_TextPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -1861,6 +1863,8 @@
F95046FD2C915F846BD111EF,
0647115F688F4B35C22C0A56,
42AE0D20F6FAC03F7D27A9DD,
+ 74119FA71333036A0758086F,
+ B516D9B5AC00A19188E1CD29,
E4C80E4A79A8DBD69192B3DF,
B82F87C30426983F2D051615,
EB483815A529FAF11907FC6F,
diff --git a/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj b/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj
index 029f8e6030..a709adc219 100644
--- a/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj
+++ b/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj
@@ -1141,6 +1141,9 @@
true
+
+ true
+
true
@@ -1635,6 +1638,7 @@
+
diff --git a/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj.filters b/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj.filters
index 6ed715cf7a..17d8abebcf 100644
--- a/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj.filters
+++ b/extras/audio plugin host/Builds/VisualStudio2010/Plugin Host.vcxproj.filters
@@ -1384,6 +1384,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
@@ -2742,6 +2745,9 @@
Juce Modules\juce_gui_extra\misc
+
+ Juce Modules\juce_gui_extra\misc
+
Juce Modules\juce_gui_extra\misc
diff --git a/extras/audio plugin host/JuceLibraryCode/AppConfig.h b/extras/audio plugin host/JuceLibraryCode/AppConfig.h
index 5c4ee1af89..dcf1f148a9 100644
--- a/extras/audio plugin host/JuceLibraryCode/AppConfig.h
+++ b/extras/audio plugin host/JuceLibraryCode/AppConfig.h
@@ -170,6 +170,10 @@
#define JUCE_WEB_BROWSER 0
#endif
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+#endif
+
//==============================================================================
// juce_video flags:
diff --git a/extras/example projects/Builds/MacOSX/HelloWorld.xcodeproj/project.pbxproj b/extras/example projects/Builds/MacOSX/HelloWorld.xcodeproj/project.pbxproj
index 87f526ae9b..9ef0a8295c 100644
--- a/extras/example projects/Builds/MacOSX/HelloWorld.xcodeproj/project.pbxproj
+++ b/extras/example projects/Builds/MacOSX/HelloWorld.xcodeproj/project.pbxproj
@@ -602,6 +602,7 @@
E945ED94EAF101B29713C322 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; };
E96CBEBCDABA3EA741C4C2EC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; };
E9904E84AFCF3AB39B03BAA9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; };
+ EA433D25CF79DF86FEF978D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
ECC4847BBD2AC72116506F0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; };
ED577465CA22A65861192A35 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; };
ED872E47438BBE6325FE78F2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -626,6 +627,7 @@
F420591CACE7056F78000039 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../../../modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; };
F45A8AE5F6E6FA5F6AEC8D12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; };
F4AB976B460420C5C94E6E9A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; };
+ F5047DA45BA2ECE24D308403 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; };
F58C62E4CFF820B85CEF0A9A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; };
F59A5377B8D4476B34214F98 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; };
F5D2E9784191EC7F2DFA3949 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1367,6 +1369,8 @@
C234FBE6290024F51478686E,
2199D426EC85451D81636490,
0F5CBF5A5C2283DA1344E55E,
+ EA433D25CF79DF86FEF978D1,
+ F5047DA45BA2ECE24D308403,
0D3ACCBA2F79A0C6444AF72C,
495652C9E6B06C891281D040,
30D62F5F1125F39CE8D28C78,
diff --git a/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj b/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
index dc165194e5..a715d9d22a 100644
--- a/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
+++ b/extras/example projects/Builds/VisualStudio2005/HelloWorld.vcproj
@@ -3188,6 +3188,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj b/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
index 8c8efed119..6154e7b31f 100644
--- a/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
+++ b/extras/example projects/Builds/VisualStudio2008/HelloWorld.vcproj
@@ -3188,6 +3188,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj b/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj
index 9ac986f0ab..3aafc90b2e 100644
--- a/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj
+++ b/extras/example projects/Builds/iOS/HelloWorld.xcodeproj/project.pbxproj
@@ -598,6 +598,7 @@
E945ED94EAF101B29713C322 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DynamicObject.cpp"; path = "../../../../modules/juce_core/containers/juce_DynamicObject.cpp"; sourceTree = "SOURCE_ROOT"; };
E96CBEBCDABA3EA741C4C2EC = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_android_Windowing.cpp"; path = "../../../../modules/juce_gui_basics/native/juce_android_Windowing.cpp"; sourceTree = "SOURCE_ROOT"; };
E9904E84AFCF3AB39B03BAA9 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ApplicationCommandManager.cpp"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandManager.cpp"; sourceTree = "SOURCE_ROOT"; };
+ EA433D25CF79DF86FEF978D1 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_LiveConstantEditor.cpp"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
ECC4847BBD2AC72116506F0E = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; };
ED577465CA22A65861192A35 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TooltipClient.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TooltipClient.h"; sourceTree = "SOURCE_ROOT"; };
ED872E47438BBE6325FE78F2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_GlyphArrangement.cpp"; path = "../../../../modules/juce_graphics/fonts/juce_GlyphArrangement.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -621,6 +622,7 @@
F420591CACE7056F78000039 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Value.cpp"; path = "../../../../modules/juce_data_structures/values/juce_Value.cpp"; sourceTree = "SOURCE_ROOT"; };
F45A8AE5F6E6FA5F6AEC8D12 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TabbedButtonBar.cpp"; path = "../../../../modules/juce_gui_basics/layout/juce_TabbedButtonBar.cpp"; sourceTree = "SOURCE_ROOT"; };
F4AB976B460420C5C94E6E9A = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ColourGradient.h"; path = "../../../../modules/juce_graphics/colour/juce_ColourGradient.h"; sourceTree = "SOURCE_ROOT"; };
+ F5047DA45BA2ECE24D308403 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_LiveConstantEditor.h"; path = "../../../../modules/juce_gui_extra/misc/juce_LiveConstantEditor.h"; sourceTree = "SOURCE_ROOT"; };
F58C62E4CFF820B85CEF0A9A = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageConvolutionKernel.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageConvolutionKernel.cpp"; sourceTree = "SOURCE_ROOT"; };
F59A5377B8D4476B34214F98 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_KeyPressMappingSet.h"; path = "../../../../modules/juce_gui_basics/commands/juce_KeyPressMappingSet.h"; sourceTree = "SOURCE_ROOT"; };
F5D2E9784191EC7F2DFA3949 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_AbstractFifo.h"; path = "../../../../modules/juce_core/containers/juce_AbstractFifo.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1365,6 +1367,8 @@
C234FBE6290024F51478686E,
2199D426EC85451D81636490,
0F5CBF5A5C2283DA1344E55E,
+ EA433D25CF79DF86FEF978D1,
+ F5047DA45BA2ECE24D308403,
0D3ACCBA2F79A0C6444AF72C,
495652C9E6B06C891281D040,
30D62F5F1125F39CE8D28C78,
diff --git a/extras/example projects/JuceLibraryCode/AppConfig.h b/extras/example projects/JuceLibraryCode/AppConfig.h
index a9bf7747ec..23e7bb0439 100644
--- a/extras/example projects/JuceLibraryCode/AppConfig.h
+++ b/extras/example projects/JuceLibraryCode/AppConfig.h
@@ -89,5 +89,9 @@
//#define JUCE_WEB_BROWSER
#endif
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+#endif
+
#endif // __JUCE_APPCONFIG_TTAKTK1S__
diff --git a/extras/windows dll/Builds/VisualStudio2008/juce_dll.vcproj b/extras/windows dll/Builds/VisualStudio2008/juce_dll.vcproj
index 7738e5203a..2f90983091 100644
--- a/extras/windows dll/Builds/VisualStudio2008/juce_dll.vcproj
+++ b/extras/windows dll/Builds/VisualStudio2008/juce_dll.vcproj
@@ -4178,6 +4178,17 @@
+
+
+
+
+
+
+
+
+
diff --git a/extras/windows dll/JuceLibraryCode/AppConfig.h b/extras/windows dll/JuceLibraryCode/AppConfig.h
index 496607d66f..6ecc9c9df2 100644
--- a/extras/windows dll/JuceLibraryCode/AppConfig.h
+++ b/extras/windows dll/JuceLibraryCode/AppConfig.h
@@ -170,6 +170,10 @@
//#define JUCE_WEB_BROWSER
#endif
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ //#define JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+#endif
+
//==============================================================================
// juce_video flags:
diff --git a/modules/juce_gui_extra/juce_gui_extra.cpp b/modules/juce_gui_extra/juce_gui_extra.cpp
index 764c33c107..23fbdcfe8a 100644
--- a/modules/juce_gui_extra/juce_gui_extra.cpp
+++ b/modules/juce_gui_extra/juce_gui_extra.cpp
@@ -93,6 +93,7 @@ namespace juce
#include "misc/juce_RecentlyOpenedFilesList.cpp"
#include "misc/juce_SplashScreen.cpp"
#include "misc/juce_SystemTrayIconComponent.cpp"
+#include "misc/juce_LiveConstantEditor.cpp"
}
diff --git a/modules/juce_gui_extra/juce_gui_extra.h b/modules/juce_gui_extra/juce_gui_extra.h
index aead733e32..955b888a21 100644
--- a/modules/juce_gui_extra/juce_gui_extra.h
+++ b/modules/juce_gui_extra/juce_gui_extra.h
@@ -37,6 +37,14 @@
#define JUCE_WEB_BROWSER 1
#endif
+/** Config: JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ This lets you turn on the JUCE_ENABLE_LIVE_CONSTANT_EDITOR support. See the documentation
+ for that macro for more details.
+*/
+#ifndef JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+ #define JUCE_ENABLE_LIVE_CONSTANT_EDITOR 0
+#endif
+
//=============================================================================
namespace juce
{
@@ -59,6 +67,7 @@ namespace juce
#include "misc/juce_SplashScreen.h"
#include "misc/juce_SystemTrayIconComponent.h"
#include "misc/juce_WebBrowserComponent.h"
+#include "misc/juce_LiveConstantEditor.h"
}
diff --git a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp
new file mode 100644
index 0000000000..dd975c5bf5
--- /dev/null
+++ b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.cpp
@@ -0,0 +1,445 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+
+ Permission is granted to use this software under the terms of either:
+ a) the GPL v2 (or any later version)
+ b) the Affero GPL v3
+
+ Details of these licenses can be found at: www.gnu.org/licenses
+
+ JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ ------------------------------------------------------------------------------
+
+ To release a closed-source product which uses JUCE, commercial licenses are
+ available: visit www.juce.com for more information.
+
+ ==============================================================================
+*/
+
+#if JUCE_ENABLE_LIVE_CONSTANT_EDITOR
+
+namespace LiveConstantEditor
+{
+
+//==============================================================================
+class AllComponentRepainter : private Timer,
+ private DeletedAtShutdown
+{
+public:
+ AllComponentRepainter() {}
+
+ static AllComponentRepainter& getInstance()
+ {
+ static AllComponentRepainter* instance = new AllComponentRepainter();
+ return *instance;
+ }
+
+ void trigger()
+ {
+ startTimer (70);
+ }
+
+private:
+ void timerCallback() override
+ {
+ stopTimer();
+
+ for (int i = TopLevelWindow::getNumTopLevelWindows(); --i >= 0;)
+ if (Component* c = TopLevelWindow::getTopLevelWindow(i))
+ repaintAndResizeAllComps (c);
+ }
+
+ static void repaintAndResizeAllComps (Component::SafePointer c)
+ {
+ for (int i = c->getNumChildComponents(); --i >= 0;)
+ {
+ if (c != nullptr)
+ {
+ if (Component* child = c->getChildComponent(i))
+ {
+ child->repaint();
+ child->resized();
+ }
+ }
+ }
+ }
+};
+
+//==============================================================================
+int64 parseInt (String s)
+{
+ s = s.retainCharacters ("0123456789abcdefABCDEFx");
+
+ if (s.startsWith ("0x"))
+ return s.substring(2).getHexValue64();
+
+ return s.getLargeIntValue();
+}
+
+double parseDouble (const String& s)
+{
+ return s.retainCharacters ("0123456789.eE-").getDoubleValue();
+}
+
+String hexString (int v) { return "0x" + String::toHexString (v); }
+String hexString (int64 v) { return "0x" + String::toHexString (v); }
+
+//==============================================================================
+LiveValueBase::LiveValueBase (const char* file, int line)
+ : sourceFile (file), sourceLine (line)
+{
+ name = File (sourceFile).getFileName() + " : " + String (sourceLine);
+}
+
+LiveValueBase::~LiveValueBase()
+{
+}
+
+
+//==============================================================================
+LivePropertyEditorBase::LivePropertyEditorBase (LiveValueBase& v, CodeDocument& d)
+ : value (v), document (d), sourceEditor (document, &tokeniser)
+{
+ setSize (600, 100);
+
+ addAndMakeVisible (&name);
+ addAndMakeVisible (&valueEditor);
+ addAndMakeVisible (&sourceEditor);
+ sourceEditor.setWantsKeyboardFocus (false);
+ sourceEditor.setEnabled (false);
+
+ findOriginalValueInCode();
+ selectOriginalValue();
+
+ name.setFont (13.0f);
+ name.setText (v.name, dontSendNotification);
+ valueEditor.setText (v.getStringValue(), dontSendNotification);
+ valueEditor.addListener (this);
+}
+
+void LivePropertyEditorBase::paint (Graphics& g)
+{
+ g.setColour (Colours::white);
+ g.fillRect (getLocalBounds().removeFromBottom (1));
+}
+
+void LivePropertyEditorBase::resized()
+{
+ Rectangle r (getLocalBounds().reduced (0, 3).withTrimmedBottom (1));
+
+ Rectangle left (r.removeFromLeft (jmax (200, r.getWidth() / 3)));
+
+ name.setBounds (left.removeFromTop (25));
+ valueEditor.setBounds (left.removeFromTop (25));
+ left.removeFromTop (2);
+
+ if (customComp != nullptr)
+ customComp->setBounds (left);
+
+ r.removeFromLeft (4);
+ sourceEditor.setBounds (r);
+}
+
+void LivePropertyEditorBase::textEditorTextChanged (TextEditor&)
+{
+ applyNewValue (valueEditor.getText());
+}
+
+void LivePropertyEditorBase::applyNewValue (const String& s)
+{
+ value.setStringValue (s);
+
+ document.replaceSection (valueStart.getPosition(), valueEnd.getPosition(), value.getCodeValue());
+ document.clearUndoHistory();
+ selectOriginalValue();
+
+ valueEditor.setText (s, dontSendNotification);
+ AllComponentRepainter::getInstance().trigger();
+}
+
+void LivePropertyEditorBase::selectOriginalValue()
+{
+ sourceEditor.selectRegion (valueStart, valueEnd);
+}
+
+void LivePropertyEditorBase::findOriginalValueInCode()
+{
+ CodeDocument::Position pos (document, value.sourceLine, 0);
+ String line (pos.getLineText());
+ String::CharPointerType p (line.getCharPointer());
+
+ p = CharacterFunctions::find (p, CharPointer_ASCII ("JUCE_LIVE_CONSTANT"));
+
+ if (p.isEmpty())
+ {
+ // Not sure how this would happen - some kind of mix-up between source code and line numbers..
+ jassertfalse;
+ return;
+ }
+
+ p += (int) (sizeof ("JUCE_LIVE_CONSTANT") - 1);
+ p = p.findEndOfWhitespace();
+
+ if (! CharacterFunctions::find (p, CharPointer_ASCII ("JUCE_LIVE_CONSTANT")).isEmpty())
+ {
+ // Aargh! You've added two JUCE_LIVE_CONSTANT macros on the same line!
+ // They're identified by their line number, so you must make sure each
+ // one goes on a separate line!
+ jassertfalse;
+ }
+
+ if (p.getAndAdvance() == '(')
+ {
+ String::CharPointerType start (p), end (p);
+
+ int depth = 1;
+
+ while (! end.isEmpty())
+ {
+ const juce_wchar c = end.getAndAdvance();
+
+ if (c == '(') ++depth;
+ if (c == ')') --depth;
+
+ if (depth == 0)
+ {
+ --end;
+ break;
+ }
+ }
+
+ if (end > start)
+ {
+ valueStart = CodeDocument::Position (document, value.sourceLine, (int) (start - line.getCharPointer()));
+ valueEnd = CodeDocument::Position (document, value.sourceLine, (int) (end - line.getCharPointer()));
+
+ valueStart.setPositionMaintained (true);
+ valueEnd.setPositionMaintained (true);
+ }
+ }
+}
+
+//==============================================================================
+class ValueListHolderComponent : public Component
+{
+public:
+ ValueListHolderComponent (ValueList& l) : valueList (l)
+ {
+ setVisible (true);
+ }
+
+ void addItem (int width, LiveValueBase& v, CodeDocument& doc)
+ {
+ addAndMakeVisible (editors.add (v.createPropertyComponent (doc)));
+ layout (width);
+ }
+
+ void layout (int width)
+ {
+ setSize (width, editors.size() * itemHeight);
+ resized();
+ }
+
+ void resized() override
+ {
+ Rectangle r (getLocalBounds());
+
+ for (int i = 0; i < editors.size(); ++i)
+ editors.getUnchecked(i)->setBounds (r.removeFromTop (itemHeight));
+ }
+
+ enum { itemHeight = 120 };
+
+ ValueList& valueList;
+ OwnedArray editors;
+};
+
+//==============================================================================
+class ValueList::EditorWindow : public DocumentWindow,
+ private DeletedAtShutdown
+{
+public:
+ EditorWindow (ValueList& list)
+ : DocumentWindow ("Live Values", Colours::lightgrey, DocumentWindow::closeButton)
+ {
+ setLookAndFeel (&lookAndFeel);
+ setUsingNativeTitleBar (true);
+
+ viewport.setViewedComponent (new ValueListHolderComponent (list), true);
+ viewport.setSize (700, 600);
+ viewport.setScrollBarsShown (true, false);
+
+ setContentNonOwned (&viewport, true);
+ setResizable (true, false);
+ setResizeLimits (500, 400, 10000, 10000);
+ setVisible (true);
+ centreWithSize (getWidth(), getHeight());
+ }
+
+ void closeButtonPressed() override
+ {
+ setVisible (false);
+ }
+
+ void addItem (LiveValueBase& v, CodeDocument& doc)
+ {
+ if (ValueListHolderComponent* l = dynamic_cast (viewport.getViewedComponent()))
+ l->addItem (viewport.getMaximumVisibleWidth(), v, doc);
+ }
+
+ void resized() override
+ {
+ DocumentWindow::resized();
+
+ if (ValueListHolderComponent* l = dynamic_cast (viewport.getViewedComponent()))
+ l->layout (viewport.getMaximumVisibleWidth());
+ }
+
+ Viewport viewport;
+ LookAndFeel_V3 lookAndFeel;
+};
+
+
+struct ColourEditorComp : public Component,
+ private ChangeListener
+{
+ ColourEditorComp (LivePropertyEditorBase& e) : editor (e)
+ {
+ setMouseCursor (MouseCursor::PointingHandCursor);
+ }
+
+ Colour getColour() const
+ {
+ return Colour ((int) parseInt (editor.value.getStringValue()));
+ }
+
+ void paint (Graphics& g) override
+ {
+ g.fillCheckerBoard (getLocalBounds(), 6, 6,
+ Colour (0xffdddddd).overlaidWith (getColour()),
+ Colour (0xffffffff).overlaidWith (getColour()));
+ }
+
+ void mouseDown (const MouseEvent&) override
+ {
+ ColourSelector* colourSelector = new ColourSelector();
+ colourSelector->setName ("Colour");
+ colourSelector->setCurrentColour (getColour());
+ colourSelector->addChangeListener (this);
+ colourSelector->setColour (ColourSelector::backgroundColourId, Colours::transparentBlack);
+ colourSelector->setSize (300, 400);
+
+ CallOutBox::launchAsynchronously (colourSelector, getScreenBounds(), nullptr);
+ }
+
+ void changeListenerCallback (ChangeBroadcaster* source) override
+ {
+ if (ColourSelector* cs = dynamic_cast (source))
+ editor.applyNewValue (getAsString (cs->getCurrentColour()));
+
+ repaint();
+ }
+
+ LivePropertyEditorBase& editor;
+};
+
+Component* createColourEditor (LivePropertyEditorBase& editor)
+{
+ return new ColourEditorComp (editor);
+}
+
+//==============================================================================
+class SliderComp : public Component,
+ private Slider::Listener
+{
+public:
+ SliderComp (LivePropertyEditorBase& e, bool useFloat)
+ : editor (e), isFloat (useFloat)
+ {
+ slider.setTextBoxStyle (Slider::NoTextBox, true, 0, 0);
+ addAndMakeVisible (&slider);
+ updateRange();
+ slider.addListener (this);
+ }
+
+ void updateRange()
+ {
+ double v = isFloat ? parseDouble (editor.value.getStringValue())
+ : (double) parseInt (editor.value.getStringValue());
+
+ double range = isFloat ? 10 : 100;
+
+ slider.setRange (v - range, v + range);
+ slider.setValue (v, dontSendNotification);
+ }
+
+private:
+ LivePropertyEditorBase& editor;
+ Slider slider;
+ bool isFloat;
+
+ void sliderValueChanged (Slider*)
+ {
+ editor.applyNewValue (isFloat ? getAsString ((double) slider.getValue())
+ : getAsString ((int64) slider.getValue()));
+
+ }
+
+ void sliderDragStarted (Slider*) {}
+ void sliderDragEnded (Slider*) { updateRange(); }
+
+ void resized()
+ {
+ slider.setBounds (getLocalBounds().removeFromTop (25));
+ }
+};
+
+
+Component* createIntegerSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, false); }
+Component* createFloatSlider (LivePropertyEditorBase& editor) { return new SliderComp (editor, true); }
+
+//==============================================================================
+ValueList::ValueList()
+{
+}
+
+ValueList& ValueList::getInstance()
+{
+ static ValueList* i = new ValueList();
+ return *i;
+}
+
+void ValueList::addValue (LiveValueBase* v)
+{
+ values.add (v);
+
+ if (editorWindow == nullptr)
+ editorWindow = new EditorWindow (*this);
+
+ editorWindow->addItem (*v, getDocument (v->sourceFile));
+ editorWindow->setVisible (true);
+}
+
+CodeDocument& ValueList::getDocument (const File& file)
+{
+ const int index = documentFiles.indexOf (file.getFullPathName());
+
+ if (index >= 0)
+ return *documents.getUnchecked (index);
+
+ CodeDocument* doc = documents.add (new CodeDocument());
+ documentFiles.add (file);
+ doc->replaceAllContent (file.loadFileAsString());
+ doc->clearUndoHistory();
+ return *doc;
+}
+
+}
+
+#endif
\ No newline at end of file
diff --git a/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h
new file mode 100644
index 0000000000..6865deb7a2
--- /dev/null
+++ b/modules/juce_gui_extra/misc/juce_LiveConstantEditor.h
@@ -0,0 +1,287 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+
+ Permission is granted to use this software under the terms of either:
+ a) the GPL v2 (or any later version)
+ b) the Affero GPL v3
+
+ Details of these licenses can be found at: www.gnu.org/licenses
+
+ JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ ------------------------------------------------------------------------------
+
+ To release a closed-source product which uses JUCE, commercial licenses are
+ available: visit www.juce.com for more information.
+
+ ==============================================================================
+*/
+
+#ifndef JUCE_LIVECONSTANTEDITOR_H_INCLUDED
+#define JUCE_LIVECONSTANTEDITOR_H_INCLUDED
+
+#if JUCE_ENABLE_LIVE_CONSTANT_EDITOR && ! DOXYGEN
+
+//==============================================================================
+/** You can safely ignore all the stuff in this namespace - it's a bunch of boilerplate
+ code used to implement the JUCE_LIVE_CONSTANT functionality.
+*/
+namespace LiveConstantEditor
+{
+ int64 parseInt (String);
+ double parseDouble (const String&);
+ String hexString (int);
+ String hexString (int64);
+
+ template
+ static void setFromString (Type& v, const String& s) { v = static_cast (s); }
+ inline void setFromString (char& v, const String& s) { v = (char) parseInt (s); }
+ inline void setFromString (unsigned char& v, const String& s) { v = (unsigned char) parseInt (s); }
+ inline void setFromString (short& v, const String& s) { v = (short) parseInt (s); }
+ inline void setFromString (unsigned short& v, const String& s) { v = (unsigned short) parseInt (s); }
+ inline void setFromString (int& v, const String& s) { v = (int) parseInt (s); }
+ inline void setFromString (unsigned int& v, const String& s) { v = (unsigned int) parseInt (s); }
+ inline void setFromString (long& v, const String& s) { v = (long) parseInt (s); }
+ inline void setFromString (unsigned long& v, const String& s) { v = (unsigned long) parseInt (s); }
+ inline void setFromString (int64& v, const String& s) { v = (int64) parseInt (s); }
+ inline void setFromString (uint64& v, const String& s) { v = (uint64) parseInt (s); }
+ inline void setFromString (double& v, const String& s) { v = parseDouble (s); }
+ inline void setFromString (float& v, const String& s) { v = (float) parseDouble (s); }
+ inline void setFromString (String& v, const String& s) { v = s; }
+ inline void setFromString (Colour& v, const String& s) { v = Colour ((int) parseInt (s)); }
+
+ template
+ inline String getAsString (const Type& v) { return String (v); }
+ inline String getAsString (char v) { return hexString ((int) v); }
+ inline String getAsString (unsigned char v) { return hexString ((int) v); }
+ inline String getAsString (short v) { return hexString ((int) v); }
+ inline String getAsString (unsigned short v) { return hexString ((int) v); }
+ inline String getAsString (int v) { return hexString ((int) v); }
+ inline String getAsString (unsigned int v) { return hexString ((int) v); }
+ inline String getAsString (int64 v) { return hexString ((int64) v); }
+ inline String getAsString (uint64 v) { return hexString ((int64) v); }
+ inline String getAsString (Colour v) { return hexString ((int) v.getARGB()); }
+
+ template
+ inline String getAsCode (Type& value) { return getAsString (value); }
+ inline String getAsCode (Colour value) { return "Colour (" + hexString ((int) value.getARGB()) + ")"; }
+ inline String getAsCode (const String& v) { return "\"" + v + "\""; }
+ inline String getAsCode (const char* value) { return getAsCode (String (value)); }
+
+ template
+ inline const char* castToCharPointer (const Type&) { return ""; }
+ inline const char* castToCharPointer (const String& s) { return s.toRawUTF8(); }
+
+ struct LivePropertyEditorBase;
+
+ //==============================================================================
+ struct LiveValueBase
+ {
+ LiveValueBase (const char* file, int line);
+ virtual ~LiveValueBase();
+
+ virtual LivePropertyEditorBase* createPropertyComponent (CodeDocument&) = 0;
+ virtual String getStringValue() const = 0;
+ virtual String getCodeValue() const = 0;
+ virtual void setStringValue (const String&) = 0;
+
+ String name, sourceFile;
+ int sourceLine;
+
+ JUCE_DECLARE_NON_COPYABLE (LiveValueBase)
+ };
+
+ //==============================================================================
+ struct LivePropertyEditorBase : public Component,
+ private TextEditor::Listener
+ {
+ LivePropertyEditorBase (LiveValueBase&, CodeDocument&);
+
+ void paint (Graphics&) override;
+ void resized() override;
+ void textEditorTextChanged (TextEditor&) override;
+
+ void applyNewValue (const String&);
+ void selectOriginalValue();
+ void findOriginalValueInCode();
+
+ LiveValueBase& value;
+ Label name;
+ TextEditor valueEditor;
+ CodeDocument& document;
+ CPlusPlusCodeTokeniser tokeniser;
+ CodeEditorComponent sourceEditor;
+ CodeDocument::Position valueStart, valueEnd;
+ ScopedPointer customComp;
+
+ JUCE_DECLARE_NON_COPYABLE (LivePropertyEditorBase)
+ };
+
+ //==============================================================================
+ Component* createColourEditor (LivePropertyEditorBase&);
+ Component* createIntegerSlider (LivePropertyEditorBase&);
+ Component* createFloatSlider (LivePropertyEditorBase&);
+
+ template struct CustomEditor { static Component* create (LivePropertyEditorBase&) { return nullptr; } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createIntegerSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createFloatSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createFloatSlider (e); } };
+ template<> struct CustomEditor { static Component* create (LivePropertyEditorBase& e) { return createColourEditor (e); } };
+
+ template
+ struct LivePropertyEditor : public LivePropertyEditorBase
+ {
+ template
+ LivePropertyEditor (ValueType& v, CodeDocument& d) : LivePropertyEditorBase (v, d)
+ {
+ addAndMakeVisible (customComp = CustomEditor::create (*this));
+ }
+ };
+
+ //==============================================================================
+ template
+ struct LiveValue : public LiveValueBase
+ {
+ LiveValue (const char* file, int line, const Type& initialValue)
+ : LiveValueBase (file, line), value (initialValue)
+ {}
+
+ operator Type() const noexcept { return value; }
+ operator const char*() const { return castToCharPointer (value); }
+
+ LivePropertyEditorBase* createPropertyComponent (CodeDocument& doc) override
+ {
+ return new LivePropertyEditor (*this, doc);
+ }
+
+ String getStringValue() const override { return getAsString (value); }
+ String getCodeValue() const override { return getAsCode (value); }
+ void setStringValue (const String& s) override { setFromString (value, s); }
+
+ Type value;
+
+ JUCE_DECLARE_NON_COPYABLE (LiveValue)
+ };
+
+ //==============================================================================
+ class ValueList : private DeletedAtShutdown
+ {
+ public:
+ ValueList();
+ static ValueList& getInstance();
+
+ template
+ LiveValue& getValue (const char* file, int line, const Type& initialValue)
+ {
+ const ScopedLock sl (lock);
+ typedef LiveValue ValueType;
+
+ for (int i = 0; i < values.size(); ++i)
+ {
+ LiveValueBase* v = values.getUnchecked(i);
+
+ if (v->sourceLine == line && v->sourceFile == file)
+ if (ValueType* vt = dynamic_cast (v))
+ return *vt;
+ }
+
+ ValueType* v = new ValueType (file, line, initialValue);
+ addValue (v);
+ return *v;
+ }
+
+ private:
+ OwnedArray values;
+ OwnedArray documents;
+ Array documentFiles;
+ class EditorWindow;
+ Component::SafePointer editorWindow;
+ CriticalSection lock;
+
+ CodeDocument& getDocument (const File&);
+ void addValue (LiveValueBase*);
+ };
+
+ template
+ inline LiveValue& getValue (const char* file, int line, const Type& initialValue)
+ {
+ return ValueList::getInstance().getValue (file, line, initialValue);
+ }
+
+ inline LiveValue& getValue (const char* file, int line, const char* initialValue)
+ {
+ return getValue (file, line, String (initialValue));
+ }
+}
+
+#endif
+
+//==============================================================================
+#if JUCE_ENABLE_LIVE_CONSTANT_EDITOR || DOXYGEN
+ /**
+ This macro wraps a primitive constant value in some cunning boilerplate code that allows
+ its value to be interactively tweaked in a popup window while your application is running.
+
+ In a release build, this macro disappears and is replaced by only the constant that it
+ wraps, but if JUCE_ENABLE_LIVE_CONSTANT_EDITOR is enabled, it injects a class wrapper
+ that automatically pops-up a window containing an editor that allows the value to be
+ tweaked at run-time. The editor window will also force all visible components to be
+ resized and repainted whenever a value is changed, so that if you use this to wrap
+ a colour or layout parameter, you'll be able to immediately see the effects of changing it.
+
+ The editor will also load the original source-file that contains each JUCE_LIVE_CONSTANT
+ macro, and will display a preview of the modified source code as you adjust the values.
+
+ Things to note:
+
+ - Only one of these per line! The __FILE__ and __LINE__ macros are used to identify
+ the value, so things will get confused if you have more than one per line
+ - Obviously because it needs to load the source code based on the __FILE__ macro,
+ it'll only work if the source files are stored locally in the same location as they
+ were when you compiled the program.
+ - It's only designed to cope with simple types: primitives, string literals, and
+ the Colour class, so if you try using it for other classes or complex expressions,
+ good luck!
+ - The editor window will get popped up whenever a new value is used for the first
+ time. You can close the window, but there's no way to get it back without restarting
+ the app!
+
+ e.g. in this example the colours, font size, and text used in the paint method can
+ all be adjusted live:
+ @code
+ void MyComp::paint (Graphics& g) override
+ {
+ g.fillAll (JUCE_LIVE_CONSTANT (Colour (0xffddddff)));
+
+ Colour fontColour = JUCE_LIVE_CONSTANT (Colour (0xff005500));
+ float fontSize = JUCE_LIVE_CONSTANT (16.0f);
+
+ g.setColour (fontColour);
+ g.setFont (fontSize);
+
+ g.drawFittedText (JUCE_LIVE_CONSTANT ("Hello world!"),
+ getLocalBounds(), Justification::centred, 2);
+ }
+ @endcode
+ */
+ #define JUCE_LIVE_CONSTANT(initialValue) \
+ (LiveConstantEditor::getValue (__FILE__, __LINE__ - 1, initialValue))
+#else
+ #define JUCE_LIVE_CONSTANT(initialValue) \
+ (initialValue)
+#endif
+
+
+#endif // JUCE_LIVECONSTANTEDITOR_H_INCLUDED