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.

615 lines
22KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 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 "jucedemo_headers.h"
  19. #include "MainDemoWindow.h"
  20. //==============================================================================
  21. class ContentComp : public Component,
  22. public MenuBarModel,
  23. public ApplicationCommandTarget
  24. {
  25. public:
  26. //==============================================================================
  27. ContentComp (MainDemoWindow* mainWindow_)
  28. : mainWindow (mainWindow_),
  29. currentDemoId (0)
  30. {
  31. invokeDirectly (showRendering, true);
  32. }
  33. ~ContentComp()
  34. {
  35. }
  36. //==============================================================================
  37. void resized()
  38. {
  39. if (currentDemo != 0)
  40. currentDemo->setBounds (0, 0, getWidth(), getHeight());
  41. }
  42. //==============================================================================
  43. void showDemo (Component* demoComp)
  44. {
  45. currentDemo = demoComp;
  46. addAndMakeVisible (currentDemo);
  47. resized();
  48. }
  49. //==============================================================================
  50. const StringArray getMenuBarNames()
  51. {
  52. const char* const names[] = { "Demo", "Look-and-feel", 0 };
  53. return StringArray (names);
  54. }
  55. const PopupMenu getMenuForIndex (int menuIndex, const String& /*menuName*/)
  56. {
  57. ApplicationCommandManager* commandManager = &(mainWindow->commandManager);
  58. PopupMenu menu;
  59. if (menuIndex == 0)
  60. {
  61. menu.addCommandItem (commandManager, showRendering);
  62. menu.addCommandItem (commandManager, showFontsAndText);
  63. menu.addCommandItem (commandManager, showWidgets);
  64. menu.addCommandItem (commandManager, showThreading);
  65. menu.addCommandItem (commandManager, showTreeView);
  66. menu.addCommandItem (commandManager, showTable);
  67. menu.addCommandItem (commandManager, showAudio);
  68. menu.addCommandItem (commandManager, showDragAndDrop);
  69. menu.addCommandItem (commandManager, showOpenGL);
  70. menu.addCommandItem (commandManager, showQuicktime);
  71. menu.addCommandItem (commandManager, showDirectShow);
  72. menu.addCommandItem (commandManager, showInterprocessComms);
  73. menu.addCommandItem (commandManager, showCamera);
  74. menu.addCommandItem (commandManager, showWebBrowser);
  75. menu.addCommandItem (commandManager, showCodeEditor);
  76. menu.addSeparator();
  77. menu.addCommandItem (commandManager, StandardApplicationCommandIDs::quit);
  78. }
  79. else if (menuIndex == 1)
  80. {
  81. menu.addCommandItem (commandManager, setDefaultLookAndFeel);
  82. menu.addCommandItem (commandManager, setOldSchoolLookAndFeel);
  83. menu.addSeparator();
  84. menu.addCommandItem (commandManager, useNativeTitleBar);
  85. #if JUCE_MAC
  86. menu.addCommandItem (commandManager, useNativeMenus);
  87. #endif
  88. #if ! JUCE_LINUX
  89. menu.addCommandItem (commandManager, goToKioskMode);
  90. #endif
  91. StringArray renderingEngines (getPeer()->getAvailableRenderingEngines());
  92. if (renderingEngines.size() > 1)
  93. {
  94. menu.addSeparator();
  95. for (int i = 0; i < renderingEngines.size(); ++i)
  96. menu.addItem (5001 + i, "Use " + renderingEngines[i], true,
  97. i == getPeer()->getCurrentRenderingEngine());
  98. }
  99. }
  100. return menu;
  101. }
  102. void menuItemSelected (int menuItemID, int /*topLevelMenuIndex*/)
  103. {
  104. // most of our menu items are invoked automatically as commands, but we can handle the
  105. // other special cases here..
  106. if (menuItemID >= 5001 && menuItemID < 5010)
  107. getPeer()->setCurrentRenderingEngine (menuItemID - 5001);
  108. }
  109. //==============================================================================
  110. // The following methods implement the ApplicationCommandTarget interface, allowing
  111. // this window to publish a set of actions it can perform, and which can be mapped
  112. // onto menus, keypresses, etc.
  113. ApplicationCommandTarget* getNextCommandTarget()
  114. {
  115. // this will return the next parent component that is an ApplicationCommandTarget (in this
  116. // case, there probably isn't one, but it's best to use this method in your own apps).
  117. return findFirstTargetParentComponent();
  118. }
  119. void getAllCommands (Array <CommandID>& commands)
  120. {
  121. // this returns the set of all commands that this target can perform..
  122. const CommandID ids[] = { showRendering,
  123. showFontsAndText,
  124. showWidgets,
  125. showThreading,
  126. showTreeView,
  127. showTable,
  128. showAudio,
  129. showDragAndDrop,
  130. showOpenGL,
  131. showQuicktime,
  132. showDirectShow,
  133. showCamera,
  134. showWebBrowser,
  135. showCodeEditor,
  136. showInterprocessComms,
  137. setDefaultLookAndFeel,
  138. setOldSchoolLookAndFeel,
  139. useNativeTitleBar
  140. #if JUCE_MAC
  141. , useNativeMenus
  142. #endif
  143. #if ! JUCE_LINUX
  144. , goToKioskMode
  145. #endif
  146. };
  147. commands.addArray (ids, numElementsInArray (ids));
  148. }
  149. // This method is used when something needs to find out the details about one of the commands
  150. // that this object can perform..
  151. void getCommandInfo (CommandID commandID, ApplicationCommandInfo& result)
  152. {
  153. const String generalCategory ("General");
  154. const String demosCategory ("Demos");
  155. switch (commandID)
  156. {
  157. case showRendering:
  158. result.setInfo ("Graphics Rendering", "Shows the graphics demo", demosCategory, 0);
  159. result.setTicked (currentDemoId == showRendering);
  160. result.addDefaultKeypress ('1', ModifierKeys::commandModifier);
  161. break;
  162. case showFontsAndText:
  163. result.setInfo ("Fonts and Text", "Shows the fonts & text demo", demosCategory, 0);
  164. result.setTicked (currentDemoId == showFontsAndText);
  165. result.addDefaultKeypress ('2', ModifierKeys::commandModifier);
  166. break;
  167. case showWidgets:
  168. result.setInfo ("Widgets", "Shows the widgets demo", demosCategory, 0);
  169. result.setTicked (currentDemoId == showWidgets);
  170. result.addDefaultKeypress ('3', ModifierKeys::commandModifier);
  171. break;
  172. case showThreading:
  173. result.setInfo ("Multithreading", "Shows the threading demo", demosCategory, 0);
  174. result.setTicked (currentDemoId == showThreading);
  175. result.addDefaultKeypress ('4', ModifierKeys::commandModifier);
  176. break;
  177. case showTreeView:
  178. result.setInfo ("Treeviews", "Shows the treeviews demo", demosCategory, 0);
  179. result.setTicked (currentDemoId == showTreeView);
  180. result.addDefaultKeypress ('5', ModifierKeys::commandModifier);
  181. break;
  182. case showTable:
  183. result.setInfo ("Table Components", "Shows the table component demo", demosCategory, 0);
  184. result.setTicked (currentDemoId == showTable);
  185. result.addDefaultKeypress ('6', ModifierKeys::commandModifier);
  186. break;
  187. case showAudio:
  188. result.setInfo ("Audio", "Shows the audio demo", demosCategory, 0);
  189. result.setTicked (currentDemoId == showAudio);
  190. result.addDefaultKeypress ('7', ModifierKeys::commandModifier);
  191. break;
  192. case showDragAndDrop:
  193. result.setInfo ("Drag-and-drop", "Shows the drag & drop demo", demosCategory, 0);
  194. result.setTicked (currentDemoId == showDragAndDrop);
  195. result.addDefaultKeypress ('8', ModifierKeys::commandModifier);
  196. break;
  197. case showOpenGL:
  198. result.setInfo ("OpenGL", "Shows the OpenGL demo", demosCategory, 0);
  199. result.addDefaultKeypress ('9', ModifierKeys::commandModifier);
  200. result.setTicked (currentDemoId == showOpenGL);
  201. #if ! JUCE_OPENGL
  202. result.setActive (false);
  203. #endif
  204. break;
  205. case showQuicktime:
  206. result.setInfo ("Quicktime", "Shows the Quicktime demo", demosCategory, 0);
  207. result.addDefaultKeypress ('b', ModifierKeys::commandModifier);
  208. result.setTicked (currentDemoId == showQuicktime);
  209. #if ! (JUCE_QUICKTIME && ! JUCE_LINUX)
  210. result.setActive (false);
  211. #endif
  212. break;
  213. case showDirectShow:
  214. result.setInfo ("DirectShow", "Shows the DirectShow demo", demosCategory, 0);
  215. result.addDefaultKeypress ('b', ModifierKeys::commandModifier);
  216. result.setTicked (currentDemoId == showDirectShow);
  217. #if ! JUCE_DIRECTSHOW
  218. result.setActive (false);
  219. #endif
  220. break;
  221. case showCamera:
  222. result.setInfo ("Camera Capture", "Shows the camera demo", demosCategory, 0);
  223. result.addDefaultKeypress ('c', ModifierKeys::commandModifier);
  224. result.setTicked (currentDemoId == showCamera);
  225. #if ! JUCE_USE_CAMERA
  226. result.setActive (false);
  227. #endif
  228. break;
  229. case showWebBrowser:
  230. result.setInfo ("Web Browser", "Shows the web browser demo", demosCategory, 0);
  231. result.addDefaultKeypress ('i', ModifierKeys::commandModifier);
  232. result.setTicked (currentDemoId == showWebBrowser);
  233. #if (! JUCE_WEB_BROWSER) || JUCE_LINUX
  234. result.setActive (false);
  235. #endif
  236. break;
  237. case showCodeEditor:
  238. result.setInfo ("Code Editor", "Shows the code editor demo", demosCategory, 0);
  239. result.addDefaultKeypress ('e', ModifierKeys::commandModifier);
  240. result.setTicked (currentDemoId == showCodeEditor);
  241. break;
  242. case showInterprocessComms:
  243. result.setInfo ("Interprocess Comms", "Shows the interprocess communications demo", demosCategory, 0);
  244. result.addDefaultKeypress ('0', ModifierKeys::commandModifier);
  245. result.setTicked (currentDemoId == showInterprocessComms);
  246. break;
  247. case setDefaultLookAndFeel:
  248. result.setInfo ("Use default look-and-feel", String::empty, generalCategory, 0);
  249. result.setTicked (dynamic_cast <OldSchoolLookAndFeel*> (&getLookAndFeel()) == 0);
  250. break;
  251. case setOldSchoolLookAndFeel:
  252. result.setInfo ("Use the old, original juce look-and-feel", String::empty, generalCategory, 0);
  253. result.setTicked (dynamic_cast <OldSchoolLookAndFeel*> (&getLookAndFeel()) != 0);
  254. break;
  255. case useNativeTitleBar:
  256. result.setInfo ("Use native window title bar", String::empty, generalCategory, 0);
  257. result.setTicked (mainWindow->isUsingNativeTitleBar());
  258. break;
  259. #if JUCE_MAC
  260. case useNativeMenus:
  261. result.setInfo ("Use the native OSX menu bar", String::empty, generalCategory, 0);
  262. result.setTicked (MenuBarModel::getMacMainMenu() != 0);
  263. break;
  264. #endif
  265. #if ! JUCE_LINUX
  266. case goToKioskMode:
  267. result.setInfo ("Show full-screen kiosk mode", String::empty, generalCategory, 0);
  268. result.setTicked (Desktop::getInstance().getKioskModeComponent() != 0);
  269. break;
  270. #endif
  271. default:
  272. break;
  273. };
  274. }
  275. // this is the ApplicationCommandTarget method that is used to actually perform one of our commands..
  276. bool perform (const InvocationInfo& info)
  277. {
  278. switch (info.commandID)
  279. {
  280. case showRendering:
  281. showDemo (createRenderingDemo());
  282. currentDemoId = showRendering;
  283. break;
  284. case showFontsAndText:
  285. showDemo (createFontsAndTextDemo());
  286. currentDemoId = showFontsAndText;
  287. break;
  288. case showWidgets:
  289. showDemo (createWidgetsDemo());
  290. currentDemoId = showWidgets;
  291. break;
  292. case showThreading:
  293. showDemo (createThreadingDemo());
  294. currentDemoId = showThreading;
  295. break;
  296. case showTreeView:
  297. showDemo (createTreeViewDemo());
  298. currentDemoId = showTreeView;
  299. break;
  300. case showTable:
  301. showDemo (createTableDemo());
  302. currentDemoId = showTable;
  303. break;
  304. case showAudio:
  305. showDemo (createAudioDemo());
  306. currentDemoId = showAudio;
  307. break;
  308. case showDragAndDrop:
  309. showDemo (createDragAndDropDemo());
  310. currentDemoId = showDragAndDrop;
  311. break;
  312. case showOpenGL:
  313. #if JUCE_OPENGL
  314. showDemo (createOpenGLDemo());
  315. currentDemoId = showOpenGL;
  316. #endif
  317. break;
  318. case showQuicktime:
  319. #if JUCE_QUICKTIME && ! JUCE_LINUX
  320. showDemo (createQuickTimeDemo());
  321. currentDemoId = showQuicktime;
  322. #endif
  323. break;
  324. case showDirectShow:
  325. #if JUCE_DIRECTSHOW
  326. showDemo (createDirectShowDemo());
  327. currentDemoId = showDirectShow;
  328. #endif
  329. break;
  330. case showCamera:
  331. #if JUCE_USE_CAMERA
  332. showDemo (createCameraDemo());
  333. currentDemoId = showCamera;
  334. #endif
  335. break;
  336. case showWebBrowser:
  337. #if JUCE_WEB_BROWSER
  338. showDemo (createWebBrowserDemo());
  339. currentDemoId = showWebBrowser;
  340. #endif
  341. break;
  342. case showCodeEditor:
  343. showDemo (createCodeEditorDemo());
  344. currentDemoId = showCodeEditor;
  345. break;
  346. case showInterprocessComms:
  347. showDemo (createInterprocessCommsDemo());
  348. currentDemoId = showInterprocessComms;
  349. break;
  350. case setDefaultLookAndFeel:
  351. LookAndFeel::setDefaultLookAndFeel (nullptr);
  352. break;
  353. case setOldSchoolLookAndFeel:
  354. LookAndFeel::setDefaultLookAndFeel (&oldLookAndFeel);
  355. break;
  356. case useNativeTitleBar:
  357. mainWindow->setUsingNativeTitleBar (! mainWindow->isUsingNativeTitleBar());
  358. break;
  359. #if JUCE_MAC
  360. case useNativeMenus:
  361. if (MenuBarModel::getMacMainMenu() != 0)
  362. {
  363. MenuBarModel::setMacMainMenu (0);
  364. mainWindow->setMenuBar ((ContentComp*) mainWindow->getContentComponent());
  365. }
  366. else
  367. {
  368. MenuBarModel::setMacMainMenu ((ContentComp*) mainWindow->getContentComponent());
  369. mainWindow->setMenuBar (0);
  370. }
  371. break;
  372. #endif
  373. #if ! JUCE_LINUX
  374. case goToKioskMode:
  375. if (Desktop::getInstance().getKioskModeComponent() == 0)
  376. {
  377. Desktop::getInstance().setKioskModeComponent (getTopLevelComponent());
  378. }
  379. else
  380. {
  381. Desktop::getInstance().setKioskModeComponent (0);
  382. }
  383. break;
  384. #endif
  385. default:
  386. return false;
  387. };
  388. return true;
  389. }
  390. private:
  391. //==============================================================================
  392. MainDemoWindow* mainWindow;
  393. OldSchoolLookAndFeel oldLookAndFeel;
  394. ScopedPointer<Component> currentDemo;
  395. int currentDemoId;
  396. TooltipWindow tooltipWindow; // to add tooltips to an application, you
  397. // just need to create one of these and leave it
  398. // there to do its work..
  399. enum CommandIDs
  400. {
  401. showRendering = 0x2000,
  402. showFontsAndText = 0x2001,
  403. showWidgets = 0x2002,
  404. showThreading = 0x2003,
  405. showTreeView = 0x2004,
  406. showAudio = 0x2005,
  407. showDragAndDrop = 0x2006,
  408. showOpenGL = 0x2007,
  409. showQuicktime = 0x2008,
  410. showInterprocessComms = 0x2009,
  411. showTable = 0x2010,
  412. showCamera = 0x2011,
  413. showWebBrowser = 0x2012,
  414. showCodeEditor = 0x2013,
  415. showDirectShow = 0x2014,
  416. setDefaultLookAndFeel = 0x200b,
  417. setOldSchoolLookAndFeel = 0x200c,
  418. useNativeTitleBar = 0x200d,
  419. useNativeMenus = 0x200e,
  420. goToKioskMode = 0x200f
  421. };
  422. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ContentComp);
  423. };
  424. //==============================================================================
  425. #if JUCE_WINDOWS || JUCE_LINUX
  426. // Just add a simple icon to the Window system tray area..
  427. class DemoTaskbarComponent : public SystemTrayIconComponent
  428. {
  429. public:
  430. DemoTaskbarComponent()
  431. {
  432. // Create an icon which is just a square with a "j" in it..
  433. Image icon (Image::RGB, 32, 32, true);
  434. Graphics g (icon);
  435. g.fillAll (Colours::lightblue);
  436. g.setColour (Colours::black);
  437. g.setFont ((float) icon.getHeight(), Font::bold);
  438. g.drawText ("j", 0, 0, icon.getWidth(), icon.getHeight(), Justification::centred, false);
  439. setIconImage (icon);
  440. setIconTooltip ("Juce Demo App!");
  441. }
  442. ~DemoTaskbarComponent()
  443. {
  444. }
  445. void mouseDown (const MouseEvent&)
  446. {
  447. PopupMenu m;
  448. m.addItem (1, "Quit the Juce demo");
  449. const int result = m.show();
  450. if (result == 1)
  451. JUCEApplication::getInstance()->systemRequestedQuit();
  452. }
  453. };
  454. #endif
  455. //==============================================================================
  456. MainDemoWindow::MainDemoWindow()
  457. : DocumentWindow ("JUCE Demo!",
  458. Colours::azure,
  459. DocumentWindow::allButtons,
  460. true)
  461. {
  462. setResizable (true, false); // resizability is a property of ResizableWindow
  463. setResizeLimits (400, 300, 8192, 8192);
  464. ContentComp* contentComp = new ContentComp (this);
  465. commandManager.registerAllCommandsForTarget (contentComp);
  466. commandManager.registerAllCommandsForTarget (JUCEApplication::getInstance());
  467. // this lets the command manager use keypresses that arrive in our window to send
  468. // out commands
  469. addKeyListener (commandManager.getKeyMappings());
  470. // sets the main content component for the window to be this tabbed
  471. // panel. This will be deleted when the window is deleted.
  472. setContentOwned (contentComp, false);
  473. // this tells the DocumentWindow to automatically create and manage a MenuBarComponent
  474. // which uses our contentComp as its MenuBarModel
  475. setMenuBar (contentComp);
  476. // tells our menu bar model that it should watch this command manager for
  477. // changes, and send change messages accordingly.
  478. contentComp->setApplicationCommandManagerToWatch (&commandManager);
  479. setVisible (true);
  480. #if JUCE_WINDOWS || JUCE_LINUX
  481. taskbarIcon = new DemoTaskbarComponent();
  482. #endif
  483. }
  484. MainDemoWindow::~MainDemoWindow()
  485. {
  486. // because we've set the content comp to be used as our menu bar model, we
  487. // have to switch this off before deleting the content comp..
  488. setMenuBar (0);
  489. #if JUCE_MAC // ..and also the main bar if we're using that on a Mac...
  490. MenuBarModel::setMacMainMenu (0);
  491. #endif
  492. // clearing the content component will delete the current one, and
  493. // that will in turn delete all its child components. You don't always
  494. // have to do this explicitly, because the base class's destructor will
  495. // also delete the content component, but in this case we need to
  496. // make sure our content comp has gone away before deleting our command
  497. // manager.
  498. clearContentComponent();
  499. }
  500. void MainDemoWindow::closeButtonPressed()
  501. {
  502. // The correct thing to do when you want the app to quit is to call the
  503. // JUCEApplication::systemRequestedQuit() method.
  504. // That means that requests to quit that come from your own UI, or from other
  505. // OS-specific sources (e.g. the dock menu on the mac) all get handled in the
  506. // same way.
  507. JUCEApplication::getInstance()->systemRequestedQuit();
  508. }