#if defined(Hiro_MessageDialog) MessageDialog::MessageDialog(const string& text) { state.text = text; } auto MessageDialog::checked() const -> bool { return state.checked; } auto MessageDialog::error(const vector& buttons) -> string { state.buttons = buttons; state.icon = Icon::Prompt::Error; return _run(); } auto MessageDialog::information(const vector& buttons) -> string { state.buttons = buttons; state.icon = Icon::Prompt::Information; return _run(); } auto MessageDialog::question(const vector& buttons) -> string { state.buttons = buttons; state.icon = Icon::Prompt::Question; return _run(); } auto MessageDialog::setAlignment(Alignment alignment) -> type& { state.alignment = alignment; state.relativeTo = {}; return *this; } auto MessageDialog::setAlignment(sWindow relativeTo, Alignment alignment) -> type& { state.alignment = alignment; state.relativeTo = relativeTo; return *this; } auto MessageDialog::setChecked(bool checked) -> type& { state.checked = checked; return *this; } auto MessageDialog::setOption(const string& option) -> type& { state.option = option; return *this; } auto MessageDialog::setText(const string& text) -> type& { state.text = text; return *this; } auto MessageDialog::setTitle(const string& title) -> type& { state.title = title; return *this; } auto MessageDialog::warning(const vector& buttons) -> string { state.buttons = buttons; state.icon = Icon::Prompt::Warning; return _run(); } auto MessageDialog::_run() -> string { if(!state.buttons) return {}; //nothing to do Application::Namespace tr{"MessageDialog"}; Window window; VerticalLayout layout{&window}; HorizontalLayout messageLayout{&layout, Size{~0, 0}, 5_sy}; VerticalLayout messageIconLayout{&messageLayout, Size{16_sx, ~0}, 5_sx}; Canvas messageIcon{&messageIconLayout, Size{16_sx, 16_sy}, 0}; Widget messageIconSpacer{&messageIconLayout, Size{16_sx, ~0}}; Label messageText{&messageLayout, Size{~0, 0}}; Widget optionSpacer{&layout, Size{0, 0}}; CheckLabel optionText{&layout, Size{~0, 0}}; HorizontalLayout controlLayout{&layout, Size{~0, 0}}; Widget controlSpacer{&controlLayout, Size{~0, 0}}; layout.setPadding(5_sx, 5_sy); image icon{state.icon}; icon.scale(16_sx, 16_sy); messageIcon.setIcon(icon); messageText.setText(state.text); optionSpacer.setCollapsible().setVisible((bool)state.option); optionText.setCollapsible().setChecked(state.checked).setText(state.option).setVisible((bool)state.option).onToggle([&] { state.checked = optionText.checked(); }); for(auto n : range(state.buttons.size())) { Button button{&controlLayout, Size{80_sx, 0}, 5_sx}; button.onActivate([&, n] { state.response = state.buttons[n]; window.setModal(false); }); button.setText(tr(state.buttons[n])); button.setFocused(); //the last button will have effective focus } int widthMessage = 5_sx + 16 + 5_sx + Font().size(state.text).width() + 5_sx; int widthButtons = 5_sx + state.buttons.size() * 85_sx; int width = max(320_sx, widthMessage, widthButtons); window.onClose([&] { //if the dialog is dismissed (escape pressed, or window manager close button clicked), //set the response to the last button shown (which is also the default selected button), //and set a flag to indicate that the dialog was dismissed to the caller. //note that the safest option should always be the last option in the buttons list. if(!state.response) { state.response = state.buttons.last(); state.dismissed = true; } window.setModal(false); }); window.setTitle(state.title); window.setResizable(false); window.setSize({width, layout.minimumSize().height()}); window.setAlignment(state.relativeTo, state.alignment); window.setDismissable(); window.setVisible(); window.setModal(); window.setVisible(false); return state.response; } #endif