message-dialog.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #if defined(Hiro_MessageDialog)
  2. MessageDialog::MessageDialog(const string& text) {
  3. state.text = text;
  4. }
  5. auto MessageDialog::checked() const -> bool {
  6. return state.checked;
  7. }
  8. auto MessageDialog::error(const vector<string>& buttons) -> string {
  9. state.buttons = buttons;
  10. state.icon = Icon::Prompt::Error;
  11. return _run();
  12. }
  13. auto MessageDialog::information(const vector<string>& buttons) -> string {
  14. state.buttons = buttons;
  15. state.icon = Icon::Prompt::Information;
  16. return _run();
  17. }
  18. auto MessageDialog::question(const vector<string>& buttons) -> string {
  19. state.buttons = buttons;
  20. state.icon = Icon::Prompt::Question;
  21. return _run();
  22. }
  23. auto MessageDialog::setAlignment(Alignment alignment) -> type& {
  24. state.alignment = alignment;
  25. state.relativeTo = {};
  26. return *this;
  27. }
  28. auto MessageDialog::setAlignment(sWindow relativeTo, Alignment alignment) -> type& {
  29. state.alignment = alignment;
  30. state.relativeTo = relativeTo;
  31. return *this;
  32. }
  33. auto MessageDialog::setChecked(bool checked) -> type& {
  34. state.checked = checked;
  35. return *this;
  36. }
  37. auto MessageDialog::setOption(const string& option) -> type& {
  38. state.option = option;
  39. return *this;
  40. }
  41. auto MessageDialog::setText(const string& text) -> type& {
  42. state.text = text;
  43. return *this;
  44. }
  45. auto MessageDialog::setTitle(const string& title) -> type& {
  46. state.title = title;
  47. return *this;
  48. }
  49. auto MessageDialog::warning(const vector<string>& buttons) -> string {
  50. state.buttons = buttons;
  51. state.icon = Icon::Prompt::Warning;
  52. return _run();
  53. }
  54. auto MessageDialog::_run() -> string {
  55. if(!state.buttons) return {}; //nothing to do
  56. Application::Namespace tr{"MessageDialog"};
  57. Window window;
  58. VerticalLayout layout{&window};
  59. HorizontalLayout messageLayout{&layout, Size{~0, 0}, 5_sy};
  60. VerticalLayout messageIconLayout{&messageLayout, Size{16_sx, ~0}, 5_sx};
  61. Canvas messageIcon{&messageIconLayout, Size{16_sx, 16_sy}, 0};
  62. Widget messageIconSpacer{&messageIconLayout, Size{16_sx, ~0}};
  63. Label messageText{&messageLayout, Size{~0, 0}};
  64. Widget optionSpacer{&layout, Size{0, 0}};
  65. CheckLabel optionText{&layout, Size{~0, 0}};
  66. HorizontalLayout controlLayout{&layout, Size{~0, 0}};
  67. Widget controlSpacer{&controlLayout, Size{~0, 0}};
  68. layout.setPadding(5_sx, 5_sy);
  69. image icon{state.icon};
  70. icon.scale(16_sx, 16_sy);
  71. messageIcon.setIcon(icon);
  72. messageText.setText(state.text);
  73. optionSpacer.setCollapsible().setVisible((bool)state.option);
  74. optionText.setCollapsible().setChecked(state.checked).setText(state.option).setVisible((bool)state.option).onToggle([&] {
  75. state.checked = optionText.checked();
  76. });
  77. for(auto n : range(state.buttons.size())) {
  78. Button button{&controlLayout, Size{80_sx, 0}, 5_sx};
  79. button.onActivate([&, n] {
  80. state.response = state.buttons[n];
  81. window.setModal(false);
  82. });
  83. button.setText(tr(state.buttons[n]));
  84. button.setFocused(); //the last button will have effective focus
  85. }
  86. int widthMessage = 5_sx + 16 + 5_sx + Font().size(state.text).width() + 5_sx;
  87. int widthButtons = 5_sx + state.buttons.size() * 85_sx;
  88. int width = max(320_sx, widthMessage, widthButtons);
  89. window.onClose([&] {
  90. //if the dialog is dismissed (escape pressed, or window manager close button clicked),
  91. //set the response to the last button shown (which is also the default selected button),
  92. //and set a flag to indicate that the dialog was dismissed to the caller.
  93. //note that the safest option should always be the last option in the buttons list.
  94. if(!state.response) {
  95. state.response = state.buttons.last();
  96. state.dismissed = true;
  97. }
  98. window.setModal(false);
  99. });
  100. window.setTitle(state.title);
  101. window.setResizable(false);
  102. window.setSize({width, layout.minimumSize().height()});
  103. window.setAlignment(state.relativeTo, state.alignment);
  104. window.setDismissable();
  105. window.setVisible();
  106. window.setModal();
  107. window.setVisible(false);
  108. return state.response;
  109. }
  110. #endif