juce_FileSearchPathListComponent.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software 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::empty, DrawableButton::ImageOnButtonBackground),
  22. downButton (String::empty, 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. #endif
  125. }
  126. void FileSearchPathListComponent::listBoxItemDoubleClicked (int row, const MouseEvent&)
  127. {
  128. returnKeyPressed (row);
  129. }
  130. void FileSearchPathListComponent::selectedRowsChanged (int)
  131. {
  132. updateButtons();
  133. }
  134. void FileSearchPathListComponent::paint (Graphics& g)
  135. {
  136. g.fillAll (findColour (backgroundColourId));
  137. }
  138. void FileSearchPathListComponent::resized()
  139. {
  140. const int buttonH = 22;
  141. const int buttonY = getHeight() - buttonH - 4;
  142. listBox.setBounds (2, 2, getWidth() - 4, buttonY - 5);
  143. addButton.setBounds (2, buttonY, buttonH, buttonH);
  144. removeButton.setBounds (addButton.getRight(), buttonY, buttonH, buttonH);
  145. changeButton.changeWidthToFitText (buttonH);
  146. downButton.setSize (buttonH * 2, buttonH);
  147. upButton.setSize (buttonH * 2, buttonH);
  148. downButton.setTopRightPosition (getWidth() - 2, buttonY);
  149. upButton.setTopRightPosition (downButton.getX() - 4, buttonY);
  150. changeButton.setTopRightPosition (upButton.getX() - 8, buttonY);
  151. }
  152. bool FileSearchPathListComponent::isInterestedInFileDrag (const StringArray&)
  153. {
  154. return true;
  155. }
  156. void FileSearchPathListComponent::filesDropped (const StringArray& filenames, int, int mouseY)
  157. {
  158. for (int i = filenames.size(); --i >= 0;)
  159. {
  160. const File f (filenames[i]);
  161. if (f.isDirectory())
  162. {
  163. const int row = listBox.getRowContainingPosition (0, mouseY - listBox.getY());
  164. path.add (f, row);
  165. changed();
  166. }
  167. }
  168. }
  169. void FileSearchPathListComponent::buttonClicked (Button* button)
  170. {
  171. const int currentRow = listBox.getSelectedRow();
  172. if (button == &removeButton)
  173. {
  174. deleteKeyPressed (currentRow);
  175. }
  176. else if (button == &addButton)
  177. {
  178. File start (defaultBrowseTarget);
  179. if (start == File::nonexistent)
  180. start = path [0];
  181. if (start == File::nonexistent)
  182. start = File::getCurrentWorkingDirectory();
  183. #if JUCE_MODAL_LOOPS_PERMITTED
  184. FileChooser chooser (TRANS("Add a folder..."), start, "*");
  185. if (chooser.browseForDirectory())
  186. path.add (chooser.getResult(), currentRow);
  187. #else
  188. jassertfalse; // needs rewriting to deal with non-modal environments
  189. #endif
  190. }
  191. else if (button == &changeButton)
  192. {
  193. returnKeyPressed (currentRow);
  194. }
  195. else if (button == &upButton)
  196. {
  197. if (currentRow > 0 && currentRow < path.getNumPaths())
  198. {
  199. const File f (path[currentRow]);
  200. path.remove (currentRow);
  201. path.add (f, currentRow - 1);
  202. listBox.selectRow (currentRow - 1);
  203. }
  204. }
  205. else if (button == &downButton)
  206. {
  207. if (currentRow >= 0 && currentRow < path.getNumPaths() - 1)
  208. {
  209. const File f (path[currentRow]);
  210. path.remove (currentRow);
  211. path.add (f, currentRow + 1);
  212. listBox.selectRow (currentRow + 1);
  213. }
  214. }
  215. changed();
  216. }