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.

128 lines
3.5KB

  1. /*
  2. * DISTRHO Cardinal Plugin
  3. * Copyright (C) 2021 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 3 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the LICENSE file.
  16. */
  17. #include "AsyncDialog.hpp"
  18. #include <context.hpp>
  19. #include <app/Scene.hpp>
  20. #include <ui/Button.hpp>
  21. #include <ui/Label.hpp>
  22. #include <ui/MenuOverlay.hpp>
  23. #include <ui/SequentialLayout.hpp>
  24. #include <widget/OpaqueWidget.hpp>
  25. namespace asyncDialog
  26. {
  27. using namespace rack;
  28. using namespace rack::ui;
  29. using namespace rack::widget;
  30. struct AsyncDialog : OpaqueWidget
  31. {
  32. SequentialLayout* layout;
  33. SequentialLayout* contentLayout;
  34. SequentialLayout* buttonLayout;
  35. Label* label;
  36. AsyncDialog(const char* const message, const std::function<void()> action)
  37. {
  38. box.size = math::Vec(400, 120);
  39. const float margin = 10;
  40. const float buttonWidth = 100;
  41. layout = new SequentialLayout;
  42. layout->box.pos = math::Vec(0, 0);
  43. layout->box.size = box.size;
  44. layout->orientation = SequentialLayout::VERTICAL_ORIENTATION;
  45. layout->margin = math::Vec(margin, margin);
  46. layout->spacing = math::Vec(margin, margin);
  47. layout->wrap = false;
  48. addChild(layout);
  49. contentLayout = new SequentialLayout;
  50. contentLayout->spacing = math::Vec(margin, margin);
  51. layout->addChild(contentLayout);
  52. buttonLayout = new SequentialLayout;
  53. buttonLayout->alignment = SequentialLayout::CENTER_ALIGNMENT;
  54. buttonLayout->box.size = box.size;
  55. buttonLayout->spacing = math::Vec(margin, margin);
  56. layout->addChild(buttonLayout);
  57. label = new Label;
  58. label->box.size.x = box.size.x - 2*margin;
  59. label->box.size.y = box.size.y - 2*margin - 40;
  60. label->fontSize = 16;
  61. label->text = message;
  62. contentLayout->addChild(label);
  63. struct AsyncCancelButton : Button {
  64. AsyncDialog* dialog;
  65. void onAction(const ActionEvent& e) override {
  66. dialog->getParent()->requestDelete();
  67. }
  68. };
  69. AsyncCancelButton* const cancelButton = new AsyncCancelButton;
  70. cancelButton->box.size.x = buttonWidth;
  71. cancelButton->text = "Cancel";
  72. cancelButton->dialog = this;
  73. buttonLayout->addChild(cancelButton);
  74. struct AsyncOkButton : Button {
  75. AsyncDialog* dialog;
  76. std::function<void()> action;
  77. void onAction(const ActionEvent& e) override {
  78. action();
  79. dialog->getParent()->requestDelete();
  80. }
  81. };
  82. AsyncOkButton* const okButton = new AsyncOkButton;
  83. okButton->box.size.x = buttonWidth;
  84. okButton->text = "Ok";
  85. okButton->dialog = this;
  86. okButton->action = action;
  87. buttonLayout->addChild(okButton);
  88. }
  89. void step() override
  90. {
  91. OpaqueWidget::step();
  92. box.pos = parent->box.size.minus(box.size).div(2).round();
  93. }
  94. void draw(const DrawArgs& args) override
  95. {
  96. bndMenuBackground(args.vg, 0.0, 0.0, box.size.x, box.size.y, 0);
  97. Widget::draw(args);
  98. }
  99. };
  100. void create(const char* const message, const std::function<void()> action)
  101. {
  102. MenuOverlay* const overlay = new MenuOverlay;
  103. overlay->bgColor = nvgRGBAf(0, 0, 0, 0.33);
  104. AsyncDialog* const dialog = new AsyncDialog(message, action);
  105. overlay->addChild(dialog);
  106. APP->scene->addChild(overlay);
  107. }
  108. }