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.

160 lines
5.4KB

  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. //==============================================================================
  20. class JavaScriptDemo : public Component,
  21. private CodeDocument::Listener,
  22. private Timer
  23. {
  24. public:
  25. JavaScriptDemo()
  26. {
  27. setOpaque (true);
  28. addAndMakeVisible (editor = new CodeEditorComponent (codeDocument, nullptr));
  29. editor->setFont (Font (Font::getDefaultMonospacedFontName(), 14.0f, Font::plain));
  30. editor->setTabSize (4, true);
  31. outputDisplay.setMultiLine (true);
  32. outputDisplay.setReadOnly (true);
  33. outputDisplay.setCaretVisible (false);
  34. outputDisplay.setFont (Font (Font::getDefaultMonospacedFontName(), 14.0f, Font::plain));
  35. addAndMakeVisible (outputDisplay);
  36. codeDocument.addListener (this);
  37. editor->loadContent (
  38. "/*\n"
  39. " Javascript! In this simple demo, the native\n"
  40. " code provides an object called \'Demo\' which\n"
  41. " has a method \'print\' that writes to the\n"
  42. " console below...\n"
  43. "*/\n"
  44. "\n"
  45. "Demo.print (\"Hello World in JUCE + Javascript!\");\n"
  46. "Demo.print (\"\");\n"
  47. "\n"
  48. "function factorial (n)\n"
  49. "{\n"
  50. " var total = 1;\n"
  51. " while (n > 0)\n"
  52. " total = total * n--;\n"
  53. " return total;\n"
  54. "}\n"
  55. "\n"
  56. "for (var i = 1; i < 10; ++i)\n"
  57. " Demo.print (\"Factorial of \" + i \n"
  58. " + \" = \" + factorial (i));\n");
  59. }
  60. void runScript()
  61. {
  62. outputDisplay.clear();
  63. JavascriptEngine engine;
  64. engine.maximumExecutionTime = RelativeTime::seconds (5);
  65. engine.registerNativeObject ("Demo", new DemoClass (*this));
  66. const double startTime = Time::getMillisecondCounterHiRes();
  67. Result result = engine.execute (codeDocument.getAllContent());
  68. const double elapsedMs = Time::getMillisecondCounterHiRes() - startTime;
  69. if (result.failed())
  70. outputDisplay.setText (result.getErrorMessage());
  71. else
  72. outputDisplay.insertTextAtCaret ("\n(Execution time: " + String (elapsedMs, 2) + " milliseconds)");
  73. }
  74. void consoleOutput (const String& message)
  75. {
  76. outputDisplay.moveCaretToEnd();
  77. outputDisplay.insertTextAtCaret (message + newLine);
  78. }
  79. //==============================================================================
  80. // This class is used by the script, and provides methods that the JS can call.
  81. struct DemoClass : public DynamicObject
  82. {
  83. DemoClass (JavaScriptDemo& demo) : owner (demo)
  84. {
  85. setMethod ("print", print);
  86. }
  87. static Identifier getClassName() { return "Demo"; }
  88. static var print (const var::NativeFunctionArgs& args)
  89. {
  90. if (args.numArguments > 0)
  91. if (DemoClass* thisObject = dynamic_cast<DemoClass*> (args.thisObject.getObject()))
  92. thisObject->owner.consoleOutput (args.arguments[0].toString());
  93. return var::undefined();
  94. }
  95. JavaScriptDemo& owner;
  96. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DemoClass)
  97. };
  98. void paint (Graphics& g)
  99. {
  100. fillTiledBackground (g);
  101. }
  102. private:
  103. CodeDocument codeDocument;
  104. ScopedPointer<CodeEditorComponent> editor;
  105. TextEditor outputDisplay;
  106. void codeDocumentTextInserted (const String&, int) override { startTimer (300); }
  107. void codeDocumentTextDeleted (int, int) override { startTimer (300); }
  108. void timerCallback() override
  109. {
  110. stopTimer();
  111. runScript();
  112. }
  113. void resized() override
  114. {
  115. Rectangle<int> r (getLocalBounds().reduced (8));
  116. editor->setBounds (r.removeFromTop (proportionOfHeight (0.6f)));
  117. outputDisplay.setBounds (r.withTrimmedTop (8));
  118. }
  119. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JavaScriptDemo)
  120. };
  121. // This static object will register this demo type in a global list of demos..
  122. static JuceDemoType<JavaScriptDemo> demo ("40 JavaScript");