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.

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