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.

671 lines
18KB

  1. --- ../Rack/src/app/MenuBar.cpp 2022-01-15 14:44:46.391280963 +0000
  2. +++ MenuBar.cpp 2022-01-24 11:25:15.507061204 +0000
  3. @@ -1,8 +1,33 @@
  4. +/*
  5. + * DISTRHO Cardinal Plugin
  6. + * Copyright (C) 2021-2022 Filipe Coelho <falktx@falktx.com>
  7. + *
  8. + * This program is free software; you can redistribute it and/or
  9. + * modify it under the terms of the GNU General Public License as
  10. + * published by the Free Software Foundation; either version 3 of
  11. + * the License, or any later version.
  12. + *
  13. + * This program is distributed in the hope that it will be useful,
  14. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. + * GNU General Public License for more details.
  17. + *
  18. + * For a full copy of the GNU General Public License see the LICENSE file.
  19. + */
  20. +
  21. +/**
  22. + * This file is an edited version of VCVRack's app/MenuBar.cpp
  23. + * Copyright (C) 2016-2021 VCV.
  24. + *
  25. + * This program is free software: you can redistribute it and/or
  26. + * modify it under the terms of the GNU General Public License as
  27. + * published by the Free Software Foundation; either version 3 of
  28. + * the License, or (at your option) any later version.
  29. + */
  30. +
  31. #include <thread>
  32. #include <utility>
  33. -#include <osdialog.h>
  34. -
  35. #include <app/MenuBar.hpp>
  36. #include <app/TipWindow.hpp>
  37. #include <widget/OpaqueWidget.hpp>
  38. @@ -25,6 +50,11 @@
  39. #include <patch.hpp>
  40. #include <library.hpp>
  41. +#ifdef HAVE_LIBLO
  42. +# include <lo/lo.h>
  43. +#endif
  44. +
  45. +#include "../CardinalCommon.hpp"
  46. namespace rack {
  47. namespace app {
  48. @@ -48,79 +78,75 @@
  49. };
  50. -struct NotificationIcon : widget::Widget {
  51. - void draw(const DrawArgs& args) override {
  52. - nvgBeginPath(args.vg);
  53. - float radius = 4;
  54. - nvgCircle(args.vg, radius, radius, radius);
  55. - nvgFillColor(args.vg, nvgRGBf(1.0, 0.0, 0.0));
  56. - nvgFill(args.vg);
  57. - nvgStrokeColor(args.vg, nvgRGBf(0.5, 0.0, 0.0));
  58. - nvgStroke(args.vg);
  59. - }
  60. -};
  61. -
  62. -
  63. ////////////////////
  64. // File
  65. ////////////////////
  66. struct FileButton : MenuButton {
  67. + const bool isStandalone;
  68. +
  69. + FileButton(const bool standalone)
  70. + : MenuButton(), isStandalone(standalone) {}
  71. +
  72. void onAction(const ActionEvent& e) override {
  73. ui::Menu* menu = createMenu();
  74. menu->cornerFlags = BND_CORNER_TOP;
  75. menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
  76. menu->addChild(createMenuItem("New", RACK_MOD_CTRL_NAME "+N", []() {
  77. - APP->patch->loadTemplateDialog();
  78. + patchUtils::loadTemplateDialog();
  79. }));
  80. - menu->addChild(createMenuItem("Open", RACK_MOD_CTRL_NAME "+O", []() {
  81. - APP->patch->loadDialog();
  82. + menu->addChild(createMenuItem("Open / Import...", RACK_MOD_CTRL_NAME "+O", []() {
  83. + patchUtils::loadDialog();
  84. }));
  85. - menu->addChild(createSubmenuItem("Open recent", "", [](ui::Menu* menu) {
  86. - for (const std::string& path : settings::recentPatchPaths) {
  87. - std::string name = system::getStem(path);
  88. - menu->addChild(createMenuItem(name, "", [=]() {
  89. - APP->patch->loadPathDialog(path);
  90. - }));
  91. - }
  92. - }, settings::recentPatchPaths.empty()));
  93. -
  94. menu->addChild(createMenuItem("Save", RACK_MOD_CTRL_NAME "+S", []() {
  95. - APP->patch->saveDialog();
  96. + // NOTE: will do nothing if path is empty, intentionally
  97. + patchUtils::saveDialog(APP->patch->path);
  98. + }, APP->patch->path.empty()));
  99. +
  100. + menu->addChild(createMenuItem("Save as / Export...", RACK_MOD_CTRL_NAME "+Shift+S", []() {
  101. + patchUtils::saveAsDialog();
  102. }));
  103. - menu->addChild(createMenuItem("Save as", RACK_MOD_CTRL_NAME "+Shift+S", []() {
  104. - APP->patch->saveAsDialog();
  105. - }));
  106. +#ifdef HAVE_LIBLO
  107. + if (patchUtils::isRemoteConnected()) {
  108. + menu->addChild(createMenuItem("Deploy to MOD", "F7", []() {
  109. + patchUtils::deployToRemote();
  110. + }));
  111. - menu->addChild(createMenuItem("Save a copy", "", []() {
  112. - APP->patch->saveAsDialog(false);
  113. - }));
  114. + const bool autoDeploy = patchUtils::isRemoteAutoDeployed();
  115. + menu->addChild(createCheckMenuItem("Auto deploy to MOD", "",
  116. + [=]() {return autoDeploy;},
  117. + [=]() {patchUtils::setRemoteAutoDeploy(!autoDeploy);}
  118. + ));
  119. + } else {
  120. + menu->addChild(createMenuItem("Connect to MOD", "", [this]() {
  121. + patchUtils::connectToRemote();
  122. + }));
  123. + }
  124. +#endif
  125. menu->addChild(createMenuItem("Revert", RACK_MOD_CTRL_NAME "+" RACK_MOD_SHIFT_NAME "+O", []() {
  126. - APP->patch->revertDialog();
  127. - }, APP->patch->path == ""));
  128. -
  129. - menu->addChild(createMenuItem("Overwrite template", "", []() {
  130. - APP->patch->saveTemplateDialog();
  131. - }));
  132. + patchUtils::revertDialog();
  133. + }, APP->patch->path.empty()));
  134. menu->addChild(new ui::MenuSeparator);
  135. // Load selection
  136. menu->addChild(createMenuItem("Import selection", "", [=]() {
  137. - APP->scene->rack->loadSelectionDialog();
  138. + patchUtils::loadSelectionDialog();
  139. }, false, true));
  140. - menu->addChild(new ui::MenuSeparator);
  141. + if (isStandalone) {
  142. + menu->addChild(new ui::MenuSeparator);
  143. - menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() {
  144. - APP->window->close();
  145. - }));
  146. + menu->addChild(createMenuItem("Quit", RACK_MOD_CTRL_NAME "+Q", []() {
  147. + APP->window->close();
  148. + }));
  149. + };
  150. }
  151. };
  152. @@ -166,7 +192,7 @@
  153. menu->addChild(new ui::MenuSeparator);
  154. - APP->scene->rack->appendSelectionContextMenu(menu);
  155. + patchUtils::appendSelectionContextMenu(menu);
  156. }
  157. };
  158. @@ -256,7 +282,7 @@
  159. return settings::cableTension;
  160. }
  161. float getDefaultValue() override {
  162. - return 0.5;
  163. + return 0.75;
  164. }
  165. float getDisplayValue() override {
  166. return getValue() * 100;
  167. @@ -421,28 +447,9 @@
  168. haloBrightnessSlider->box.size.x = 250.0;
  169. menu->addChild(haloBrightnessSlider);
  170. - double frameRate = APP->window->getMonitorRefreshRate() / settings::frameSwapInterval;
  171. - menu->addChild(createSubmenuItem("Frame rate", string::f("%.0f Hz", frameRate), [=](ui::Menu* menu) {
  172. - for (int i = 1; i <= 6; i++) {
  173. - double frameRate = APP->window->getMonitorRefreshRate() / i;
  174. - menu->addChild(createCheckMenuItem(string::f("%.0f Hz", frameRate), "",
  175. - [=]() {return settings::frameSwapInterval == i;},
  176. - [=]() {settings::frameSwapInterval = i;}
  177. - ));
  178. - }
  179. - }));
  180. -
  181. - bool fullscreen = APP->window->isFullScreen();
  182. - std::string fullscreenText = "F11";
  183. - if (fullscreen)
  184. - fullscreenText += " " CHECKMARK_STRING;
  185. - menu->addChild(createMenuItem("Fullscreen", fullscreenText, [=]() {
  186. - APP->window->setFullScreen(!fullscreen);
  187. - }));
  188. -
  189. menu->addChild(new ui::MenuSeparator);
  190. - menu->addChild(createBoolPtrMenuItem("Lock cursor while dragging params", "", &settings::allowCursorLock));
  191. + // menu->addChild(createBoolPtrMenuItem("Hide cursor while dragging", "", &settings::allowCursorLock));
  192. static const std::vector<std::string> knobModeLabels = {
  193. "Linear",
  194. @@ -467,6 +474,21 @@
  195. menu->addChild(knobScrollSensitivitySlider);
  196. menu->addChild(createBoolPtrMenuItem("Lock module positions", "", &settings::lockModules));
  197. +
  198. + static const std::vector<std::string> rateLimitLabels = {
  199. + "None",
  200. + "2x",
  201. + "4x",
  202. + };
  203. + static const std::vector<int> rateLimits = {0, 1, 2};
  204. + menu->addChild(createSubmenuItem("Update rate limit", rateLimitLabels[settings::rateLimit], [=](ui::Menu* menu) {
  205. + for (int rateLimit : rateLimits) {
  206. + menu->addChild(createCheckMenuItem(rateLimitLabels[rateLimit], "",
  207. + [=]() {return settings::rateLimit == rateLimit;},
  208. + [=]() {settings::rateLimit = rateLimit;}
  209. + ));
  210. + }
  211. + }));
  212. }
  213. };
  214. @@ -476,47 +498,6 @@
  215. ////////////////////
  216. -struct SampleRateItem : ui::MenuItem {
  217. - ui::Menu* createChildMenu() override {
  218. - ui::Menu* menu = new ui::Menu;
  219. -
  220. - // Auto sample rate
  221. - std::string rightText;
  222. - if (settings::sampleRate == 0) {
  223. - float sampleRate = APP->engine->getSampleRate();
  224. - rightText += string::f("(%g kHz) ", sampleRate / 1000.f);
  225. - }
  226. - menu->addChild(createCheckMenuItem("Auto", rightText,
  227. - [=]() {return settings::sampleRate == 0;},
  228. - [=]() {settings::sampleRate = 0;}
  229. - ));
  230. -
  231. - // Power-of-2 oversample times 44.1kHz or 48kHz
  232. - for (int i = -2; i <= 4; i++) {
  233. - for (int j = 0; j < 2; j++) {
  234. - float oversample = std::pow(2.f, i);
  235. - float sampleRate = (j == 0) ? 44100.f : 48000.f;
  236. - sampleRate *= oversample;
  237. -
  238. - std::string text = string::f("%g kHz", sampleRate / 1000.f);
  239. - std::string rightText;
  240. - if (oversample > 1.f) {
  241. - rightText += string::f("(%.0fx)", oversample);
  242. - }
  243. - else if (oversample < 1.f) {
  244. - rightText += string::f("(1/%.0fx)", 1.f / oversample);
  245. - }
  246. - menu->addChild(createCheckMenuItem(text, rightText,
  247. - [=]() {return settings::sampleRate == sampleRate;},
  248. - [=]() {settings::sampleRate = sampleRate;}
  249. - ));
  250. - }
  251. - }
  252. - return menu;
  253. - }
  254. -};
  255. -
  256. -
  257. struct EngineButton : MenuButton {
  258. void onAction(const ActionEvent& e) override {
  259. ui::Menu* menu = createMenu();
  260. @@ -529,269 +510,6 @@
  261. menu->addChild(createMenuItem("Performance meters", cpuMeterText, [=]() {
  262. settings::cpuMeter ^= true;
  263. }));
  264. -
  265. - menu->addChild(createMenuItem<SampleRateItem>("Sample rate", RIGHT_ARROW));
  266. -
  267. - menu->addChild(createSubmenuItem("Threads", string::f("%d", settings::threadCount), [=](ui::Menu* menu) {
  268. - // BUG This assumes SMT is enabled.
  269. - int cores = system::getLogicalCoreCount() / 2;
  270. -
  271. - for (int i = 1; i <= 2 * cores; i++) {
  272. - std::string rightText;
  273. - if (i == cores)
  274. - rightText += "(most modules)";
  275. - else if (i == 1)
  276. - rightText += "(lowest CPU usage)";
  277. - menu->addChild(createCheckMenuItem(string::f("%d", i), rightText,
  278. - [=]() {return settings::threadCount == i;},
  279. - [=]() {settings::threadCount = i;}
  280. - ));
  281. - }
  282. - }));
  283. - }
  284. -};
  285. -
  286. -
  287. -////////////////////
  288. -// Plugins
  289. -////////////////////
  290. -
  291. -
  292. -struct AccountPasswordField : ui::PasswordField {
  293. - ui::MenuItem* logInItem;
  294. - void onAction(const ActionEvent& e) override {
  295. - logInItem->doAction();
  296. - }
  297. -};
  298. -
  299. -
  300. -struct LogInItem : ui::MenuItem {
  301. - ui::TextField* emailField;
  302. - ui::TextField* passwordField;
  303. -
  304. - void onAction(const ActionEvent& e) override {
  305. - std::string email = emailField->text;
  306. - std::string password = passwordField->text;
  307. - std::thread t([=] {
  308. - library::logIn(email, password);
  309. - library::checkUpdates();
  310. - });
  311. - t.detach();
  312. - e.unconsume();
  313. - }
  314. -
  315. - void step() override {
  316. - text = "Log in";
  317. - rightText = library::loginStatus;
  318. - MenuItem::step();
  319. - }
  320. -};
  321. -
  322. -
  323. -struct SyncUpdatesItem : ui::MenuItem {
  324. - void step() override {
  325. - if (library::updateStatus != "") {
  326. - text = library::updateStatus;
  327. - }
  328. - else if (library::isSyncing) {
  329. - text = "Updating...";
  330. - }
  331. - else if (!library::hasUpdates()) {
  332. - text = "Up-to-date";
  333. - }
  334. - else {
  335. - text = "Update all";
  336. - }
  337. -
  338. - disabled = library::isSyncing || !library::hasUpdates();
  339. - MenuItem::step();
  340. - }
  341. -
  342. - void onAction(const ActionEvent& e) override {
  343. - std::thread t([=] {
  344. - library::syncUpdates();
  345. - });
  346. - t.detach();
  347. - e.unconsume();
  348. - }
  349. -};
  350. -
  351. -
  352. -struct SyncUpdateItem : ui::MenuItem {
  353. - std::string slug;
  354. -
  355. - void setUpdate(const std::string& slug) {
  356. - this->slug = slug;
  357. -
  358. - auto it = library::updateInfos.find(slug);
  359. - if (it == library::updateInfos.end())
  360. - return;
  361. - library::UpdateInfo update = it->second;
  362. -
  363. - text = update.name;
  364. - }
  365. -
  366. - ui::Menu* createChildMenu() override {
  367. - auto it = library::updateInfos.find(slug);
  368. - if (it == library::updateInfos.end())
  369. - return NULL;
  370. - library::UpdateInfo update = it->second;
  371. -
  372. - if (update.changelogUrl == "")
  373. - return NULL;
  374. -
  375. - ui::Menu* menu = new ui::Menu;
  376. -
  377. - std::string changelogUrl = update.changelogUrl;
  378. - menu->addChild(createMenuItem("Changelog", "", [=]() {
  379. - system::openBrowser(changelogUrl);
  380. - }));
  381. -
  382. - return menu;
  383. - }
  384. -
  385. - void step() override {
  386. - disabled = library::isSyncing;
  387. -
  388. - auto it = library::updateInfos.find(slug);
  389. - if (it != library::updateInfos.end()) {
  390. - library::UpdateInfo update = it->second;
  391. -
  392. - if (update.downloaded) {
  393. - rightText = CHECKMARK_STRING;
  394. - disabled = true;
  395. - }
  396. - else if (slug == library::updateSlug) {
  397. - rightText = string::f("%.0f%%", library::updateProgress * 100.f);
  398. - }
  399. - else {
  400. - rightText = "";
  401. - plugin::Plugin* p = plugin::getPlugin(slug);
  402. - if (p) {
  403. - rightText += p->version + " → ";
  404. - }
  405. - rightText += update.version;
  406. - }
  407. - }
  408. -
  409. - MenuItem::step();
  410. - }
  411. -
  412. - void onAction(const ActionEvent& e) override {
  413. - std::thread t([=] {
  414. - library::syncUpdate(slug);
  415. - });
  416. - t.detach();
  417. - e.unconsume();
  418. - }
  419. -};
  420. -
  421. -
  422. -struct LibraryMenu : ui::Menu {
  423. - LibraryMenu() {
  424. - refresh();
  425. - }
  426. -
  427. - void step() override {
  428. - // Refresh menu when appropriate
  429. - if (library::refreshRequested) {
  430. - library::refreshRequested = false;
  431. - refresh();
  432. - }
  433. - Menu::step();
  434. - }
  435. -
  436. - void refresh() {
  437. - setChildMenu(NULL);
  438. - clearChildren();
  439. -
  440. - if (settings::devMode) {
  441. - addChild(createMenuLabel("Disabled in development mode"));
  442. - }
  443. - else if (!library::isLoggedIn()) {
  444. - addChild(createMenuItem("Register VCV account", "", [=]() {
  445. - system::openBrowser("https://vcvrack.com/login");
  446. - }));
  447. -
  448. - ui::TextField* emailField = new ui::TextField;
  449. - emailField->placeholder = "Email";
  450. - emailField->box.size.x = 240.0;
  451. - addChild(emailField);
  452. -
  453. - AccountPasswordField* passwordField = new AccountPasswordField;
  454. - passwordField->placeholder = "Password";
  455. - passwordField->box.size.x = 240.0;
  456. - passwordField->nextField = emailField;
  457. - emailField->nextField = passwordField;
  458. - addChild(passwordField);
  459. -
  460. - LogInItem* logInItem = new LogInItem;
  461. - logInItem->emailField = emailField;
  462. - logInItem->passwordField = passwordField;
  463. - passwordField->logInItem = logInItem;
  464. - addChild(logInItem);
  465. - }
  466. - else {
  467. - addChild(createMenuItem("Log out", "", [=]() {
  468. - library::logOut();
  469. - }));
  470. -
  471. - addChild(createMenuItem("Browse VCV Library", "", [=]() {
  472. - system::openBrowser("https://library.vcvrack.com/");
  473. - }));
  474. -
  475. - SyncUpdatesItem* syncItem = new SyncUpdatesItem;
  476. - syncItem->text = "Update all";
  477. - addChild(syncItem);
  478. -
  479. - if (!library::updateInfos.empty()) {
  480. - addChild(new ui::MenuSeparator);
  481. - addChild(createMenuLabel("Updates"));
  482. -
  483. - for (auto& pair : library::updateInfos) {
  484. - SyncUpdateItem* updateItem = new SyncUpdateItem;
  485. - updateItem->setUpdate(pair.first);
  486. - addChild(updateItem);
  487. - }
  488. - }
  489. - }
  490. - }
  491. -};
  492. -
  493. -
  494. -struct LibraryButton : MenuButton {
  495. - NotificationIcon* notification;
  496. -
  497. - LibraryButton() {
  498. - notification = new NotificationIcon;
  499. - addChild(notification);
  500. - }
  501. -
  502. - void onAction(const ActionEvent& e) override {
  503. - ui::Menu* menu = createMenu<LibraryMenu>();
  504. - menu->cornerFlags = BND_CORNER_TOP;
  505. - menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
  506. - // Check for updates when menu is opened
  507. - std::thread t([&]() {
  508. - system::setThreadName("Library");
  509. - library::checkUpdates();
  510. - });
  511. - t.detach();
  512. - }
  513. -
  514. - void step() override {
  515. - notification->box.pos = math::Vec(0, 0);
  516. - notification->visible = library::hasUpdates();
  517. -
  518. - // Popup when updates finish downloading
  519. - if (library::restartRequested) {
  520. - library::restartRequested = false;
  521. - if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been downloaded. Close and re-launch Rack to load new updates.")) {
  522. - APP->window->close();
  523. - }
  524. - }
  525. -
  526. - MenuButton::step();
  527. }
  528. };
  529. @@ -802,63 +520,24 @@
  530. struct HelpButton : MenuButton {
  531. - NotificationIcon* notification;
  532. -
  533. - HelpButton() {
  534. - notification = new NotificationIcon;
  535. - addChild(notification);
  536. - }
  537. -
  538. void onAction(const ActionEvent& e) override {
  539. ui::Menu* menu = createMenu();
  540. menu->cornerFlags = BND_CORNER_TOP;
  541. menu->box.pos = getAbsoluteOffset(math::Vec(0, box.size.y));
  542. - menu->addChild(createMenuItem("Tips", "", [=]() {
  543. - APP->scene->addChild(tipWindowCreate());
  544. - }));
  545. -
  546. - menu->addChild(createMenuItem("User manual", "F1", [=]() {
  547. + menu->addChild(createMenuItem("Rack User manual", "F1", [=]() {
  548. system::openBrowser("https://vcvrack.com/manual/");
  549. }));
  550. - menu->addChild(createMenuItem("VCVRack.com", "", [=]() {
  551. - system::openBrowser("https://vcvrack.com/");
  552. + menu->addChild(createMenuItem("Cardinal Project page", "", [=]() {
  553. + system::openBrowser("https://github.com/DISTRHO/Cardinal/");
  554. }));
  555. - menu->addChild(createMenuItem("Open user folder", "", [=]() {
  556. - system::openDirectory(asset::user(""));
  557. - }));
  558. -
  559. - if (library::isAppUpdateAvailable()) {
  560. - menu->addChild(new ui::MenuSeparator);
  561. -
  562. - menu->addChild(createMenuItem("Update " + APP_NAME, APP_VERSION + " → " + library::appVersion, [=]() {
  563. - system::openBrowser(library::appDownloadUrl);
  564. - }));
  565. -
  566. - menu->addChild(createMenuItem("Review changelog", "", [=]() {
  567. - system::openBrowser(library::appChangelogUrl);
  568. - }));
  569. - }
  570. - else if (!settings::autoCheckUpdates && !settings::devMode) {
  571. - menu->addChild(createMenuItem("Check for " + APP_NAME + " update", "", [=]() {
  572. - std::thread t([&]() {
  573. - library::checkAppUpdate();
  574. - });
  575. - t.detach();
  576. - }, false, true));
  577. - }
  578. -
  579. menu->addChild(new ui::MenuSeparator);
  580. - menu->addChild(createMenuLabel(APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION));
  581. - }
  582. + menu->addChild(createMenuLabel(APP_EDITION + " " + APP_EDITION_NAME));
  583. - void step() override {
  584. - notification->box.pos = math::Vec(0, 0);
  585. - notification->visible = library::isAppUpdateAvailable();
  586. - MenuButton::step();
  587. + menu->addChild(createMenuLabel("Rack " + APP_VERSION + " Compatible"));
  588. }
  589. };
  590. @@ -908,7 +587,9 @@
  591. struct MenuBar : widget::OpaqueWidget {
  592. MeterLabel* meterLabel;
  593. - MenuBar() {
  594. + MenuBar(const bool isStandalone)
  595. + : widget::OpaqueWidget()
  596. + {
  597. const float margin = 5;
  598. box.size.y = BND_WIDGET_HEIGHT + 2 * margin;
  599. @@ -917,7 +598,7 @@
  600. layout->spacing = math::Vec(0, 0);
  601. addChild(layout);
  602. - FileButton* fileButton = new FileButton;
  603. + FileButton* fileButton = new FileButton(isStandalone);
  604. fileButton->text = "File";
  605. layout->addChild(fileButton);
  606. @@ -933,10 +614,6 @@
  607. engineButton->text = "Engine";
  608. layout->addChild(engineButton);
  609. - LibraryButton* libraryButton = new LibraryButton;
  610. - libraryButton->text = "Library";
  611. - layout->addChild(libraryButton);
  612. -
  613. HelpButton* helpButton = new HelpButton;
  614. helpButton->text = "Help";
  615. layout->addChild(helpButton);
  616. @@ -971,7 +648,11 @@
  617. widget::Widget* createMenuBar() {
  618. - menuBar::MenuBar* menuBar = new menuBar::MenuBar;
  619. + return new widget::Widget;
  620. +}
  621. +
  622. +widget::Widget* createMenuBar(const bool isStandalone) {
  623. + menuBar::MenuBar* menuBar = new menuBar::MenuBar(isStandalone);
  624. return menuBar;
  625. }