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.

162 lines
4.2KB

  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. static const constexpr float margin = 10;
  33. static const constexpr float buttonWidth = 100;
  34. SequentialLayout* layout;
  35. SequentialLayout* contentLayout;
  36. SequentialLayout* buttonLayout;
  37. Label* label;
  38. AsyncDialog(const char* const message)
  39. {
  40. setup(message);
  41. struct AsyncDismissButton : Button {
  42. AsyncDialog* dialog;
  43. void onAction(const ActionEvent& e) override {
  44. dialog->getParent()->requestDelete();
  45. }
  46. };
  47. AsyncDismissButton* const dismissButton = new AsyncDismissButton;
  48. dismissButton->box.size.x = buttonWidth;
  49. dismissButton->text = "Dismiss";
  50. dismissButton->dialog = this;
  51. buttonLayout->addChild(dismissButton);
  52. }
  53. AsyncDialog(const char* const message, const std::function<void()> action)
  54. {
  55. setup(message);
  56. struct AsyncCancelButton : Button {
  57. AsyncDialog* dialog;
  58. void onAction(const ActionEvent& e) override {
  59. dialog->getParent()->requestDelete();
  60. }
  61. };
  62. AsyncCancelButton* const cancelButton = new AsyncCancelButton;
  63. cancelButton->box.size.x = buttonWidth;
  64. cancelButton->text = "Cancel";
  65. cancelButton->dialog = this;
  66. buttonLayout->addChild(cancelButton);
  67. struct AsyncOkButton : Button {
  68. AsyncDialog* dialog;
  69. std::function<void()> action;
  70. void onAction(const ActionEvent& e) override {
  71. action();
  72. dialog->getParent()->requestDelete();
  73. }
  74. };
  75. AsyncOkButton* const okButton = new AsyncOkButton;
  76. okButton->box.size.x = buttonWidth;
  77. okButton->text = "Ok";
  78. okButton->dialog = this;
  79. okButton->action = action;
  80. buttonLayout->addChild(okButton);
  81. }
  82. void setup(const char* const message)
  83. {
  84. box.size = math::Vec(400, 120);
  85. layout = new SequentialLayout;
  86. layout->box.pos = math::Vec(0, 0);
  87. layout->box.size = box.size;
  88. layout->orientation = SequentialLayout::VERTICAL_ORIENTATION;
  89. layout->margin = math::Vec(margin, margin);
  90. layout->spacing = math::Vec(margin, margin);
  91. layout->wrap = false;
  92. addChild(layout);
  93. contentLayout = new SequentialLayout;
  94. contentLayout->spacing = math::Vec(margin, margin);
  95. layout->addChild(contentLayout);
  96. buttonLayout = new SequentialLayout;
  97. buttonLayout->alignment = SequentialLayout::CENTER_ALIGNMENT;
  98. buttonLayout->box.size = box.size;
  99. buttonLayout->spacing = math::Vec(margin, margin);
  100. layout->addChild(buttonLayout);
  101. label = new Label;
  102. label->box.size.x = box.size.x - 2*margin;
  103. label->box.size.y = box.size.y - 2*margin - 40;
  104. label->fontSize = 16;
  105. label->text = message;
  106. contentLayout->addChild(label);
  107. }
  108. void step() override
  109. {
  110. OpaqueWidget::step();
  111. box.pos = parent->box.size.minus(box.size).div(2).round();
  112. }
  113. void draw(const DrawArgs& args) override
  114. {
  115. bndMenuBackground(args.vg, 0.0, 0.0, box.size.x, box.size.y, 0);
  116. Widget::draw(args);
  117. }
  118. };
  119. void create(const char* const message)
  120. {
  121. MenuOverlay* const overlay = new MenuOverlay;
  122. overlay->bgColor = nvgRGBAf(0, 0, 0, 0.33);
  123. AsyncDialog* const dialog = new AsyncDialog(message);
  124. overlay->addChild(dialog);
  125. APP->scene->addChild(overlay);
  126. }
  127. void create(const char* const message, const std::function<void()> action)
  128. {
  129. MenuOverlay* const overlay = new MenuOverlay;
  130. overlay->bgColor = nvgRGBAf(0, 0, 0, 0.33);
  131. AsyncDialog* const dialog = new AsyncDialog(message, action);
  132. overlay->addChild(dialog);
  133. APP->scene->addChild(overlay);
  134. }
  135. }