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.

157 lines
5.4KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #pragma once
  20. class FilePathPropertyComponent : public PropertyComponent
  21. {
  22. public:
  23. /** A Property Component for selecting files or folders.
  24. The user may drag files over the property box, enter the path
  25. manually and/or click the '...' button to open a file selection
  26. dialog box
  27. */
  28. FilePathPropertyComponent (Value valueToControl,
  29. const String& propertyDescription,
  30. bool isDirectory,
  31. const String& wildcards = "*",
  32. const File& rootToUseForRelativePaths = File())
  33. : PropertyComponent (propertyDescription),
  34. innerComp (valueToControl, isDirectory, wildcards, rootToUseForRelativePaths)
  35. {
  36. addAndMakeVisible (innerComp);
  37. }
  38. void refresh() override {} // N/A
  39. private:
  40. struct InnerComponent : public Component,
  41. public FileDragAndDropTarget,
  42. private Button::Listener
  43. {
  44. InnerComponent (Value v, bool isDir, const String& wc, const File& rt)
  45. : value (v),
  46. isDirectory (isDir),
  47. highlightForDragAndDrop (false),
  48. wildcards (wc),
  49. root (rt),
  50. button ("...")
  51. {
  52. addAndMakeVisible (textbox);
  53. textbox.getTextValue().referTo (value);
  54. addAndMakeVisible (button);
  55. button.addListener (this);
  56. lookAndFeelChanged();
  57. }
  58. void paintOverChildren (Graphics& g) override
  59. {
  60. if (highlightForDragAndDrop)
  61. {
  62. g.setColour (Colours::green.withAlpha (0.1f));
  63. g.fillRect (getLocalBounds());
  64. }
  65. }
  66. void resized() override
  67. {
  68. juce::Rectangle<int> r (getLocalBounds());
  69. button.setBounds (r.removeFromRight (30));
  70. textbox.setBounds (r);
  71. }
  72. bool isInterestedInFileDrag (const StringArray&) override { return true; }
  73. void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
  74. void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
  75. void filesDropped (const StringArray& files, int, int) override
  76. {
  77. const File firstFile (files[0]);
  78. if (isDirectory)
  79. setTo (firstFile.isDirectory() ? firstFile
  80. : firstFile.getParentDirectory());
  81. else
  82. setTo (firstFile);
  83. }
  84. void buttonClicked (Button*) override
  85. {
  86. const File currentFile (root.getChildFile (value.toString()));
  87. if (isDirectory)
  88. {
  89. FileChooser chooser ("Select directory", currentFile);
  90. if (chooser.browseForDirectory())
  91. setTo (chooser.getResult());
  92. }
  93. else
  94. {
  95. FileChooser chooser ("Select file", currentFile, wildcards);
  96. if (chooser.browseForFileToOpen())
  97. setTo (chooser.getResult());
  98. }
  99. }
  100. void setTo (const File& f)
  101. {
  102. value = (root == File()) ? f.getFullPathName()
  103. : f.getRelativePathFrom (root);
  104. }
  105. void lookAndFeelChanged() override
  106. {
  107. textbox.setColour (TextEditor::backgroundColourId, findColour (widgetBackgroundColourId));
  108. textbox.setColour (TextEditor::outlineColourId, Colours::transparentBlack);
  109. textbox.setColour (TextEditor::textColourId, findColour (widgetTextColourId));
  110. textbox.applyFontToAllText (textbox.getFont());
  111. button.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
  112. button.setColour (TextButton::textColourOffId, Colours::white);
  113. }
  114. Value value;
  115. bool isDirectory, highlightForDragAndDrop;
  116. String wildcards;
  117. File root;
  118. TextEditor textbox;
  119. TextButton button;
  120. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (InnerComponent)
  121. };
  122. InnerComponent innerComp; // Used so that the PropertyComponent auto first-child positioning works
  123. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
  124. };