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.

266 lines
8.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. FileSearchPathListComponent::FileSearchPathListComponent()
  19. : addButton ("+"),
  20. removeButton ("-"),
  21. changeButton (TRANS ("change...")),
  22. upButton (String::empty, DrawableButton::ImageOnButtonBackground),
  23. downButton (String::empty, DrawableButton::ImageOnButtonBackground)
  24. {
  25. listBox.setModel (this);
  26. addAndMakeVisible (&listBox);
  27. listBox.setColour (ListBox::backgroundColourId, Colours::black.withAlpha (0.02f));
  28. listBox.setColour (ListBox::outlineColourId, Colours::black.withAlpha (0.1f));
  29. listBox.setOutlineThickness (1);
  30. addAndMakeVisible (&addButton);
  31. addButton.addListener (this);
  32. addButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
  33. addAndMakeVisible (&removeButton);
  34. removeButton.addListener (this);
  35. removeButton.setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | Button::ConnectedOnBottom | Button::ConnectedOnTop);
  36. addAndMakeVisible (&changeButton);
  37. changeButton.addListener (this);
  38. addAndMakeVisible (&upButton);
  39. upButton.addListener (this);
  40. {
  41. Path arrowPath;
  42. arrowPath.addArrow (Line<float> (50.0f, 100.0f, 50.0f, 0.0f), 40.0f, 100.0f, 50.0f);
  43. DrawablePath arrowImage;
  44. arrowImage.setFill (Colours::black.withAlpha (0.4f));
  45. arrowImage.setPath (arrowPath);
  46. upButton.setImages (&arrowImage);
  47. }
  48. addAndMakeVisible (&downButton);
  49. downButton.addListener (this);
  50. {
  51. Path arrowPath;
  52. arrowPath.addArrow (Line<float> (50.0f, 0.0f, 50.0f, 100.0f), 40.0f, 100.0f, 50.0f);
  53. DrawablePath arrowImage;
  54. arrowImage.setFill (Colours::black.withAlpha (0.4f));
  55. arrowImage.setPath (arrowPath);
  56. downButton.setImages (&arrowImage);
  57. }
  58. updateButtons();
  59. }
  60. FileSearchPathListComponent::~FileSearchPathListComponent()
  61. {
  62. }
  63. void FileSearchPathListComponent::updateButtons()
  64. {
  65. const bool anythingSelected = listBox.getNumSelectedRows() > 0;
  66. removeButton.setEnabled (anythingSelected);
  67. changeButton.setEnabled (anythingSelected);
  68. upButton.setEnabled (anythingSelected);
  69. downButton.setEnabled (anythingSelected);
  70. }
  71. void FileSearchPathListComponent::changed()
  72. {
  73. listBox.updateContent();
  74. listBox.repaint();
  75. updateButtons();
  76. }
  77. //==============================================================================
  78. void FileSearchPathListComponent::setPath (const FileSearchPath& newPath)
  79. {
  80. if (newPath.toString() != path.toString())
  81. {
  82. path = newPath;
  83. changed();
  84. }
  85. }
  86. void FileSearchPathListComponent::setDefaultBrowseTarget (const File& newDefaultDirectory)
  87. {
  88. defaultBrowseTarget = newDefaultDirectory;
  89. }
  90. //==============================================================================
  91. int FileSearchPathListComponent::getNumRows()
  92. {
  93. return path.getNumPaths();
  94. }
  95. void FileSearchPathListComponent::paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected)
  96. {
  97. if (rowIsSelected)
  98. g.fillAll (findColour (TextEditor::highlightColourId));
  99. g.setColour (findColour (ListBox::textColourId));
  100. Font f (height * 0.7f);
  101. f.setHorizontalScale (0.9f);
  102. g.setFont (f);
  103. g.drawText (path [rowNumber].getFullPathName(),
  104. 4, 0, width - 6, height,
  105. Justification::centredLeft, true);
  106. }
  107. void FileSearchPathListComponent::deleteKeyPressed (int row)
  108. {
  109. if (isPositiveAndBelow (row, path.getNumPaths()))
  110. {
  111. path.remove (row);
  112. changed();
  113. }
  114. }
  115. void FileSearchPathListComponent::returnKeyPressed (int row)
  116. {
  117. #if JUCE_MODAL_LOOPS_PERMITTED
  118. FileChooser chooser (TRANS("Change folder..."), path [row], "*");
  119. if (chooser.browseForDirectory())
  120. {
  121. path.remove (row);
  122. path.add (chooser.getResult(), row);
  123. changed();
  124. }
  125. #endif
  126. }
  127. void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&)
  128. {
  129. returnKeyPressed (row);
  130. }
  131. void FileSearchPathListComponent::selectedRowsChanged (int)
  132. {
  133. updateButtons();
  134. }
  135. void FileSearchPathListComponent::paint (Graphics& g)
  136. {
  137. g.fillAll (findColour (backgroundColourId));
  138. }
  139. void FileSearchPathListComponent::resized()
  140. {
  141. const int buttonH = 22;
  142. const int buttonY = getHeight() - buttonH - 4;
  143. listBox.setBounds (2, 2, getWidth() - 4, buttonY - 5);
  144. addButton.setBounds (2, buttonY, buttonH, buttonH);
  145. removeButton.setBounds (addButton.getRight(), buttonY, buttonH, buttonH);
  146. changeButton.changeWidthToFitText (buttonH);
  147. downButton.setSize (buttonH * 2, buttonH);
  148. upButton.setSize (buttonH * 2, buttonH);
  149. downButton.setTopRightPosition (getWidth() - 2, buttonY);
  150. upButton.setTopRightPosition (downButton.getX() - 4, buttonY);
  151. changeButton.setTopRightPosition (upButton.getX() - 8, buttonY);
  152. }
  153. bool FileSearchPathListComponent::isInterestedInFileDrag (const StringArray&)
  154. {
  155. return true;
  156. }
  157. void FileSearchPathListComponent::filesDropped (const StringArray& filenames, int, int mouseY)
  158. {
  159. for (int i = filenames.size(); --i >= 0;)
  160. {
  161. const File f (filenames[i]);
  162. if (f.isDirectory())
  163. {
  164. const int row = listBox.getRowContainingPosition (0, mouseY - listBox.getY());
  165. path.add (f, row);
  166. changed();
  167. }
  168. }
  169. }
  170. void FileSearchPathListComponent::buttonClicked (Button* button)
  171. {
  172. const int currentRow = listBox.getSelectedRow();
  173. if (button == &removeButton)
  174. {
  175. deleteKeyPressed (currentRow);
  176. }
  177. else if (button == &addButton)
  178. {
  179. File start (defaultBrowseTarget);
  180. if (start == File::nonexistent)
  181. start = path [0];
  182. if (start == File::nonexistent)
  183. start = File::getCurrentWorkingDirectory();
  184. #if JUCE_MODAL_LOOPS_PERMITTED
  185. FileChooser chooser (TRANS("Add a folder..."), start, "*");
  186. if (chooser.browseForDirectory())
  187. path.add (chooser.getResult(), currentRow);
  188. #else
  189. jassertfalse; // needs rewriting to deal with non-modal environments
  190. #endif
  191. }
  192. else if (button == &changeButton)
  193. {
  194. returnKeyPressed (currentRow);
  195. }
  196. else if (button == &upButton)
  197. {
  198. if (currentRow > 0 && currentRow < path.getNumPaths())
  199. {
  200. const File f (path[currentRow]);
  201. path.remove (currentRow);
  202. path.add (f, currentRow - 1);
  203. listBox.selectRow (currentRow - 1);
  204. }
  205. }
  206. else if (button == &downButton)
  207. {
  208. if (currentRow >= 0 && currentRow < path.getNumPaths() - 1)
  209. {
  210. const File f (path[currentRow]);
  211. path.remove (currentRow);
  212. path.add (f, currentRow + 1);
  213. listBox.selectRow (currentRow + 1);
  214. }
  215. }
  216. changed();
  217. }