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.

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