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.

277 lines
8.4KB

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