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.

287 lines
9.1KB

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