The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
5.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #pragma once
  18. class FilePathPropertyComponent : public PropertyComponent
  19. {
  20. public:
  21. /** A Property Component for selecting files or folders.
  22. The user may drag files over the property box, enter the path
  23. manually and/or click the '...' button to open a file selection
  24. dialog box
  25. */
  26. FilePathPropertyComponent (Value valueToControl,
  27. const String& propertyDescription,
  28. bool isDirectory,
  29. const String& wildcards = "*",
  30. const File& rootToUseForRelativePaths = File())
  31. : PropertyComponent (propertyDescription),
  32. innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths)
  33. {
  34. addAndMakeVisible (innerComp);
  35. }
  36. void refresh() override {} // N/A
  37. private:
  38. struct InnerComponent : public Component,
  39. public FileDragAndDropTarget,
  40. private Button::Listener
  41. {
  42. InnerComponent (Value v, bool isDir, const String& wc, const File& rt)
  43. : value (v),
  44. isDirectory (isDir),
  45. highlightForDragAndDrop (false),
  46. wildcards (wc),
  47. root (rt),
  48. button ("...")
  49. {
  50. addAndMakeVisible (textbox);
  51. textbox.getTextValue().referTo (value);
  52. addAndMakeVisible (button);
  53. button.addListener (this);
  54. lookAndFeelChanged();
  55. }
  56. void paintOverChildren (Graphics& g) override
  57. {
  58. if (highlightForDragAndDrop)
  59. {
  60. g.setColour (Colours::green.withAlpha (0.1f));
  61. g.fillRect (getLocalBounds());
  62. }
  63. }
  64. void resized() override
  65. {
  66. juce::Rectangle<int> r (getLocalBounds());
  67. button.setBounds (r.removeFromRight (30));
  68. textbox.setBounds (r);
  69. }
  70. bool isInterestedInFileDrag (const StringArray&) override { return true; }
  71. void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
  72. void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
  73. void filesDropped (const StringArray& files, int, int) override
  74. {
  75. const File firstFile (files[0]);
  76. if (isDirectory)
  77. setTo (firstFile.isDirectory() ? firstFile
  78. : firstFile.getParentDirectory());
  79. else
  80. setTo (firstFile);
  81. }
  82. void buttonClicked (Button*) override
  83. {
  84. const File currentFile (root.getChildFile (value.toString()));
  85. if (isDirectory)
  86. {
  87. FileChooser chooser ("Select directory", currentFile);
  88. if (chooser.browseForDirectory())
  89. setTo (chooser.getResult());
  90. }
  91. else
  92. {
  93. FileChooser chooser ("Select file", currentFile, wildcards);
  94. if (chooser.browseForFileToOpen())
  95. setTo (chooser.getResult());
  96. }
  97. }
  98. void setTo (const File& f)
  99. {
  100. value = (root == File()) ? f.getFullPathName()
  101. : f.getRelativePathFrom (root);
  102. }
  103. void lookAndFeelChanged() override
  104. {
  105. textbox.setColour (TextEditor::backgroundColourId, findColour (widgetBackgroundColourId));
  106. textbox.setColour (TextEditor::outlineColourId, Colours::transparentBlack);
  107. textbox.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
  108. textbox.applyFontToAllText (textbox.getFont());
  109. button.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
  110. button.setColour (TextButton::textColourOffId, Colours::white);
  111. }
  112. Value value;
  113. bool isDirectory, highlightForDragAndDrop;
  114. String wildcards;
  115. File root;
  116. TextEditor textbox;
  117. TextButton button;
  118. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent)
  119. };
  120. InnerComponent innerComp; // Used so that the PropertyComponent auto first-child positioning works
  121. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
  122. };