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.

159 lines
7.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. enum class ResultCodeMappingMode
  21. {
  22. plainIndex, // The result code is equal to the index of the selected button.
  23. // This is used for NativeMessageBox::show, showAsync, and showMessageBox.
  24. alertWindow, // The result code is mapped in the same way as AlertWindow, i.e. if there
  25. // are N buttons then button X will return ((X + 1) % N).
  26. };
  27. static std::unique_ptr<detail::ScopedMessageBoxInterface> makeNativeMessageBoxWithMappedResult (const MessageBoxOptions& opts,
  28. ResultCodeMappingMode mode)
  29. {
  30. class Adapter : public detail::ScopedMessageBoxInterface
  31. {
  32. public:
  33. explicit Adapter (const MessageBoxOptions& options)
  34. : inner (detail::ScopedMessageBoxInterface::create (options)),
  35. numButtons (options.getNumButtons()) {}
  36. void runAsync (std::function<void (int)> fn) override
  37. {
  38. inner->runAsync ([fn, n = numButtons] (int result)
  39. {
  40. fn (map (result, n));
  41. });
  42. }
  43. int runSync() override
  44. {
  45. return map (inner->runSync(), numButtons);
  46. }
  47. void close() override
  48. {
  49. inner->close();
  50. }
  51. private:
  52. static int map (int button, int numButtons) { return (button + 1) % numButtons; }
  53. std::unique_ptr<detail::ScopedMessageBoxInterface> inner;
  54. int numButtons = 0;
  55. };
  56. return mode == ResultCodeMappingMode::plainIndex ? detail::ScopedMessageBoxInterface::create (opts)
  57. : std::make_unique<Adapter> (opts);
  58. }
  59. static int showNativeBoxUnmanaged (const MessageBoxOptions& opts,
  60. ModalComponentManager::Callback* cb,
  61. ResultCodeMappingMode mode)
  62. {
  63. auto implementation = makeNativeMessageBoxWithMappedResult (opts, mode);
  64. return detail::ConcreteScopedMessageBoxImpl::showUnmanaged (std::move (implementation), cb);
  65. }
  66. #if JUCE_MODAL_LOOPS_PERMITTED
  67. void JUCE_CALLTYPE NativeMessageBox::showMessageBox (MessageBoxIconType iconType,
  68. const String& title, const String& message,
  69. Component* associatedComponent)
  70. {
  71. showNativeBoxUnmanaged (MessageBoxOptions().withIconType (iconType)
  72. .withTitle (title)
  73. .withMessage (message)
  74. .withButton (TRANS("OK"))
  75. .withAssociatedComponent (associatedComponent),
  76. nullptr,
  77. ResultCodeMappingMode::plainIndex);
  78. }
  79. int JUCE_CALLTYPE NativeMessageBox::show (const MessageBoxOptions& options)
  80. {
  81. return showNativeBoxUnmanaged (options, nullptr, ResultCodeMappingMode::plainIndex);
  82. }
  83. #endif
  84. void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (MessageBoxIconType iconType,
  85. const String& title, const String& message,
  86. Component* associatedComponent,
  87. ModalComponentManager::Callback* callback)
  88. {
  89. auto options = MessageBoxOptions::makeOptionsOk (iconType, title, message, {}, associatedComponent);
  90. showNativeBoxUnmanaged (options, callback, ResultCodeMappingMode::alertWindow);
  91. }
  92. bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (MessageBoxIconType iconType,
  93. const String& title, const String& message,
  94. Component* associatedComponent,
  95. ModalComponentManager::Callback* callback)
  96. {
  97. auto options = MessageBoxOptions::makeOptionsOkCancel (iconType, title, message, {}, {}, associatedComponent);
  98. return showNativeBoxUnmanaged (options, callback, ResultCodeMappingMode::alertWindow) != 0;
  99. }
  100. int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (MessageBoxIconType iconType,
  101. const String& title, const String& message,
  102. Component* associatedComponent,
  103. ModalComponentManager::Callback* callback)
  104. {
  105. auto options = MessageBoxOptions::makeOptionsYesNoCancel (iconType, title, message, {}, {}, {}, associatedComponent);
  106. return showNativeBoxUnmanaged (options, callback, ResultCodeMappingMode::alertWindow);
  107. }
  108. int JUCE_CALLTYPE NativeMessageBox::showYesNoBox (MessageBoxIconType iconType,
  109. const String& title, const String& message,
  110. Component* associatedComponent,
  111. ModalComponentManager::Callback* callback)
  112. {
  113. auto options = MessageBoxOptions::makeOptionsYesNo (iconType, title, message, {}, {}, associatedComponent);
  114. return showNativeBoxUnmanaged (options, callback, ResultCodeMappingMode::alertWindow);
  115. }
  116. void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
  117. ModalComponentManager::Callback* callback)
  118. {
  119. showNativeBoxUnmanaged (options, callback, ResultCodeMappingMode::plainIndex);
  120. }
  121. void JUCE_CALLTYPE NativeMessageBox::showAsync (const MessageBoxOptions& options,
  122. std::function<void (int)> callback)
  123. {
  124. showAsync (options, ModalCallbackFunction::create (callback));
  125. }
  126. ScopedMessageBox NativeMessageBox::showScopedAsync (const MessageBoxOptions& options, std::function<void (int)> callback)
  127. {
  128. auto implementation = makeNativeMessageBoxWithMappedResult (options, ResultCodeMappingMode::alertWindow);
  129. return detail::ConcreteScopedMessageBoxImpl::show (std::move (implementation), std::move (callback));
  130. }
  131. } // namespace juce