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.

599 lines
21KB

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