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.

281 lines
8.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2015 - ROLI 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. #include "../../jucer_Headers.h"
  18. #include "jucer_ResourceEditorPanel.h"
  19. //==============================================================================
  20. class ResourceListButton : public Component,
  21. private ButtonListener
  22. {
  23. public:
  24. ResourceListButton (JucerDocument& doc)
  25. : document (doc), reloadButton ("Reload"), row (0)
  26. {
  27. setInterceptsMouseClicks (false, true);
  28. addAndMakeVisible (reloadButton);
  29. reloadButton.addListener (this);
  30. }
  31. void update (int newRow)
  32. {
  33. row = newRow;
  34. reloadButton.setVisible (document.getResources() [row] != nullptr);
  35. }
  36. void resized()
  37. {
  38. reloadButton.setBoundsInset (BorderSize<int> (2));
  39. }
  40. void buttonClicked (Button*)
  41. {
  42. if (const BinaryResources::BinaryResource* const r = document.getResources() [row])
  43. document.getResources()
  44. .browseForResource ("Select a file to replace this resource",
  45. "*",
  46. File (r->originalFilename),
  47. r->name);
  48. }
  49. private:
  50. JucerDocument& document;
  51. TextButton reloadButton;
  52. int row;
  53. };
  54. //==============================================================================
  55. ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc)
  56. : document (doc),
  57. addButton ("Add new resource..."),
  58. reloadAllButton ("Reload all resources"),
  59. delButton ("Delete selected resources")
  60. {
  61. addAndMakeVisible (addButton);
  62. addButton.addListener (this);
  63. addAndMakeVisible (reloadAllButton);
  64. reloadAllButton.addListener (this);
  65. addAndMakeVisible (delButton);
  66. delButton.addListener (this);
  67. delButton.setEnabled (false);
  68. addAndMakeVisible (listBox = new TableListBox (String(), this));
  69. listBox->getHeader().addColumn ("name", 1, 150, 80, 400);
  70. listBox->getHeader().addColumn ("original file", 2, 350, 80, 800);
  71. listBox->getHeader().addColumn ("size", 3, 100, 40, 150);
  72. listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable);
  73. listBox->getHeader().setStretchToFitActive (true);
  74. listBox->setColour (ListBox::backgroundColourId, findColour (secondaryBackgroundColourId));
  75. listBox->setColour (ListBox::outlineColourId, Colours::transparentBlack);
  76. listBox->setOutlineThickness (1);
  77. listBox->updateContent();
  78. document.addChangeListener (this);
  79. handleCommandMessage (1);
  80. }
  81. ResourceEditorPanel::~ResourceEditorPanel()
  82. {
  83. document.removeChangeListener (this);
  84. }
  85. int ResourceEditorPanel::getNumRows()
  86. {
  87. return document.getResources().size();
  88. }
  89. void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/,
  90. int /*width*/, int /*height*/, bool rowIsSelected)
  91. {
  92. if (rowIsSelected)
  93. g.fillAll (findColour (defaultHighlightColourId));
  94. }
  95. void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height,
  96. bool /*rowIsSelected*/)
  97. {
  98. if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber])
  99. {
  100. String text;
  101. if (columnId == 1)
  102. text = r->name;
  103. else if (columnId == 2)
  104. text = r->originalFilename;
  105. else if (columnId == 3)
  106. text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
  107. g.setFont (13.0f);
  108. g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true);
  109. }
  110. }
  111. Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
  112. Component* existingComponentToUpdate)
  113. {
  114. if (columnId != 4)
  115. return nullptr;
  116. if (existingComponentToUpdate == nullptr)
  117. existingComponentToUpdate = new ResourceListButton (document);
  118. ((ResourceListButton*) existingComponentToUpdate)->update (rowNumber);
  119. return existingComponentToUpdate;
  120. }
  121. int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId)
  122. {
  123. if (columnId == 4)
  124. return 0;
  125. Font f (13.0f);
  126. int widest = 40;
  127. for (int i = document.getResources().size(); --i >= 0;)
  128. {
  129. const BinaryResources::BinaryResource* const r = document.getResources() [i];
  130. jassert (r != nullptr);
  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 ((int64) 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::paint (Graphics& g)
  184. {
  185. g.fillAll (findColour (secondaryBackgroundColourId));
  186. }
  187. void ResourceEditorPanel::visibilityChanged()
  188. {
  189. if (isVisible())
  190. listBox->updateContent();
  191. }
  192. void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*)
  193. {
  194. if (isVisible())
  195. listBox->updateContent();
  196. }
  197. void ResourceEditorPanel::buttonClicked (Button* b)
  198. {
  199. if (b == &addButton)
  200. {
  201. document.getResources()
  202. .browseForResource ("Select a file to add as a resource",
  203. "*",
  204. File(),
  205. String());
  206. }
  207. else if (b == &delButton)
  208. {
  209. document.getResources().remove (listBox->getSelectedRow (0));
  210. }
  211. else if (b == &reloadAllButton)
  212. {
  213. StringArray failed;
  214. for (int i = 0; i < document.getResources().size(); ++i)
  215. {
  216. if (! document.getResources().reload (i))
  217. failed.add (document.getResources().getResourceNames() [i]);
  218. }
  219. if (failed.size() > 0)
  220. {
  221. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  222. TRANS("Reloading resources"),
  223. TRANS("The following resources couldn't be reloaded from their original files:\n\n")
  224. + failed.joinIntoString (", "));
  225. }
  226. }
  227. }