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.

254 lines
9.3KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-12 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 "../JuceDemoHeader.h"
  19. #if JUCE_QUICKTIME || JUCE_DIRECTSHOW
  20. //==============================================================================
  21. // so that we can easily have two video windows each with a file browser, wrap this up as a class..
  22. class MovieComponentWithFileBrowser : public Component,
  23. public DragAndDropTarget,
  24. private FilenameComponentListener
  25. {
  26. public:
  27. MovieComponentWithFileBrowser()
  28. : isDragOver (false),
  29. fileChooser ("movie", File::nonexistent, true, false, false,
  30. "*", String::empty, "(choose a video file to play)")
  31. {
  32. addAndMakeVisible (&videoComp);
  33. addAndMakeVisible (&fileChooser);
  34. fileChooser.addListener (this);
  35. fileChooser.setBrowseButtonText ("browse");
  36. }
  37. void setFile (const File& file)
  38. {
  39. fileChooser.setCurrentFile (file, true);
  40. }
  41. void paintOverChildren (Graphics& g)
  42. {
  43. if (isDragOver)
  44. {
  45. g.setColour (Colours::red);
  46. g.drawRect (fileChooser.getBounds(), 2);
  47. }
  48. }
  49. void resized()
  50. {
  51. videoComp.setBoundsWithCorrectAspectRatio (Rectangle<int> (0, 0, getWidth(), getHeight() - 30),
  52. Justification::centred);
  53. fileChooser.setBounds (0, getHeight() - 24, getWidth(), 24);
  54. }
  55. bool isInterestedInDragSource (const SourceDetails&) { return true; }
  56. void itemDragEnter (const SourceDetails&)
  57. {
  58. isDragOver = true;
  59. repaint();
  60. }
  61. void itemDragExit (const SourceDetails&)
  62. {
  63. isDragOver = false;
  64. repaint();
  65. }
  66. void itemDropped (const SourceDetails& dragSourceDetails)
  67. {
  68. setFile (dragSourceDetails.description.toString());
  69. isDragOver = false;
  70. repaint();
  71. }
  72. private:
  73. #if JUCE_QUICKTIME
  74. QuickTimeMovieComponent videoComp;
  75. #elif JUCE_DIRECTSHOW
  76. DirectShowComponent videoComp;
  77. #endif
  78. bool isDragOver;
  79. FilenameComponent fileChooser;
  80. void filenameComponentChanged (FilenameComponent*) override
  81. {
  82. // this is called when the user changes the filename in the file chooser box
  83. #if JUCE_QUICKTIME
  84. if (videoComp.loadMovie (fileChooser.getCurrentFile(), true))
  85. #elif JUCE_DIRECTSHOW
  86. if (videoComp.loadMovie (fileChooser.getCurrentFile()))
  87. #endif
  88. {
  89. // loaded the file ok, so let's start it playing..
  90. videoComp.play();
  91. resized(); // update to reflect the video's aspect ratio
  92. }
  93. else
  94. {
  95. AlertWindow::showMessageBox (AlertWindow::WarningIcon,
  96. "Couldn't load the file!",
  97. #if JUCE_QUICKTIME
  98. "Sorry, QuickTime didn't manage to load that file!");
  99. #elif JUCE_DIRECTSHOW
  100. "Sorry, DirectShow didn't manage to load that file!");
  101. #endif
  102. }
  103. }
  104. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MovieComponentWithFileBrowser)
  105. };
  106. //==============================================================================
  107. class VideoDemo : public Component,
  108. public DragAndDropContainer,
  109. private Button::Listener,
  110. private FileBrowserListener
  111. {
  112. public:
  113. VideoDemo()
  114. : moviesWildcardFilter ("*", "*", "Movies File Filter"),
  115. directoryThread ("Movie File Scanner Thread"),
  116. movieList (&moviesWildcardFilter, directoryThread),
  117. fileTree (movieList),
  118. resizerBar (&stretchableManager, 1, false)
  119. {
  120. setOpaque (true);
  121. movieList.setDirectory (File::getSpecialLocation (File::userMoviesDirectory), true, true);
  122. directoryThread.startThread (1);
  123. fileTree.addListener (this);
  124. fileTree.setColour (TreeView::backgroundColourId, Colours::lightgrey);
  125. addAndMakeVisible (&fileTree);
  126. addAndMakeVisible (&resizerBar);
  127. loadLeftButton.setButtonText ("Load Left");
  128. loadRightButton.setButtonText ("Load Right");
  129. loadLeftButton.addListener (this);
  130. loadRightButton.addListener (this);
  131. addAndMakeVisible (&loadLeftButton);
  132. addAndMakeVisible (&loadRightButton);
  133. addAndMakeVisible (&movieCompLeft);
  134. addAndMakeVisible (&movieCompRight);
  135. // we have to set up our StretchableLayoutManager so it know the limits and preferred sizes of it's contents
  136. stretchableManager.setItemLayout (0, // for the fileTree
  137. -0.1, -0.9, // must be between 50 pixels and 90% of the available space
  138. -0.3); // and its preferred size is 30% of the total available space
  139. stretchableManager.setItemLayout (1, // for the resize bar
  140. 5, 5, 5); // hard limit to 5 pixels
  141. stretchableManager.setItemLayout (2, // for the movie components
  142. -0.1, -0.9, // size must be between 50 pixels and 90% of the available space
  143. -0.7); // and its preferred size is 70% of the total available space
  144. }
  145. ~VideoDemo()
  146. {
  147. loadLeftButton.removeListener (this);
  148. loadRightButton.removeListener (this);
  149. fileTree.removeListener (this);
  150. }
  151. void paint (Graphics& g) override
  152. {
  153. fillBrushedAluminiumBackground (g);
  154. }
  155. void resized() override
  156. {
  157. // make a list of two of our child components that we want to reposition
  158. Component* comps[] = { &fileTree, &resizerBar, nullptr };
  159. // this will position the 3 components, one above the other, to fit
  160. // vertically into the rectangle provided.
  161. stretchableManager.layOutComponents (comps, 3,
  162. 0, 0, getWidth(), getHeight(),
  163. true, true);
  164. // now position out two video components in the space that's left
  165. Rectangle<int> area (getLocalBounds().removeFromBottom (getHeight() - resizerBar.getBottom()));
  166. {
  167. Rectangle<int> buttonArea (area.removeFromTop (30));
  168. loadLeftButton.setBounds (buttonArea.removeFromLeft (buttonArea.getWidth() / 2).reduced (5));
  169. loadRightButton.setBounds (buttonArea.reduced (5));
  170. }
  171. movieCompLeft.setBounds (area.removeFromLeft (area.getWidth() / 2).reduced (5));
  172. movieCompRight.setBounds (area.reduced (5));
  173. }
  174. private:
  175. WildcardFileFilter moviesWildcardFilter;
  176. TimeSliceThread directoryThread;
  177. DirectoryContentsList movieList;
  178. FileTreeComponent fileTree;
  179. StretchableLayoutManager stretchableManager;
  180. StretchableLayoutResizerBar resizerBar;
  181. TextButton loadLeftButton, loadRightButton;
  182. MovieComponentWithFileBrowser movieCompLeft, movieCompRight;
  183. void buttonClicked (Button* button) override
  184. {
  185. if (button == &loadLeftButton)
  186. movieCompLeft.setFile (fileTree.getSelectedFile (0));
  187. else if (button == &loadRightButton)
  188. movieCompRight.setFile (fileTree.getSelectedFile (0));
  189. }
  190. void selectionChanged() override
  191. {
  192. // we're just going to update the drag description of out tree so that rows can be dragged onto the file players
  193. fileTree.setDragAndDropDescription (fileTree.getSelectedFile().getFullPathName());
  194. }
  195. void fileClicked (const File&, const MouseEvent&) override {}
  196. void fileDoubleClicked (const File&) override {}
  197. void browserRootChanged (const File&) override {}
  198. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VideoDemo)
  199. };
  200. // This static object will register this demo type in a global list of demos..
  201. static JuceDemoType<VideoDemo> demo ("29 Graphics: Video Playback");
  202. #endif