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.

276 lines
9.0KB

  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. #include "../../jucer_Headers.h"
  19. #include "jucer_ResourceEditorPanel.h"
  20. //==============================================================================
  21. class ResourceListButton : public Component,
  22. private ButtonListener
  23. {
  24. public:
  25. ResourceListButton (JucerDocument& doc)
  26. : document (doc), reloadButton ("Reload"), row (0)
  27. {
  28. setInterceptsMouseClicks (false, true);
  29. addAndMakeVisible (&reloadButton);
  30. reloadButton.addListener (this);
  31. }
  32. void update (int newRow)
  33. {
  34. row = newRow;
  35. reloadButton.setVisible (document.getResources() [row] != nullptr);
  36. }
  37. void resized()
  38. {
  39. reloadButton.setBoundsInset (BorderSize<int> (2));
  40. }
  41. void buttonClicked (Button*)
  42. {
  43. if (const BinaryResources::BinaryResource* const r = document.getResources() [row])
  44. document.getResources()
  45. .browseForResource ("Select a file to replace this resource",
  46. "*",
  47. File (r->originalFilename),
  48. r->name);
  49. }
  50. private:
  51. JucerDocument& document;
  52. TextButton reloadButton;
  53. int row;
  54. };
  55. //==============================================================================
  56. ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc)
  57. : document (doc),
  58. addButton ("Add new resource..."),
  59. reloadAllButton ("Reload all resources"),
  60. delButton ("Delete selected resources")
  61. {
  62. addAndMakeVisible (&addButton);
  63. addButton.addListener (this);
  64. addAndMakeVisible (&reloadAllButton);
  65. reloadAllButton.addListener (this);
  66. addAndMakeVisible (&delButton);
  67. delButton.addListener (this);
  68. delButton.setEnabled (false);
  69. addAndMakeVisible (listBox = new TableListBox (String::empty, this));
  70. listBox->getHeader().addColumn ("name", 1, 150, 80, 400);
  71. listBox->getHeader().addColumn ("original file", 2, 350, 80, 800);
  72. listBox->getHeader().addColumn ("size", 3, 100, 40, 150);
  73. listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable);
  74. listBox->getHeader().setStretchToFitActive (true);
  75. listBox->setColour (ListBox::backgroundColourId, Colours::lightgrey);
  76. listBox->setColour (ListBox::outlineColourId, Colours::darkgrey);
  77. listBox->setOutlineThickness (1);
  78. listBox->updateContent();
  79. document.addChangeListener (this);
  80. handleCommandMessage (1);
  81. }
  82. ResourceEditorPanel::~ResourceEditorPanel()
  83. {
  84. document.removeChangeListener (this);
  85. }
  86. int ResourceEditorPanel::getNumRows()
  87. {
  88. return document.getResources().size();
  89. }
  90. void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/,
  91. int /*width*/, int /*height*/, bool rowIsSelected)
  92. {
  93. if (rowIsSelected)
  94. g.fillAll (findColour (TextEditor::highlightColourId));
  95. }
  96. void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height,
  97. bool /*rowIsSelected*/)
  98. {
  99. if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber])
  100. {
  101. String text;
  102. if (columnId == 1)
  103. text = r->name;
  104. else if (columnId == 2)
  105. text = r->originalFilename;
  106. else if (columnId == 3)
  107. text = File::descriptionOfSizeInBytes (r->data.getSize());
  108. g.setFont (13.0f);
  109. g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true);
  110. }
  111. }
  112. Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
  113. Component* existingComponentToUpdate)
  114. {
  115. if (columnId != 4)
  116. return nullptr;
  117. if (existingComponentToUpdate == nullptr)
  118. existingComponentToUpdate = new ResourceListButton (document);
  119. ((ResourceListButton*) existingComponentToUpdate)->update (rowNumber);
  120. return existingComponentToUpdate;
  121. }
  122. int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId)
  123. {
  124. if (columnId == 4)
  125. return 0;
  126. Font f (13.0f);
  127. int widest = 40;
  128. for (int i = document.getResources().size(); --i >= 0;)
  129. {
  130. const BinaryResources::BinaryResource* const r = document.getResources() [i];
  131. String text;
  132. if (columnId == 1)
  133. text = r->name;
  134. else if (columnId == 2)
  135. text = r->originalFilename;
  136. else if (columnId == 3)
  137. text = File::descriptionOfSizeInBytes (r->data.getSize());
  138. widest = jmax (widest, f.getStringWidth (text));
  139. }
  140. return widest + 10;
  141. }
  142. //==============================================================================
  143. class ResourceSorter
  144. {
  145. public:
  146. ResourceSorter (const int columnId_, const bool forwards)
  147. : columnId (columnId_),
  148. direction (forwards ? 1 : -1)
  149. {
  150. }
  151. int compareElements (BinaryResources::BinaryResource* first, BinaryResources::BinaryResource* second)
  152. {
  153. if (columnId == 1) return direction * first->name.compare (second->name);
  154. if (columnId == 2) return direction * first->originalFilename.compare (second->originalFilename);
  155. if (columnId == 3) return direction * (int) first->data.getSize() - (int) second->data.getSize();
  156. return 0;
  157. }
  158. private:
  159. const int columnId, direction;
  160. ResourceSorter (const ResourceSorter&);
  161. ResourceSorter& operator= (const ResourceSorter&);
  162. };
  163. void ResourceEditorPanel::sortOrderChanged (int newSortColumnId, const bool isForwards)
  164. {
  165. ResourceSorter sorter (newSortColumnId, isForwards);
  166. document.getResources().sort (sorter);
  167. }
  168. //==============================================================================
  169. void ResourceEditorPanel::selectedRowsChanged (int /*lastRowSelected*/)
  170. {
  171. delButton.setEnabled (listBox->getNumSelectedRows() > 0);
  172. }
  173. void ResourceEditorPanel::resized()
  174. {
  175. listBox->setBounds (6, 4, getWidth() - 12, getHeight() - 38);
  176. addButton.changeWidthToFitText (22);
  177. addButton.setTopLeftPosition (8, getHeight() - 30);
  178. reloadAllButton.changeWidthToFitText (22);
  179. reloadAllButton.setTopLeftPosition (addButton.getRight() + 10, getHeight() - 30);
  180. delButton.changeWidthToFitText (22);
  181. delButton.setTopRightPosition (getWidth() - 8, getHeight() - 30);
  182. }
  183. void ResourceEditorPanel::visibilityChanged()
  184. {
  185. if (isVisible())
  186. listBox->updateContent();
  187. }
  188. void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*)
  189. {
  190. if (isVisible())
  191. listBox->updateContent();
  192. }
  193. void ResourceEditorPanel::buttonClicked (Button* b)
  194. {
  195. if (b == &addButton)
  196. {
  197. document.getResources()
  198. .browseForResource ("Select a file to add as a resource",
  199. "*",
  200. File::nonexistent,
  201. String::empty);
  202. }
  203. else if (b == &delButton)
  204. {
  205. document.getResources().remove (listBox->getSelectedRow (0));
  206. }
  207. else if (b == &reloadAllButton)
  208. {
  209. StringArray failed;
  210. for (int i = 0; i < document.getResources().size(); ++i)
  211. {
  212. if (! document.getResources().reload (i))
  213. failed.add (document.getResources().getResourceNames() [i]);
  214. }
  215. if (failed.size() > 0)
  216. {
  217. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  218. TRANS("Reloading resources"),
  219. TRANS("The following resources couldn't be reloaded from their original files:\n\n")
  220. + failed.joinIntoString (", "));
  221. }
  222. }
  223. }