diff --git a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
index f230bb1940..3ebce581a0 100644
--- a/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
+++ b/extras/Introjucer/Builds/CodeBlocks/The Introjucer.cbp
@@ -537,6 +537,10 @@
+
+
+
+
@@ -546,6 +550,14 @@
+
+
+
+
+
+
+
+
diff --git a/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj b/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
index 48e162795c..a5c7535522 100644
--- a/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
+++ b/extras/Introjucer/Builds/MacOSX/The Introjucer.xcodeproj/project.pbxproj
@@ -265,6 +265,7 @@
352DA3794CAAE2400AE8F2E0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_data_structures.h"; path = "../../../../modules/juce_data_structures/juce_data_structures.h"; sourceTree = "SOURCE_ROOT"; };
353E622BE257074B5589199D = {isa = PBXFileReference; lastKnownFileType = image.png; name = projectIconCodeblocks.png; path = ../../Source/BinaryData/projectIconCodeblocks.png; sourceTree = "SOURCE_ROOT"; };
358DA8CCDC8FA5B0D62D6CA3 = {isa = PBXFileReference; lastKnownFileType = file.svg; name = "wizard_Openfile.svg"; path = "../../Source/BinaryData/wizard_Openfile.svg"; sourceTree = "SOURCE_ROOT"; };
+ 35A36102EAD2D2620EE99E7E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FilePathPropertyComponent.h"; path = "../../Source/Utility/jucer_FilePathPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; };
35AF9D5F0603CF6CE2D355A1 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_RelativeCoordinatePositioner.cpp"; path = "../../../../modules/juce_gui_basics/positioning/juce_RelativeCoordinatePositioner.cpp"; sourceTree = "SOURCE_ROOT"; };
35BF11530EF0D771FD94ABDC = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_TextDragAndDropTarget.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_TextDragAndDropTarget.h"; sourceTree = "SOURCE_ROOT"; };
35CB48D497F35BF3F6998F5D = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectExporter.h"; path = "../../Source/Project Saving/jucer_ProjectExporter.h"; sourceTree = "SOURCE_ROOT"; };
@@ -763,6 +764,7 @@
C5D5D2FFB030BD43160167EB = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryIterator.cpp"; path = "../../../../modules/juce_core/files/juce_DirectoryIterator.cpp"; sourceTree = "SOURCE_ROOT"; };
C5FCECA838D4D12D03929139 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_FileBrowserComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileBrowserComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
C61E82D93918A611FAFD9E9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ComponentBoundsConstrainer.h"; path = "../../../../modules/juce_gui_basics/layout/juce_ComponentBoundsConstrainer.h"; sourceTree = "SOURCE_ROOT"; };
+ C68355AA4D62939EECAD469E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; };
C6861DB44A31CE7A3DEFA083 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileInputStream.h"; path = "../../../../modules/juce_core/files/juce_FileInputStream.h"; sourceTree = "SOURCE_ROOT"; };
C6E46DBD249D9426C95E2235 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChangeBroadcaster.cpp"; path = "../../../../modules/juce_events/broadcasters/juce_ChangeBroadcaster.cpp"; sourceTree = "SOURCE_ROOT"; };
C717D2384896547D1CD993F6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_DialogWindow.h"; path = "../../../../modules/juce_gui_basics/windows/juce_DialogWindow.h"; sourceTree = "SOURCE_ROOT"; };
@@ -788,6 +790,7 @@
CDCAF0EC777DA2884AEB2B59 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Label.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_Label.cpp"; sourceTree = "SOURCE_ROOT"; };
CDDF5BDC75277F7B83A38885 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PropertySet.cpp"; path = "../../../../modules/juce_core/containers/juce_PropertySet.cpp"; sourceTree = "SOURCE_ROOT"; };
CDF8F65F9079B2C14A740F0F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ImageButton.h"; path = "../../../../modules/juce_gui_basics/buttons/juce_ImageButton.h"; sourceTree = "SOURCE_ROOT"; };
+ CE1DFE4E3908943656E180AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; };
CF0615A1AF1A514A60322B50 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MouseCursor.h"; path = "../../../../modules/juce_gui_basics/mouse/juce_MouseCursor.h"; sourceTree = "SOURCE_ROOT"; };
CF21D9DB3AEC0A4DCAB36A99 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_Icons.cpp"; path = "../../Source/Utility/jucer_Icons.cpp"; sourceTree = "SOURCE_ROOT"; };
CF6C8BD0DA3D8CD4E99EBADA = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
@@ -802,7 +805,7 @@
D2F1CF252F7EC62B35A21CB6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DropShadowEffect.cpp"; path = "../../../../modules/juce_graphics/effects/juce_DropShadowEffect.cpp"; sourceTree = "SOURCE_ROOT"; };
D2F80DA0946A5EE01FC016CA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CharPointer_UTF32.h"; path = "../../../../modules/juce_core/text/juce_CharPointer_UTF32.h"; sourceTree = "SOURCE_ROOT"; };
D374DC78AAC02504576AA9B3 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_GroupComponentHandler.h"; path = "../../Source/ComponentEditor/components/jucer_GroupComponentHandler.h"; sourceTree = "SOURCE_ROOT"; };
- D376B9B54EC944E766AFEC45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; };
+ D3E139185095C486DD3D61F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationTool.h"; path = "../../Source/Utility/jucer_TranslationTool.h"; sourceTree = "SOURCE_ROOT"; };
D4444EC6342A2A7BC4F7BC46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ComponentTextProperty.h"; path = "../../Source/ComponentEditor/properties/jucer_ComponentTextProperty.h"; sourceTree = "SOURCE_ROOT"; };
D4697A0232AECE5DAC5E332E = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ChoicePropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ChoicePropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
D4E56676E2EF83404EDCBA8C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_TextEditor.cpp"; path = "../../../../modules/juce_gui_basics/widgets/juce_TextEditor.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -815,6 +818,7 @@
D6C91E2BF537F75A80F5C1DB = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ListBox.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ListBox.h"; sourceTree = "SOURCE_ROOT"; };
D75EAC16FAECCC51E3669193 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ApplicationCommandInfo.h"; path = "../../../../modules/juce_gui_basics/commands/juce_ApplicationCommandInfo.h"; sourceTree = "SOURCE_ROOT"; };
D782DA091AD3ECE158FC6A5F = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ButtonPropertyComponent.h"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; };
+ D800DE818BEDBF4579D15B1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; };
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"; };
@@ -836,18 +840,16 @@
E4BD4C43370651B49F75855B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_MainTemplate_SimpleWindow.cpp"; path = "../../Source/BinaryData/jucer_MainTemplate_SimpleWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
E570E57CC1FCEF78B54A7084 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileOutputStream.h"; path = "../../../../modules/juce_core/files/juce_FileOutputStream.h"; sourceTree = "SOURCE_ROOT"; };
E5D6C36496F5BC84D7213BE8 = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
+ E62D9BA6E92FE7BB6EF65699 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; };
E65A820D34BF39478B7C5925 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_DocumentEditorComponent.h"; path = "../../Source/Application/jucer_DocumentEditorComponent.h"; sourceTree = "SOURCE_ROOT"; };
E6F5CEC32EDC917B054467EF = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ReadWriteLock.cpp"; path = "../../../../modules/juce_core/threads/juce_ReadWriteLock.cpp"; sourceTree = "SOURCE_ROOT"; };
E720FBCD836FF3AA466C31B6 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_HighResolutionTimer.cpp"; path = "../../../../modules/juce_core/threads/juce_HighResolutionTimer.cpp"; sourceTree = "SOURCE_ROOT"; };
E96597BBC6A98255B51B94DC = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
25F52316D256B4534BED16D1 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Introjucer.app; sourceTree = "BUILT_PRODUCTS_DIR"; };
- C68355AA4D62939EECAD469E = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Random.h"; path = "../../../../modules/juce_core/maths/juce_Random.h"; sourceTree = "SOURCE_ROOT"; };
- CE1DFE4E3908943656E180AD = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_UnitTest.cpp"; path = "../../../../modules/juce_core/unit_tests/juce_UnitTest.cpp"; sourceTree = "SOURCE_ROOT"; };
D253F74B7F5734984E568CA7 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_linux_Files.cpp"; path = "../../../../modules/juce_core/native/juce_linux_Files.cpp"; sourceTree = "SOURCE_ROOT"; };
- D3E139185095C486DD3D61F2 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_TranslationTool.h"; path = "../../Source/Utility/jucer_TranslationTool.h"; sourceTree = "SOURCE_ROOT"; };
+ D376B9B54EC944E766AFEC45 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_PopupMenu.cpp"; path = "../../../../modules/juce_gui_basics/menus/juce_PopupMenu.cpp"; sourceTree = "SOURCE_ROOT"; };
D780ED33573AED5AD383A036 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CaretComponent.h"; path = "../../../../modules/juce_gui_basics/keyboard/juce_CaretComponent.h"; sourceTree = "SOURCE_ROOT"; };
D7A7F1AA9F313B0CCAAA73A0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MathsFunctions.h"; path = "../../../../modules/juce_core/maths/juce_MathsFunctions.h"; sourceTree = "SOURCE_ROOT"; };
- D800DE818BEDBF4579D15B1D = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = "juce_mac_AppleRemote.mm"; path = "../../../../modules/juce_gui_extra/native/juce_mac_AppleRemote.mm"; sourceTree = "SOURCE_ROOT"; };
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"; };
@@ -863,11 +865,13 @@
DE5F3C9EF6BFFDE73AF9E7FC = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_DirectoryContentsDisplayComponent.cpp"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_DirectoryContentsDisplayComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
DEF579B1433EB8DEE7AB50F8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Drawable.cpp"; path = "../../../../modules/juce_gui_basics/drawables/juce_Drawable.cpp"; sourceTree = "SOURCE_ROOT"; };
DF725A596B7BCD7520CC0A9F = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "jucer_ResourceEditorPanel.cpp"; path = "../../Source/ComponentEditor/ui/jucer_ResourceEditorPanel.cpp"; sourceTree = "SOURCE_ROOT"; };
+ DF78EF6242D82F912534A277 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ColourPropertyComponent.h"; path = "../../Source/Utility/jucer_ColourPropertyComponent.h"; sourceTree = "SOURCE_ROOT"; };
DF7BB5B6B394EDEEF5F5B4B8 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_CallbackMessage.h"; path = "../../../../modules/juce_events/messages/juce_CallbackMessage.h"; sourceTree = "SOURCE_ROOT"; };
E07C56267CBB46FC44EF2026 = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_Image.cpp"; path = "../../../../modules/juce_graphics/images/juce_Image.cpp"; sourceTree = "SOURCE_ROOT"; };
E1C16C872E34BCB144B469F9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_EdgeTable.h"; path = "../../../../modules/juce_graphics/geometry/juce_EdgeTable.h"; sourceTree = "SOURCE_ROOT"; };
E27F0860F27023BAA9798B46 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_Rectangle.h"; path = "../../../../modules/juce_graphics/geometry/juce_Rectangle.h"; sourceTree = "SOURCE_ROOT"; };
E284B565DBD647DC0830D23B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ButtonPropertyComponent.cpp"; path = "../../../../modules/juce_gui_basics/properties/juce_ButtonPropertyComponent.cpp"; sourceTree = "SOURCE_ROOT"; };
+ E382C78A1D837DD98916E86A = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_FloatingToolWindow.h"; path = "../../Source/Utility/jucer_FloatingToolWindow.h"; sourceTree = "SOURCE_ROOT"; };
E3869AC657E984565F1718AA = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ConnectedChildProcess.h"; path = "../../../../modules/juce_events/interprocess/juce_ConnectedChildProcess.h"; sourceTree = "SOURCE_ROOT"; };
E3FF16862AA1B2F943DC616C = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ImageCache.cpp"; path = "../../../../modules/juce_graphics/images/juce_ImageCache.cpp"; sourceTree = "SOURCE_ROOT"; };
E446FFE889CD490FDE3F0F2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = "juce_ThreadWithProgressWindow.cpp"; path = "../../../../modules/juce_gui_basics/windows/juce_ThreadWithProgressWindow.cpp"; sourceTree = "SOURCE_ROOT"; };
@@ -876,7 +880,6 @@
E530742870F07704E9616358 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_ToolbarItemComponent.h"; path = "../../../../modules/juce_gui_basics/widgets/juce_ToolbarItemComponent.h"; sourceTree = "SOURCE_ROOT"; };
E54D0994D31E20A0A05EBA2B = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_SystemTrayIconComponent.h"; path = "../../../../modules/juce_gui_extra/misc/juce_SystemTrayIconComponent.h"; sourceTree = "SOURCE_ROOT"; };
E60E28D1B7491047DEA236AE = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "jucer_ProjectContentComponent.h"; path = "../../Source/Project/jucer_ProjectContentComponent.h"; sourceTree = "SOURCE_ROOT"; };
- E62D9BA6E92FE7BB6EF65699 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_JSON.h"; path = "../../../../modules/juce_core/javascript/juce_JSON.h"; sourceTree = "SOURCE_ROOT"; };
E63F54CF8D5D922A319C6962 = {isa = PBXFileReference; lastKnownFileType = image.png; name = projectIconXcodeIOS.png; path = ../../Source/BinaryData/projectIconXcodeIOS.png; sourceTree = "SOURCE_ROOT"; };
E642193A9990C48CFB6479A9 = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_FileListComponent.h"; path = "../../../../modules/juce_gui_basics/filebrowser/juce_FileListComponent.h"; sourceTree = "SOURCE_ROOT"; };
E654E3A3CD45A888C5F773DF = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "juce_MenuBarModel.h"; path = "../../../../modules/juce_gui_basics/menus/juce_MenuBarModel.h"; sourceTree = "SOURCE_ROOT"; };
@@ -1115,9 +1118,12 @@
D93DED1F5F1B0E49E10A6760 = {isa = PBXGroup; children = (
9B9CAD20E1243B4351B4C8D8,
914ADDB50ED7365F08BA91F9,
+ DF78EF6242D82F912534A277,
188D03A4247F4BC0539F5C49,
1729AEDC34001C31B8CC357C,
553725A0E3A391651ED1731E,
+ 35A36102EAD2D2620EE99E7E,
+ E382C78A1D837DD98916E86A,
CF21D9DB3AEC0A4DCAB36A99,
515FF6E74826E3E3F7273621,
47DD50A5A9091F9900E0EAD9,
diff --git a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
index e9b4f2f003..701855c341 100644
--- a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj
@@ -1165,8 +1165,11 @@
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
index c83b6885f5..be436283df 100644
--- a/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2010/The Introjucer.vcxproj.filters
@@ -1662,12 +1662,21 @@
The Introjucer\Utility
+
+ The Introjucer\Utility
+
The Introjucer\Utility
The Introjucer\Utility
+
+ The Introjucer\Utility
+
+
+ The Introjucer\Utility
+
The Introjucer\Utility
diff --git a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
index b8351e949a..d90d5b4336 100644
--- a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj
@@ -1171,8 +1171,11 @@
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
index c83b6885f5..be436283df 100644
--- a/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2012/The Introjucer.vcxproj.filters
@@ -1662,12 +1662,21 @@
The Introjucer\Utility
+
+ The Introjucer\Utility
+
The Introjucer\Utility
The Introjucer\Utility
+
+ The Introjucer\Utility
+
+
+ The Introjucer\Utility
+
The Introjucer\Utility
diff --git a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
index c3d7d7ea61..a5acf011dd 100644
--- a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj
@@ -1171,8 +1171,11 @@
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
index 8706c1de20..e873d45abe 100644
--- a/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2013/The Introjucer.vcxproj.filters
@@ -1662,12 +1662,21 @@
The Introjucer\Utility
+
+ The Introjucer\Utility
+
The Introjucer\Utility
The Introjucer\Utility
+
+ The Introjucer\Utility
+
+
+ The Introjucer\Utility
+
The Introjucer\Utility
diff --git a/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj b/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj
index 08a3aa2f6a..c65268ec44 100644
--- a/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj
+++ b/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj
@@ -1171,8 +1171,11 @@
+
+
+
diff --git a/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj.filters b/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj.filters
index 834b34d4f5..1475663a35 100644
--- a/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj.filters
+++ b/extras/Introjucer/Builds/VisualStudio2015/The Introjucer.vcxproj.filters
@@ -1662,12 +1662,21 @@
The Introjucer\Utility
+
+ The Introjucer\Utility
+
The Introjucer\Utility
The Introjucer\Utility
+
+ The Introjucer\Utility
+
+
+ The Introjucer\Utility
+
The Introjucer\Utility
diff --git a/extras/Introjucer/Introjucer.jucer b/extras/Introjucer/Introjucer.jucer
index 6fb9589d2b..66e07ebe70 100644
--- a/extras/Introjucer/Introjucer.jucer
+++ b/extras/Introjucer/Introjucer.jucer
@@ -433,12 +433,18 @@
file="Source/Utility/jucer_CodeHelpers.cpp"/>
+
+
+
& ownerPointer)
{
if (ownerPointer != nullptr)
- {
ownerPointer->toFront (true);
- }
else
- {
new FloatingToolWindow ("Global Preferences",
"globalPreferencesEditorPos",
new GlobalPreferencesComponent,
ownerPointer,
500, 500, 500, 500, 500, 500);
- }
}
//==============================================================================
diff --git a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp
index 66177cdd4b..da0e186ccb 100644
--- a/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp
+++ b/extras/Introjucer/Source/Project/jucer_ProjectContentComponent.cpp
@@ -27,6 +27,7 @@
#include "../Application/jucer_MainWindow.h"
#include "../Application/jucer_Application.h"
#include "../Code Editor/jucer_SourceCodeEditor.h"
+#include "../Utility/jucer_FilePathPropertyComponent.h"
#include "jucer_TreeItemTypes.h"
diff --git a/extras/Introjucer/Source/Utility/jucer_ColourPropertyComponent.h b/extras/Introjucer/Source/Utility/jucer_ColourPropertyComponent.h
new file mode 100644
index 0000000000..7940c5f8a6
--- /dev/null
+++ b/extras/Introjucer/Source/Utility/jucer_ColourPropertyComponent.h
@@ -0,0 +1,227 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2015 - ROLI 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 JUCER_COLOURPROPERTYCOMPONENT_H_INCLUDED
+#define JUCER_COLOURPROPERTYCOMPONENT_H_INCLUDED
+
+
+struct ColourPropertyComponent : public PropertyComponent
+{
+ ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
+ Colour defaultColour, bool canResetToDefault)
+ : PropertyComponent (name),
+ colourEditor (undoManager, colour, defaultColour, canResetToDefault)
+ {
+ addAndMakeVisible (colourEditor);
+ }
+
+ void resized() override
+ {
+ colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
+ }
+
+ void refresh() override {}
+
+private:
+ /**
+ A component that shows a colour swatch with hex ARGB value, and which pops up
+ a colour selector when you click it.
+ */
+ struct ColourEditorComponent : public Component,
+ public Value::Listener
+ {
+ ColourEditorComponent (UndoManager* um, const Value& colour,
+ Colour defaultCol, const bool canReset)
+ : undoManager (um), colourValue (colour), defaultColour (defaultCol),
+ canResetToDefault (canReset)
+ {
+ colourValue.addListener (this);
+ }
+
+ void paint (Graphics& g) override
+ {
+ const Colour colour (getColour());
+
+ g.fillAll (Colours::grey);
+ g.fillCheckerBoard (getLocalBounds().reduced (2),
+ 10, 10,
+ Colour (0xffdddddd).overlaidWith (colour),
+ Colour (0xffffffff).overlaidWith (colour));
+
+ g.setColour (Colours::white.overlaidWith (colour).contrasting());
+ g.setFont (Font (getHeight() * 0.6f, Font::bold));
+ g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
+ Justification::centred, 1);
+ }
+
+ Colour getColour() const
+ {
+ if (colourValue.toString().isEmpty())
+ return defaultColour;
+
+ return Colour::fromString (colourValue.toString());
+ }
+
+ void setColour (Colour newColour)
+ {
+ if (getColour() != newColour)
+ {
+ if (newColour == defaultColour && canResetToDefault)
+ colourValue = var::null;
+ else
+ colourValue = newColour.toDisplayString (true);
+ }
+ }
+
+ void resetToDefault()
+ {
+ setColour (defaultColour);
+ }
+
+ void refresh()
+ {
+ const Colour col (getColour());
+
+ if (col != lastColour)
+ {
+ lastColour = col;
+ repaint();
+ }
+ }
+
+ void mouseDown (const MouseEvent&) override
+ {
+ if (undoManager != nullptr)
+ undoManager->beginNewTransaction();
+
+ CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue,
+ defaultColour,
+ canResetToDefault),
+ getScreenBounds(), nullptr);
+ }
+
+ void valueChanged (Value&) override
+ {
+ refresh();
+ }
+
+ UndoManager* undoManager;
+ Value colourValue;
+ Colour lastColour;
+ const Colour defaultColour;
+ const bool canResetToDefault;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
+ };
+
+ //==============================================================================
+ struct PopupColourSelector : public Component,
+ public ChangeListener,
+ public Value::Listener,
+ public ButtonListener
+ {
+ PopupColourSelector (const Value& colour,
+ Colour defaultCol,
+ const bool canResetToDefault)
+ : defaultButton ("Reset to Default"),
+ colourValue (colour),
+ defaultColour (defaultCol)
+ {
+ addAndMakeVisible (selector);
+ selector.setName ("Colour");
+ selector.setCurrentColour (getColour());
+ selector.addChangeListener (this);
+
+ if (canResetToDefault)
+ {
+ addAndMakeVisible (defaultButton);
+ defaultButton.addListener (this);
+ }
+
+ colourValue.addListener (this);
+ setSize (300, 400);
+ }
+
+ void resized() override
+ {
+ if (defaultButton.isVisible())
+ {
+ selector.setBounds (0, 0, getWidth(), getHeight() - 30);
+ defaultButton.changeWidthToFitText (22);
+ defaultButton.setTopLeftPosition (10, getHeight() - 26);
+ }
+ else
+ {
+ selector.setBounds (getLocalBounds());
+ }
+ }
+
+ Colour getColour() const
+ {
+ if (colourValue.toString().isEmpty())
+ return defaultColour;
+
+ return Colour::fromString (colourValue.toString());
+ }
+
+ void setColour (Colour newColour)
+ {
+ if (getColour() != newColour)
+ {
+ if (newColour == defaultColour && defaultButton.isVisible())
+ colourValue = var();
+ else
+ colourValue = newColour.toDisplayString (true);
+ }
+ }
+
+ void buttonClicked (Button*) override
+ {
+ setColour (defaultColour);
+ selector.setCurrentColour (defaultColour);
+ }
+
+ void changeListenerCallback (ChangeBroadcaster*) override
+ {
+ if (selector.getCurrentColour() != getColour())
+ setColour (selector.getCurrentColour());
+ }
+
+ void valueChanged (Value&) override
+ {
+ selector.setCurrentColour (getColour());
+ }
+
+ private:
+ StoredSettings::ColourSelectorWithSwatches selector;
+ TextButton defaultButton;
+ Value colourValue;
+ Colour defaultColour;
+ };
+
+ ColourEditorComponent colourEditor;
+};
+
+
+#endif // JUCER_COLOURPROPERTYCOMPONENT_H_INCLUDED
diff --git a/extras/Introjucer/Source/Utility/jucer_FilePathPropertyComponent.h b/extras/Introjucer/Source/Utility/jucer_FilePathPropertyComponent.h
new file mode 100644
index 0000000000..b6e966e167
--- /dev/null
+++ b/extras/Introjucer/Source/Utility/jucer_FilePathPropertyComponent.h
@@ -0,0 +1,145 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2015 - ROLI 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 JUCER_FILEPATHPROPERTYCOMPONENT_H_INCLUDED
+#define JUCER_FILEPATHPROPERTYCOMPONENT_H_INCLUDED
+
+
+class FilePathPropertyComponent : public PropertyComponent
+{
+public:
+ /** A Property Component for selecting files or folders.
+
+ The user may drag files over the property box, enter the path
+ manually and/or click the '...' button to open a file selection
+ dialog box
+ */
+ FilePathPropertyComponent (Value valueToControl,
+ const String& propertyDescription,
+ bool isDirectory,
+ const String& wildcards = "*",
+ const File& rootToUseForRelativePaths = File::nonexistent)
+ : PropertyComponent (propertyDescription),
+ innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths)
+ {
+ addAndMakeVisible (innerComp);
+ }
+
+ void refresh() override {} // N/A
+
+private:
+ struct InnerComponent : public Component,
+ public FileDragAndDropTarget,
+ private Button::Listener
+ {
+ InnerComponent (Value v, bool isDir, const String& wc, const File& rt)
+ : value (v),
+ isDirectory (isDir),
+ highlightForDragAndDrop (false),
+ wildcards (wc),
+ root (rt),
+ button ("...")
+ {
+ addAndMakeVisible (textbox);
+ textbox.getTextValue().referTo (value);
+
+ addAndMakeVisible (button);
+ button.addListener (this);
+ }
+
+ void paintOverChildren (Graphics& g) override
+ {
+ if (highlightForDragAndDrop)
+ {
+ g.setColour (Colours::green.withAlpha (0.1f));
+ g.fillRect (getLocalBounds());
+ }
+ }
+
+ void resized() override
+ {
+ juce::Rectangle r (getLocalBounds());
+
+ button.setBounds (r.removeFromRight (24));
+ textbox.setBounds (r);
+ }
+
+ bool isInterestedInFileDrag (const StringArray&) override { return true; }
+ void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
+ void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
+
+ void filesDropped (const StringArray& files, int, int) override
+ {
+ const File firstFile (files[0]);
+
+ if (isDirectory)
+ setTo (firstFile.isDirectory() ? firstFile
+ : firstFile.getParentDirectory());
+ else
+ setTo (firstFile);
+ }
+
+ void buttonClicked (Button*) override
+ {
+ const File currentFile (root.getChildFile (value.toString()));
+
+ if (isDirectory)
+ {
+ FileChooser chooser ("Select directory", currentFile);
+
+ if (chooser.browseForDirectory())
+ setTo (chooser.getResult());
+ }
+ else
+ {
+ FileChooser chooser ("Select file", currentFile, wildcards);
+
+ if (chooser.browseForFileToOpen())
+ setTo (chooser.getResult());
+ }
+ }
+
+ void setTo (const File& f)
+ {
+ value = (root == File::nonexistent) ? f.getFullPathName()
+ : f.getRelativePathFrom (root);
+ }
+
+ Value value;
+ bool isDirectory, highlightForDragAndDrop;
+ String wildcards;
+ File root;
+ TextEditor textbox;
+ TextButton button;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent)
+ };
+
+ InnerComponent innerComp; // Used so that the PropertyComponent auto first-child positioning works
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
+};
+
+
+#endif // JUCER_FILEPATHPROPERTYCOMPONENT_H_INCLUDED
diff --git a/extras/Introjucer/Source/Utility/jucer_FloatingToolWindow.h b/extras/Introjucer/Source/Utility/jucer_FloatingToolWindow.h
new file mode 100644
index 0000000000..0d06efdb2e
--- /dev/null
+++ b/extras/Introjucer/Source/Utility/jucer_FloatingToolWindow.h
@@ -0,0 +1,83 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2015 - ROLI 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 JUCER_FLOATINGTOOLWINDOW_H_INCLUDED
+#define JUCER_FLOATINGTOOLWINDOW_H_INCLUDED
+
+
+//==============================================================================
+struct FloatingToolWindow : public DialogWindow
+{
+ FloatingToolWindow (const String& title,
+ const String& windowPosPropertyName,
+ Component* content,
+ ScopedPointer& ownerPointer,
+ int defaultW, int defaultH,
+ int minW, int minH,
+ int maxW, int maxH)
+ : DialogWindow (title, Colours::darkgrey, true, true),
+ windowPosProperty (windowPosPropertyName),
+ owner (ownerPointer)
+ {
+ setUsingNativeTitleBar (true);
+ setResizable (true, true);
+ setResizeLimits (minW, minH, maxW, maxH);
+ setContentOwned (content, false);
+
+ const String windowState (getGlobalProperties().getValue (windowPosProperty));
+
+ if (windowState.isNotEmpty())
+ restoreWindowStateFromString (windowState);
+ else
+ centreAroundComponent (Component::getCurrentlyFocusedComponent(), defaultW, defaultH);
+
+ setVisible (true);
+ owner = this;
+ }
+
+ ~FloatingToolWindow()
+ {
+ getGlobalProperties().setValue (windowPosProperty, getWindowStateAsString());
+ }
+
+ void closeButtonPressed() override
+ {
+ owner = nullptr;
+ }
+
+ bool escapeKeyPressed() override
+ {
+ closeButtonPressed();
+ return true;
+ }
+
+private:
+ String windowPosProperty;
+ ScopedPointer& owner;
+
+ JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FloatingToolWindow)
+};
+
+
+#endif // JUCER_FLOATINGTOOLWINDOW_H_INCLUDED
diff --git a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp
index 6434855bca..f722a20bb4 100644
--- a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp
+++ b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.cpp
@@ -275,4 +275,3 @@ bool fileNeedsCppSyntaxHighlighting (const File& file)
return CharPointer_UTF8::isValidString (fileStart, sizeof (fileStart))
&& String (fileStart).trimStart().startsWith ("// -*- C++ -*-");
}
-
diff --git a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h
index 65bdaf3931..22ce43f284 100644
--- a/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h
+++ b/extras/Introjucer/Source/Utility/jucer_MiscUtilities.h
@@ -22,8 +22,6 @@
==============================================================================
*/
-//==============================================================================
-
#ifndef JUCER_MISCUTILITIES_H_INCLUDED
#define JUCER_MISCUTILITIES_H_INCLUDED
@@ -41,6 +39,7 @@ StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const Stri
String createGCCPreprocessorFlags (const StringPairArray& defs);
String replacePreprocessorDefs (const StringPairArray& definitions, String sourceString);
+StringArray getCleanedStringArray (StringArray);
StringArray getSearchPathsFromString (const String& searchPath);
StringArray getCommaOrWhitespaceSeparatedItems (const String&);
@@ -57,16 +56,9 @@ int indexOfLineStartingWith (const StringArray& lines, const String& text, int s
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true);
-bool cancelAnyModalComponents();
-
-StringArray getCleanedStringArray (StringArray);
-
//==============================================================================
-class PropertyListBuilder
+struct PropertyListBuilder
{
-public:
- PropertyListBuilder() {}
-
void add (PropertyComponent* propertyComp)
{
components.add (propertyComp);
@@ -90,10 +82,7 @@ public:
components.getUnchecked(j)->setPreferredHeight (height);
}
- Array components;
-
-private:
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PropertyListBuilder)
+ Array components;
};
//==============================================================================
@@ -116,377 +105,5 @@ protected:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSourceFilter)
};
-//==============================================================================
-class FloatingToolWindow : public DialogWindow
-{
-public:
- FloatingToolWindow (const String& title,
- const String& windowPosPropertyName,
- Component* content,
- ScopedPointer& ownerPointer,
- int defaultW, int defaultH,
- int minW, int minH,
- int maxW, int maxH)
- : DialogWindow (title, Colours::darkgrey, true, true),
- windowPosProperty (windowPosPropertyName),
- owner (ownerPointer)
- {
- setUsingNativeTitleBar (true);
- setResizable (true, true);
- setResizeLimits (minW, minH, maxW, maxH);
- setContentOwned (content, false);
-
- const String windowState (getGlobalProperties().getValue (windowPosProperty));
-
- if (windowState.isNotEmpty())
- restoreWindowStateFromString (windowState);
- else
- centreAroundComponent (Component::getCurrentlyFocusedComponent(), defaultW, defaultH);
-
- setVisible (true);
- owner = this;
- }
-
- ~FloatingToolWindow()
- {
- getGlobalProperties().setValue (windowPosProperty, getWindowStateAsString());
- }
-
- void closeButtonPressed() override
- {
- owner = nullptr;
- }
-
- bool escapeKeyPressed() override
- {
- closeButtonPressed();
- return true;
- }
-
-private:
- String windowPosProperty;
- ScopedPointer& owner;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FloatingToolWindow)
-};
-
-//==============================================================================
-class PopupColourSelector : public Component,
- public ChangeListener,
- public Value::Listener,
- public ButtonListener
-{
-public:
- PopupColourSelector (const Value& colour,
- Colour defaultCol,
- const bool canResetToDefault)
- : defaultButton ("Reset to Default"),
- colourValue (colour),
- defaultColour (defaultCol)
- {
- addAndMakeVisible (selector);
- selector.setName ("Colour");
- selector.setCurrentColour (getColour());
- selector.addChangeListener (this);
-
- if (canResetToDefault)
- {
- addAndMakeVisible (defaultButton);
- defaultButton.addListener (this);
- }
-
- colourValue.addListener (this);
- setSize (300, 400);
- }
-
- void resized() override
- {
- if (defaultButton.isVisible())
- {
- selector.setBounds (0, 0, getWidth(), getHeight() - 30);
- defaultButton.changeWidthToFitText (22);
- defaultButton.setTopLeftPosition (10, getHeight() - 26);
- }
- else
- {
- selector.setBounds (getLocalBounds());
- }
- }
-
- Colour getColour() const
- {
- if (colourValue.toString().isEmpty())
- return defaultColour;
-
- return Colour::fromString (colourValue.toString());
- }
-
- void setColour (Colour newColour)
- {
- if (getColour() != newColour)
- {
- if (newColour == defaultColour && defaultButton.isVisible())
- colourValue = var();
- else
- colourValue = newColour.toDisplayString (true);
- }
- }
-
- void buttonClicked (Button*) override
- {
- setColour (defaultColour);
- selector.setCurrentColour (defaultColour);
- }
-
- void changeListenerCallback (ChangeBroadcaster*) override
- {
- if (selector.getCurrentColour() != getColour())
- setColour (selector.getCurrentColour());
- }
-
- void valueChanged (Value&) override
- {
- selector.setCurrentColour (getColour());
- }
-
-private:
- StoredSettings::ColourSelectorWithSwatches selector;
- TextButton defaultButton;
- Value colourValue;
- Colour defaultColour;
-};
-
-//==============================================================================
-/**
- A component that shows a colour swatch with hex ARGB value, and which pops up
- a colour selector when you click it.
-*/
-class ColourEditorComponent : public Component,
- public Value::Listener
-{
-public:
- ColourEditorComponent (UndoManager* um, const Value& colour,
- Colour defaultCol, const bool canReset)
- : undoManager (um), colourValue (colour), defaultColour (defaultCol),
- canResetToDefault (canReset)
- {
- colourValue.addListener (this);
- }
-
- void paint (Graphics& g) override
- {
- const Colour colour (getColour());
-
- g.fillAll (Colours::grey);
- g.fillCheckerBoard (getLocalBounds().reduced (2),
- 10, 10,
- Colour (0xffdddddd).overlaidWith (colour),
- Colour (0xffffffff).overlaidWith (colour));
-
- g.setColour (Colours::white.overlaidWith (colour).contrasting());
- g.setFont (Font (getHeight() * 0.6f, Font::bold));
- g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
- Justification::centred, 1);
- }
-
- Colour getColour() const
- {
- if (colourValue.toString().isEmpty())
- return defaultColour;
-
- return Colour::fromString (colourValue.toString());
- }
-
- void setColour (Colour newColour)
- {
- if (getColour() != newColour)
- {
- if (newColour == defaultColour && canResetToDefault)
- colourValue = var::null;
- else
- colourValue = newColour.toDisplayString (true);
- }
- }
-
- void resetToDefault()
- {
- setColour (defaultColour);
- }
-
- void refresh()
- {
- const Colour col (getColour());
-
- if (col != lastColour)
- {
- lastColour = col;
- repaint();
- }
- }
-
- void mouseDown (const MouseEvent&) override
- {
- if (undoManager != nullptr)
- undoManager->beginNewTransaction();
-
- CallOutBox::launchAsynchronously (new PopupColourSelector (colourValue,
- defaultColour,
- canResetToDefault),
- getScreenBounds(), nullptr);
- }
-
- void valueChanged (Value&) override
- {
- refresh();
- }
-
-private:
- UndoManager* undoManager;
- Value colourValue;
- Colour lastColour;
- const Colour defaultColour;
- const bool canResetToDefault;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
-};
-
-//==============================================================================
-class ColourPropertyComponent : public PropertyComponent
-{
-public:
- ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
- Colour defaultColour, bool canResetToDefault)
- : PropertyComponent (name),
- colourEditor (undoManager, colour, defaultColour, canResetToDefault)
- {
- addAndMakeVisible (colourEditor);
- }
-
- void resized() override
- {
- colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
- }
-
- void refresh() override {}
-
-protected:
- ColourEditorComponent colourEditor;
-};
-
-//==============================================================================
-class FilePathPropertyComponent : public PropertyComponent
-{
-public:
- /** A Property Component for selecting files or folders.
-
- The user may drag files over the property box, enter the path
- manually and/or click the '...' button to open a file selection
- dialog box
- */
- FilePathPropertyComponent (Value valueToControl,
- const String& propertyDescription,
- bool isDirectory,
- const String& wildcards = "*",
- const File& rootToUseForRelativePaths = File::nonexistent)
- : PropertyComponent (propertyDescription),
- innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths)
- {
- addAndMakeVisible (innerComp);
- }
-
- void refresh() override {} // N/A
-
-private:
- struct InnerComponent : public Component,
- public FileDragAndDropTarget,
- private Button::Listener
- {
- InnerComponent (Value v, bool isDir, const String& wc, const File& rt)
- : value (v),
- isDirectory (isDir),
- highlightForDragAndDrop (false),
- wildcards (wc),
- root (rt),
- button ("...")
- {
- addAndMakeVisible (textbox);
- textbox.getTextValue().referTo (value);
-
- addAndMakeVisible (button);
- button.addListener (this);
- }
-
- void paintOverChildren (Graphics& g) override
- {
- if (highlightForDragAndDrop)
- {
- g.setColour (Colours::green.withAlpha (0.1f));
- g.fillRect (getLocalBounds());
- }
- }
-
- void resized() override
- {
- juce::Rectangle r (getLocalBounds());
-
- button.setBounds (r.removeFromRight (24));
- textbox.setBounds (r);
- }
-
- bool isInterestedInFileDrag (const StringArray&) override { return true; }
- void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
- void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
-
- void filesDropped (const StringArray& files, int, int) override
- {
- const File firstFile (files[0]);
-
- if (isDirectory)
- setTo (firstFile.isDirectory() ? firstFile
- : firstFile.getParentDirectory());
- else
- setTo (firstFile);
- }
-
- void buttonClicked (Button*) override
- {
- const File currentFile (root.getChildFile (value.toString()));
-
- if (isDirectory)
- {
- FileChooser chooser ("Select directory", currentFile);
-
- if (chooser.browseForDirectory())
- setTo (chooser.getResult());
- }
- else
- {
- FileChooser chooser ("Select file", currentFile, wildcards);
-
- if (chooser.browseForFileToOpen())
- setTo (chooser.getResult());
- }
- }
-
- void setTo (const File& f)
- {
- value = (root == File::nonexistent) ? f.getFullPathName()
- : f.getRelativePathFrom (root);
- }
-
- Value value;
- bool isDirectory, highlightForDragAndDrop;
- String wildcards;
- File root;
- TextEditor textbox;
- TextButton button;
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent)
- };
-
- InnerComponent innerComp; // Used so that the PropertyComponent auto first-child positioning works
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
-};
#endif // JUCER_MISCUTILITIES_H_INCLUDED