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.

283 lines
8.9KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. #include "../../jucer_Headers.h"
  20. #include "jucer_ResourceEditorPanel.h"
  21. //==============================================================================
  22. class ResourceListButton : public Component,
  23. private ButtonListener
  24. {
  25. public:
  26. ResourceListButton (JucerDocument& doc)
  27. : document (doc), reloadButton ("Reload"), row (0)
  28. {
  29. setInterceptsMouseClicks (false, true);
  30. addAndMakeVisible (reloadButton);
  31. reloadButton.addListener (this);
  32. }
  33. void update (int newRow)
  34. {
  35. row = newRow;
  36. reloadButton.setVisible (document.getResources() [row] != nullptr);
  37. }
  38. void resized()
  39. {
  40. reloadButton.setBoundsInset (BorderSize<int> (2));
  41. }
  42. void buttonClicked (Button*)
  43. {
  44. if (const BinaryResources::BinaryResource* const r = document.getResources() [row])
  45. document.getResources()
  46. .browseForResource ("Select a file to replace this resource",
  47. "*",
  48. File (r->originalFilename),
  49. r->name);
  50. }
  51. private:
  52. JucerDocument& document;
  53. TextButton reloadButton;
  54. int row;
  55. };
  56. //==============================================================================
  57. ResourceEditorPanel::ResourceEditorPanel (JucerDocument& doc)
  58. : document (doc),
  59. addButton ("Add new resource..."),
  60. reloadAllButton ("Reload all resources"),
  61. delButton ("Delete selected resources")
  62. {
  63. addAndMakeVisible (addButton);
  64. addButton.addListener (this);
  65. addAndMakeVisible (reloadAllButton);
  66. reloadAllButton.addListener (this);
  67. addAndMakeVisible (delButton);
  68. delButton.addListener (this);
  69. delButton.setEnabled (false);
  70. addAndMakeVisible (listBox = new TableListBox (String(), this));
  71. listBox->getHeader().addColumn ("name", 1, 150, 80, 400);
  72. listBox->getHeader().addColumn ("original file", 2, 350, 80, 800);
  73. listBox->getHeader().addColumn ("size", 3, 100, 40, 150);
  74. listBox->getHeader().addColumn ("reload", 4, 100, 100, 100, TableHeaderComponent::notResizableOrSortable);
  75. listBox->getHeader().setStretchToFitActive (true);
  76. listBox->setColour (ListBox::backgroundColourId, findColour (secondaryBackgroundColourId));
  77. listBox->setColour (ListBox::outlineColourId, Colours::transparentBlack);
  78. listBox->setOutlineThickness (1);
  79. listBox->updateContent();
  80. document.addChangeListener (this);
  81. handleCommandMessage (1);
  82. }
  83. ResourceEditorPanel::~ResourceEditorPanel()
  84. {
  85. document.removeChangeListener (this);
  86. }
  87. int ResourceEditorPanel::getNumRows()
  88. {
  89. return document.getResources().size();
  90. }
  91. void ResourceEditorPanel::paintRowBackground (Graphics& g, int /*rowNumber*/,
  92. int /*width*/, int /*height*/, bool rowIsSelected)
  93. {
  94. if (rowIsSelected)
  95. g.fillAll (findColour (defaultHighlightColourId));
  96. }
  97. void ResourceEditorPanel::paintCell (Graphics& g, int rowNumber, int columnId, int width, int height,
  98. bool /*rowIsSelected*/)
  99. {
  100. if (const BinaryResources::BinaryResource* const r = document.getResources() [rowNumber])
  101. {
  102. String text;
  103. if (columnId == 1)
  104. text = r->name;
  105. else if (columnId == 2)
  106. text = r->originalFilename;
  107. else if (columnId == 3)
  108. text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
  109. g.setFont (13.0f);
  110. g.drawText (text, 4, 0, width - 6, height, Justification::centredLeft, true);
  111. }
  112. }
  113. Component* ResourceEditorPanel::refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
  114. Component* existingComponentToUpdate)
  115. {
  116. if (columnId != 4)
  117. return nullptr;
  118. if (existingComponentToUpdate == nullptr)
  119. existingComponentToUpdate = new ResourceListButton (document);
  120. ((ResourceListButton*) existingComponentToUpdate)->update (rowNumber);
  121. return existingComponentToUpdate;
  122. }
  123. int ResourceEditorPanel::getColumnAutoSizeWidth (int columnId)
  124. {
  125. if (columnId == 4)
  126. return 0;
  127. Font f (13.0f);
  128. int widest = 40;
  129. for (int i = document.getResources().size(); --i >= 0;)
  130. {
  131. const BinaryResources::BinaryResource* const r = document.getResources() [i];
  132. jassert (r != nullptr);
  133. String text;
  134. if (columnId == 1)
  135. text = r->name;
  136. else if (columnId == 2)
  137. text = r->originalFilename;
  138. else if (columnId == 3)
  139. text = File::descriptionOfSizeInBytes ((int64) r->data.getSize());
  140. widest = jmax (widest, f.getStringWidth (text));
  141. }
  142. return widest + 10;
  143. }
  144. //==============================================================================
  145. class ResourceSorter
  146. {
  147. public:
  148. ResourceSorter (const int columnId_, const bool forwards)
  149. : columnId (columnId_),
  150. direction (forwards ? 1 : -1)
  151. {
  152. }
  153. int compareElements (BinaryResources::BinaryResource* first, BinaryResources::BinaryResource* second)
  154. {
  155. if (columnId == 1) return direction * first->name.compare (second->name);
  156. if (columnId == 2) return direction * first->originalFilename.compare (second->originalFilename);
  157. if (columnId == 3) return direction * (int) first->data.getSize() - (int) second->data.getSize();
  158. return 0;
  159. }
  160. private:
  161. const int columnId, direction;
  162. ResourceSorter (const ResourceSorter&);
  163. ResourceSorter& operator= (const ResourceSorter&);
  164. };
  165. void ResourceEditorPanel::sortOrderChanged (int newSortColumnId, const bool isForwards)
  166. {
  167. ResourceSorter sorter (newSortColumnId, isForwards);
  168. document.getResources().sort (sorter);
  169. }
  170. //==============================================================================
  171. void ResourceEditorPanel::selectedRowsChanged (int /*lastRowSelected*/)
  172. {
  173. delButton.setEnabled (listBox->getNumSelectedRows() > 0);
  174. }
  175. void ResourceEditorPanel::resized()
  176. {
  177. listBox->setBounds (6, 4, getWidth() - 12, getHeight() - 38);
  178. addButton.changeWidthToFitText (22);
  179. addButton.setTopLeftPosition (8, getHeight() - 30);
  180. reloadAllButton.changeWidthToFitText (22);
  181. reloadAllButton.setTopLeftPosition (addButton.getRight() + 10, getHeight() - 30);
  182. delButton.changeWidthToFitText (22);
  183. delButton.setTopRightPosition (getWidth() - 8, getHeight() - 30);
  184. }
  185. void ResourceEditorPanel::paint (Graphics& g)
  186. {
  187. g.fillAll (findColour (secondaryBackgroundColourId));
  188. }
  189. void ResourceEditorPanel::visibilityChanged()
  190. {
  191. if (isVisible())
  192. listBox->updateContent();
  193. }
  194. void ResourceEditorPanel::changeListenerCallback (ChangeBroadcaster*)
  195. {
  196. if (isVisible())
  197. listBox->updateContent();
  198. }
  199. void ResourceEditorPanel::buttonClicked (Button* b)
  200. {
  201. if (b == &addButton)
  202. {
  203. document.getResources()
  204. .browseForResource ("Select a file to add as a resource",
  205. "*",
  206. File(),
  207. String());
  208. }
  209. else if (b == &delButton)
  210. {
  211. document.getResources().remove (listBox->getSelectedRow (0));
  212. }
  213. else if (b == &reloadAllButton)
  214. {
  215. StringArray failed;
  216. for (int i = 0; i < document.getResources().size(); ++i)
  217. {
  218. if (! document.getResources().reload (i))
  219. failed.add (document.getResources().getResourceNames() [i]);
  220. }
  221. if (failed.size() > 0)
  222. {
  223. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  224. TRANS("Reloading resources"),
  225. TRANS("The following resources couldn't be reloaded from their original files:\n\n")
  226. + failed.joinIntoString (", "));
  227. }
  228. }
  229. }