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.

272 lines
8.2KB

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