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.

267 lines
7.9KB

  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. FileSearchPathListComponent::FileSearchPathListComponent()
  18. : addButton ("+"),
  19. removeButton ("-"),
  20. changeButton (TRANS ("change...")),
  21. upButton (String(), DrawableButton::ImageOnButtonBackground),
  22. downButton (String(), DrawableButton::ImageOnButtonBackground)
  23. {
  24. listBox.setModel (this);
  25. addAndMakeVisible (listBox);
  26. listBox.setColour (ListBox::backgroundColourId, Colours::black.withAlpha (0.02f));
  27. listBox.setColour (ListBox::outlineColourId, Colours::black.withAlpha (0.1f));
  28. listBox.setOutlineThickness (1);
  29. addAndMakeVisible (addButton);
  30. addButton.addListener (this);
  31. addButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
  32. addAndMakeVisible (removeButton);
  33. removeButton.addListener (this);
  34. removeButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
  35. addAndMakeVisible (changeButton);
  36. changeButton.addListener (this);
  37. addAndMakeVisible (upButton);
  38. upButton.addListener (this);
  39. {
  40. Path arrowPath;
  41. arrowPath.addArrow (Line<float> (50.0f, 100.0f, 50.0f, 0.0f), 40.0f, 100.0f, 50.0f);
  42. DrawablePath arrowImage;
  43. arrowImage.setFill (Colours::black.withAlpha (0.4f));
  44. arrowImage.setPath (arrowPath);
  45. upButton.setImages (&arrowImage);
  46. }
  47. addAndMakeVisible (downButton);
  48. downButton.addListener (this);
  49. {
  50. Path arrowPath;
  51. arrowPath.addArrow (Line<float> (50.0f, 0.0f, 50.0f, 100.0f), 40.0f, 100.0f, 50.0f);
  52. DrawablePath arrowImage;
  53. arrowImage.setFill (Colours::black.withAlpha (0.4f));
  54. arrowImage.setPath (arrowPath);
  55. downButton.setImages (&arrowImage);
  56. }
  57. updateButtons();
  58. }
  59. FileSearchPathListComponent::~FileSearchPathListComponent()
  60. {
  61. }
  62. void FileSearchPathListComponent::updateButtons()
  63. {
  64. const bool anythingSelected = listBox.getNumSelectedRows() > 0;
  65. removeButton.setEnabled (anythingSelected);
  66. changeButton.setEnabled (anythingSelected);
  67. upButton.setEnabled (anythingSelected);
  68. downButton.setEnabled (anythingSelected);
  69. }
  70. void FileSearchPathListComponent::changed()
  71. {
  72. listBox.updateContent();
  73. listBox.repaint();
  74. updateButtons();
  75. }
  76. //==============================================================================
  77. void FileSearchPathListComponent::setPath (const FileSearchPath& newPath)
  78. {
  79. if (newPath.toString() != path.toString())
  80. {
  81. path = newPath;
  82. changed();
  83. }
  84. }
  85. void FileSearchPathListComponent::setDefaultBrowseTarget (const File& newDefaultDirectory)
  86. {
  87. defaultBrowseTarget = newDefaultDirectory;
  88. }
  89. //==============================================================================
  90. int FileSearchPathListComponent::getNumRows()
  91. {
  92. return path.getNumPaths();
  93. }
  94. void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
  95. {
  96. if (rowIsSelected)
  97. g.fillAll (findColour (TextEditor::highlightColourId));
  98. g.setColour (findColour (ListBox::textColourId));
  99. Font f (height * 0.7f);
  100. f.setHorizontalScale (0.9f);
  101. g.setFont (f);
  102. g.drawText (path [rowNumber].getFullPathName(),
  103. 4, 0, width - 6, height,
  104. Justification::centredLeft, true);
  105. }
  106. void FileSearchPathListComponent::deleteKeyPressed (int row)
  107. {
  108. if (isPositiveAndBelow (row, path.getNumPaths()))
  109. {
  110. path.remove (row);
  111. changed();
  112. }
  113. }
  114. void FileSearchPathListComponent::returnKeyPressed (int row)
  115. {
  116. #if JUCE_MODAL_LOOPS_PERMITTED
  117. FileChooser chooser (TRANS("Change folder..."), path [row], "*");
  118. if (chooser.browseForDirectory())
  119. {
  120. path.remove (row);
  121. path.add (chooser.getResult(), row);
  122. changed();
  123. }
  124. #else
  125. ignoreUnused (row);
  126. #endif
  127. }
  128. void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&)
  129. {
  130. returnKeyPressed (row);
  131. }
  132. void FileSearchPathListComponent::selectedRowsChanged (int)
  133. {
  134. updateButtons();
  135. }
  136. void FileSearchPathListComponent::paint (Graphics& g)
  137. {
  138. g.fillAll (findColour (backgroundColourId));
  139. }
  140. void FileSearchPathListComponent::resized()
  141. {
  142. const int buttonH = 22;
  143. const int buttonY = getHeight() - buttonH - 4;
  144. listBox.setBounds (2, 2, getWidth() - 4, buttonY - 5);
  145. addButton.setBounds (2, buttonY, buttonH, buttonH);
  146. removeButton.setBounds (addButton.getRight(), buttonY, buttonH, buttonH);
  147. changeButton.changeWidthToFitText (buttonH);
  148. downButton.setSize (buttonH * 2, buttonH);
  149. upButton.setSize (buttonH * 2, buttonH);
  150. downButton.setTopRightPosition (getWidth() - 2, buttonY);
  151. upButton.setTopRightPosition (downButton.getX() - 4, buttonY);
  152. changeButton.setTopRightPosition (upButton.getX() - 8, buttonY);
  153. }
  154. bool FileSearchPathListComponent::isInterestedInFileDrag (const StringArray&)
  155. {
  156. return true;
  157. }
  158. void FileSearchPathListComponent::filesDropped (const StringArray& filenames, int, int mouseY)
  159. {
  160. for (int i = filenames.size(); --i >= 0;)
  161. {
  162. const File f (filenames[i]);
  163. if (f.isDirectory())
  164. {
  165. const int row = listBox.getRowContainingPosition (0, mouseY - listBox.getY());
  166. path.add (f, row);
  167. changed();
  168. }
  169. }
  170. }
  171. void FileSearchPathListComponent::buttonClicked (Button* button)
  172. {
  173. const int currentRow = listBox.getSelectedRow();
  174. if (button == &removeButton)
  175. {
  176. deleteKeyPressed (currentRow);
  177. }
  178. else if (button == &addButton)
  179. {
  180. File start (defaultBrowseTarget);
  181. if (start == File())
  182. start = path [0];
  183. if (start == File())
  184. start = File::getCurrentWorkingDirectory();
  185. #if JUCE_MODAL_LOOPS_PERMITTED
  186. FileChooser chooser (TRANS("Add a folder..."), start, "*");
  187. if (chooser.browseForDirectory())
  188. path.add (chooser.getResult(), currentRow);
  189. #else
  190. jassertfalse; // needs rewriting to deal with non-modal environments
  191. #endif
  192. }
  193. else if (button == &changeButton)
  194. {
  195. returnKeyPressed (currentRow);
  196. }
  197. else if (button == &upButton)
  198. {
  199. if (currentRow > 0 && currentRow < path.getNumPaths())
  200. {
  201. const File f (path[currentRow]);
  202. path.remove (currentRow);
  203. path.add (f, currentRow - 1);
  204. listBox.selectRow (currentRow - 1);
  205. }
  206. }
  207. else if (button == &downButton)
  208. {
  209. if (currentRow >= 0 && currentRow < path.getNumPaths() - 1)
  210. {
  211. const File f (path[currentRow]);
  212. path.remove (currentRow);
  213. path.add (f, currentRow + 1);
  214. listBox.selectRow (currentRow + 1);
  215. }
  216. }
  217. changed();
  218. }