diff --git a/CHANGELOG.md b/CHANGELOG.md index 1153b797..87b41c6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,8 +74,9 @@ non-integer font sizes to be specified. [[#947](https://github.com/reupen/columns_ui/pull/947)] -- Info boxes, such as Filter field help, are now dark themed when dark mode is - active. [[#1041](https://github.com/reupen/columns_ui/pull/1041)] +- Message boxes now have a consistent appearance, and are dark themed when dark + mode is active. [[#1041](https://github.com/reupen/columns_ui/pull/1041), + [#1043](https://github.com/reupen/columns_ui/pull/1043)] - The positioning of tooltips in list views for centre- and right-aligned columns was improved. [[#910](https://github.com/reupen/columns_ui/pull/910)] diff --git a/fbh b/fbh index 8f5aa052..51d53f8c 160000 --- a/fbh +++ b/fbh @@ -1 +1 @@ -Subproject commit 8f5aa052caca0d157e7d41c137299a6414f81c4e +Subproject commit 51d53f8c8531f055bac992ecc6bed9492993eac2 diff --git a/foo_ui_columns/buttons_config_param.cpp b/foo_ui_columns/buttons_config_param.cpp index 2b3c011e..14c107dc 100644 --- a/foo_ui_columns/buttons_config_param.cpp +++ b/foo_ui_columns/buttons_config_param.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "buttons.h" +#include "dark_mode_dialog.h" #include "prefs_utils.h" #include "svg.h" @@ -367,10 +368,9 @@ INT_PTR ButtonsToolbar::ConfigParam::on_dialog_message(HWND wnd, UINT msg, WPARA break; } case IDC_RESET: { - if (win32_helpers::message_box(wnd, - _T("This will reset all your buttons to the default buttons. Continue?"), _T("Reset buttons"), - MB_YESNO) - == IDYES) { + if (dark::modal_info_box(wnd, "Reset buttons", + "This will reset all your buttons to the default buttons. Continue?", uih::InfoBoxType::Neutral, + uih::InfoBoxModalType::YesNo)) { m_button_list.remove_items(bit_array_true()); reset_buttons(m_buttons); populate_buttons_list(); diff --git a/foo_ui_columns/commandline.cpp b/foo_ui_columns/commandline.cpp index a8c74bc5..4d792eb8 100644 --- a/foo_ui_columns/commandline.cpp +++ b/foo_ui_columns/commandline.cpp @@ -23,7 +23,8 @@ class HelpCommandLineHandler : public commandline_handler { { HWND parent = core_api::get_main_window(); ui_control::get()->activate(); - uMessageBox(parent, reinterpret_cast(g_help_text), "Columns UI command-line help", 0); + cui::dark::modeless_info_box(parent, "Columns UI command-line help", reinterpret_cast(g_help_text), + uih::InfoBoxType::Information); } }; @@ -42,12 +43,12 @@ class CommandLineSingleFileHelper { const auto main_window = core_api::get_main_window(); if (m_files.empty()) { ui_control::get()->activate(); - cui::dark::info_box(main_window, m_error_title, m_no_files_error, OIC_ERROR); + cui::dark::modeless_info_box(main_window, m_error_title, m_no_files_error, uih::InfoBoxType::Error); return false; } if (m_files.size() > 1) { ui_control::get()->activate(); - cui::dark::info_box(main_window, m_error_title, m_too_many_files_error, OIC_ERROR); + cui::dark::modeless_info_box(main_window, m_error_title, m_too_many_files_error, uih::InfoBoxType::Error); return false; } return true; @@ -101,13 +102,13 @@ class ImportCommandLineHandler : public commandline_handler { if (!is_quiet) { ui_control::get()->activate(); - if (uMessageBox(main_window, - formatter << "Are you sure you want to import " << pfc::string_filename_ext(path) - << "? Your current Columns UI configuration will be lost.", - "Import configuration", MB_YESNO) - == IDNO) { + const auto message + = fmt::format("Are you sure you want to import {}? Your current Columns UI configuration will be lost.", + pfc::string_filename_ext(path).c_str()); + + if (!cui::dark::modal_info_box(main_window, "Import configuration", message.c_str(), + uih::InfoBoxType::Neutral, uih::InfoBoxModalType::YesNo)) return; - } } g_import_layout(core_api::get_main_window(), path, is_quiet); } diff --git a/foo_ui_columns/config_filter.cpp b/foo_ui_columns/config_filter.cpp index 37c237d3..8719bb4a 100644 --- a/foo_ui_columns/config_filter.cpp +++ b/foo_ui_columns/config_filter.cpp @@ -129,7 +129,7 @@ static class TabFilterFields : public PreferencesTab { "For example, \"Album Artist;Artist\" or \"%album artist%\".\r\n\r\n" "Only the former format supports multiple values per field and is compatible with " "inline metadata editing."; - cui::dark::info_box(wnd, "Filter Field Help", text); + cui::dark::modeless_info_box(wnd, "Filter Field Help", text, uih::InfoBoxType::Neutral); } break; case IDC_UP: { if (m_field_list.get_selection_count(2) == 1) { diff --git a/foo_ui_columns/dark_mode_dialog.cpp b/foo_ui_columns/dark_mode_dialog.cpp index 0e48f0d7..9ae1e3f5 100644 --- a/foo_ui_columns/dark_mode_dialog.cpp +++ b/foo_ui_columns/dark_mode_dialog.cpp @@ -313,14 +313,27 @@ HWND modeless_dialog_box(UINT resource_id, DialogDarkModeConfig dark_mode_config return wnd; } -void info_box(HWND wnd_parent, const char* title, const char* text, INT icon, uih::alignment text_alignment) +void modeless_info_box( + HWND wnd_parent, const char* title, const char* message, uih::InfoBoxType type, uih::alignment text_alignment) { const auto handle_before_message = [helper = std::make_shared( DialogDarkModeConfig{.button_ids{IDCANCEL}, .last_button_id = IDCANCEL})](HWND wnd, UINT msg, WPARAM wp, LPARAM lp) -> std::optional { return helper->handle_message(wnd, msg, wp, lp); }; - fbh::show_info_box(wnd_parent, title, text, icon, text_alignment, handle_before_message); + fbh::show_info_box_modeless(wnd_parent, title, message, type, text_alignment, handle_before_message); +} + +INT_PTR modal_info_box(HWND wnd_parent, const char* title, const char* message, uih::InfoBoxType type, + uih::InfoBoxModalType modal_type, uih::alignment text_alignment) +{ + const auto handle_before_message + = [helper = std::make_shared( + DialogDarkModeConfig{.button_ids{IDCANCEL, IDOK}, .last_button_id = IDCANCEL})](HWND wnd, UINT msg, + WPARAM wp, LPARAM lp) -> std::optional { return helper->handle_message(wnd, msg, wp, lp); }; + + return fbh::show_info_box_modal( + wnd_parent, title, message, type, modal_type, text_alignment, handle_before_message); } } // namespace cui::dark diff --git a/foo_ui_columns/dark_mode_dialog.h b/foo_ui_columns/dark_mode_dialog.h index c3c0cdde..08297af4 100644 --- a/foo_ui_columns/dark_mode_dialog.h +++ b/foo_ui_columns/dark_mode_dialog.h @@ -22,7 +22,10 @@ INT_PTR modal_dialog_box(UINT resource_id, DialogDarkModeConfig dark_mode_config HWND modeless_dialog_box(UINT resource_id, DialogDarkModeConfig dark_mode_config, HWND parent_window, std::function on_message); -void info_box(HWND wnd_parent, const char* title, const char* text, INT icon = OIC_INFORMATION, +void modeless_info_box(HWND wnd_parent, const char* title, const char* message, uih::InfoBoxType type, uih::alignment text_alignment = uih::ALIGN_LEFT); +INT_PTR modal_info_box(HWND wnd_parent, const char* title, const char* message, uih::InfoBoxType type, + uih::InfoBoxModalType modal_type, uih::alignment text_alignment = uih::ALIGN_LEFT); + } // namespace cui::dark diff --git a/foo_ui_columns/font_picker.cpp b/foo_ui_columns/font_picker.cpp index 0020672c..e67717e6 100644 --- a/foo_ui_columns/font_picker.cpp +++ b/foo_ui_columns/font_picker.cpp @@ -334,8 +334,8 @@ void DirectWriteFontPicker::handle_wm_init_dialog(HWND wnd) ComboBox_AddString(m_font_family_combobox, family.display_name().c_str()); if (m_font_families.empty()) { - uih::InfoBox::s_run( - m_wnd, "Error initialising fonts list", "There was an error listing fonts using DirectWrite.", OIC_ERROR); + uih::InfoBox::s_open_modeless(m_wnd, "Error initialising fonts list", + "There was an error listing fonts using DirectWrite.", uih::InfoBoxType::Error); } } diff --git a/foo_ui_columns/foo_ui_columns.vcxproj b/foo_ui_columns/foo_ui_columns.vcxproj index 492baf09..ef2ea081 100644 --- a/foo_ui_columns/foo_ui_columns.vcxproj +++ b/foo_ui_columns/foo_ui_columns.vcxproj @@ -120,7 +120,7 @@ 0x0809 - Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) + Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;Winmm.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) DebugFastLink true true @@ -160,7 +160,7 @@ 0x0809 - Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) + Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;Winmm.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) DebugFastLink true true @@ -198,7 +198,7 @@ 0x0809 - Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) + Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;Winmm.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) Debug @@ -233,7 +233,7 @@ 0x0809 - Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) + Urlmon.lib;comctl32.lib;shell32.lib;shlwapi.lib;Winmm.lib;gdiplus.lib;../foobar2000/shared/shared-$(Platform).lib;uxtheme.lib;Dwmapi.lib;usp10.lib;Windowscodecs.lib;Dwrite.lib;%(AdditionalDependencies) Debug diff --git a/foo_ui_columns/helpers.cpp b/foo_ui_columns/helpers.cpp index a4fd4419..308e7829 100644 --- a/foo_ui_columns/helpers.cpp +++ b/foo_ui_columns/helpers.cpp @@ -157,8 +157,8 @@ bool open_web_page(HWND wnd, const wchar_t* url) const auto process = ShellExecute(wnd, nullptr, url, nullptr, nullptr, SW_SHOWNORMAL); const bool succeeded = reinterpret_cast(process) > 32; if (!succeeded) { - dark::info_box(wnd, "Error opening web page", - "Columns UI was unable to open the web page using your default browser.", OIC_ERROR); + dark::modeless_info_box(wnd, "Error opening web page", + "Columns UI was unable to open the web page using your default browser.", uih::InfoBoxType::Error); } return succeeded; } diff --git a/foo_ui_columns/layout.cpp b/foo_ui_columns/layout.cpp index b67101a5..fac62e1d 100644 --- a/foo_ui_columns/layout.cpp +++ b/foo_ui_columns/layout.cpp @@ -2,6 +2,7 @@ #include "layout.h" #include "dark_mode.h" +#include "dark_mode_dialog.h" #include "splitter_utils.h" #include "main_window.h" @@ -773,11 +774,9 @@ void LayoutWindow::run_live_edit_base(const LiveEditData& p_data) if (uie::window::create_by_guid(panels[panel_index].guid, window) && window->service_query_t(splitter)) { const auto count = std::min(p_splitter->get_panel_count(), splitter->get_maximum_panel_count()); if (count == p_splitter->get_panel_count() - || MessageBox(get_wnd(), - _T("The number of child items will not fit in the selected splitter type. ") - _T("Continue?"), - _T("Warning"), MB_YESNO | MB_ICONEXCLAMATION) - == IDYES) { + || cui::dark::modal_info_box(get_wnd(), "Change splitter type", + "The number of child items will not fit in the selected splitter type. Do you want to continue?", + uih::InfoBoxType::Warning, uih::InfoBoxModalType::YesNo)) { for (unsigned n = 0; n < count; n++) { uie::splitter_item_ptr ptr; p_splitter->get_panel(n, ptr); @@ -811,11 +810,10 @@ void LayoutWindow::run_live_edit_base(const LiveEditData& p_data) const auto count = std::min(p_splitter->get_panel_count(), splitter->get_maximum_panel_count()); if (index != pfc_infinite && (count == p_splitter->get_panel_count() - || MessageBox(p_data.m_wnd, - _T("The number of child items will not fit in the selected splitter ") - _T("type. Continue?"), - _T("Warning"), MB_YESNO | MB_ICONEXCLAMATION) - == IDYES)) { + || cui::dark::modal_info_box(get_wnd(), "Change splitter type", + "The number of child items will not fit in the selected splitter type. Do you want to " + "continue?", + uih::InfoBoxType::Warning, uih::InfoBoxModalType::YesNo))) { for (unsigned n = 0; n < count; n++) { uie::splitter_item_ptr ptr; p_splitter->get_panel(n, ptr); diff --git a/foo_ui_columns/main_window.cpp b/foo_ui_columns/main_window.cpp index 86f4cfd8..b3ba5e39 100644 --- a/foo_ui_columns/main_window.cpp +++ b/foo_ui_columns/main_window.cpp @@ -12,6 +12,7 @@ #include "status_pane.h" #include "layout.h" #include "dark_mode.h" +#include "dark_mode_dialog.h" #include "icons.h" #include "system_tray.h" #include "status_bar.h" @@ -41,8 +42,8 @@ bool remember_window_pos() const TCHAR* main_window_class_name = _T("{E7076D1C-A7BF-4f39-B771-BCBE88F2A2A8}"); -const wchar_t* unsupported_os_message - = L"Sorry, your operating system version is not supported by this version " +const char* unsupported_os_message + = "Sorry, your operating system version is not supported by this version " "of Columns UI. Please upgrade to Windows 7 Service Pack 1 or newer and try again.\n\n" "Otherwise, uninstall the Columns UI component to return to the Default User Interface."; @@ -51,8 +52,8 @@ HWND cui::MainWindow::initialise(user_interface::HookProc_t hook) fbh::enable_wil_console_logging(); if (!IsWindows7SP1OrGreater()) { - MessageBox( - nullptr, unsupported_os_message, L"Columns UI - Unsupported operating system", MB_OK | MB_ICONEXCLAMATION); + dark::modal_info_box(nullptr, u8"Unsupported operating system – Columns UI"_pcc, unsupported_os_message, + uih::InfoBoxType::Error, uih::InfoBoxModalType::OK); return nullptr; } @@ -60,9 +61,12 @@ HWND cui::MainWindow::initialise(user_interface::HookProc_t hook) try { THROW_IF_FAILED(OleInitialize(nullptr)); - } catch (const wil::ResultException&) { - MessageBox( - nullptr, unsupported_os_message, L"Columns UI - Failed to initialise COM", MB_OK | MB_ICONEXCLAMATION); + } catch (const wil::ResultException& ex) { + pfc::string8 message = "Unknown COM initialisation error"; + uFormatMessage(ex.GetFailureInfo().hr, message); + + dark::modal_info_box(nullptr, u8"Failed to initialise COM – Columns UI"_pcc, message.c_str(), + uih::InfoBoxType::Error, uih::InfoBoxModalType::OK); return nullptr; } diff --git a/foo_ui_columns/playlist_switcher_v2.h b/foo_ui_columns/playlist_switcher_v2.h index b8580e61..5d6683a5 100644 --- a/foo_ui_columns/playlist_switcher_v2.h +++ b/foo_ui_columns/playlist_switcher_v2.h @@ -1,5 +1,6 @@ #pragma once +#include "dark_mode_dialog.h" #include "playlist_manager_utils.h" #include "playlist_switcher.h" #include "list_view_panel.h" @@ -175,10 +176,10 @@ class PlaylistSwitcher if (index < m_playlist_api->get_playlist_count()) { pfc::string8 name; m_playlist_api->playlist_get_name(index, name); - pfc::string_formatter formatter; - if (uMessageBox(get_wnd(), formatter << "Are you sure you want to delete the \"" << name << "\" playlist?", - "Delete Playlist", MB_YESNO) - == IDYES) + + if (dark::modal_info_box(get_wnd(), "Delete playlist", + fmt::format("Are you sure you want to delete the \"{}\" playlist?", name.c_str()).c_str(), + uih::InfoBoxType::Neutral, uih::InfoBoxModalType::YesNo)) m_playlist_api->remove_playlist_switch(index); } return true; diff --git a/foo_ui_columns/splitter_utils.cpp b/foo_ui_columns/splitter_utils.cpp index 509ea372..b056c6a1 100644 --- a/foo_ui_columns/splitter_utils.cpp +++ b/foo_ui_columns/splitter_utils.cpp @@ -2,6 +2,8 @@ #include "splitter_utils.h" +#include "dark_mode_dialog.h" + namespace cui::splitter_utils { auto normalise_splitter_item(const uie::splitter_item_t* item) @@ -161,7 +163,7 @@ std::unique_ptr get_splitter_item_from_clipbo try { return get_splitter_item_from_clipboard(); } catch (const exception_io& ex) { - uMessageBox(wnd, ex.what(), u8"Error – Paste Panel"_pcc, MB_OK | MB_ICONERROR); + dark::modeless_info_box(wnd, u8"Error – Paste panel"_pcc, ex.what(), uih::InfoBoxType::Error); } return {}; } diff --git a/foo_ui_columns/splitter_utils.h b/foo_ui_columns/splitter_utils.h index 22932feb..abd0f894 100644 --- a/foo_ui_columns/splitter_utils.h +++ b/foo_ui_columns/splitter_utils.h @@ -2,6 +2,8 @@ #include +#include "dark_mode_dialog.h" + namespace cui::splitter_utils { pfc::array_t serialise_splitter_item(const uie::splitter_item_full_v3_impl_t* item); @@ -26,7 +28,7 @@ void copy_splitter_item_to_clipboard_safe(HWND wnd, const SplitterItem* item) try { copy_splitter_item_to_clipboard(item); } catch (const exception_io& ex) { - uMessageBox(wnd, ex.what(), u8"Error – Copy Panel"_pcc, MB_OK | MB_ICONERROR); + dark::modeless_info_box(wnd, u8"Error – Copy panel"_pcc, ex.what(), uih::InfoBoxType::Error); } } diff --git a/foo_ui_columns/tab_layout.cpp b/foo_ui_columns/tab_layout.cpp index 7d817dcb..bf620c71 100644 --- a/foo_ui_columns/tab_layout.cpp +++ b/foo_ui_columns/tab_layout.cpp @@ -4,6 +4,7 @@ #include "layout.h" #include "config.h" +#include "dark_mode_dialog.h" #include "rename_dialog.h" #include "splitter_utils.h" @@ -352,9 +353,9 @@ void LayoutTab::switch_splitter(HWND wnd, HTREEITEM ti, const GUID& p_guid) if (uie::window::create_by_guid(p_guid, window) && window->service_query_t(splitter)) { const auto count = std::min(old_node->m_children.size(), splitter->get_maximum_panel_count()); if (count == old_node->m_children.size() - || MessageBox(wnd, _T("The number of child items will not fit in the selected splitter type. Continue?"), - _T("Warning"), MB_YESNO | MB_ICONEXCLAMATION) - == IDYES) { + || dark::modal_info_box(wnd, "Change splitter type", + "The number of child items will not fit in the selected splitter type. Do you want to continue?", + uih::InfoBoxType::Warning, uih::InfoBoxModalType::YesNo)) { for (unsigned n = 0; n < count; n++) splitter->add_panel(old_node->m_children[n]->m_item->get_ptr()); stream_writer_memblock conf; @@ -626,9 +627,9 @@ INT_PTR LayoutTab::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) = fmt::format(u8"Are you sure that you want to delete the layout preset ‘{}’?", reinterpret_cast(preset_name.c_str())); - if (uMessageBox(wnd, reinterpret_cast(confirmation_message.c_str()), "Delete preset", - MB_YESNO | MB_ICONWARNING) - != IDYES) + if (!dark::modal_info_box(wnd, "Delete preset", + reinterpret_cast(confirmation_message.c_str()), uih::InfoBoxType::Warning, + uih::InfoBoxModalType::YesNo)) break; } @@ -650,12 +651,9 @@ INT_PTR LayoutTab::on_message(HWND wnd, UINT msg, WPARAM wp, LPARAM lp) m_changed = true; } break; case IDC_RESET_PRESETS: - if (win32_helpers::message_box(wnd, - _T( - "This will reset layout presets to default values. Are you sure you wish to so this?" - ), - _T("Reset presets?"), MB_YESNO | MB_ICONQUESTION) - == IDYES) { + if (dark::modal_info_box(wnd, "Reset presets", + "This will reset layout presets to default values. Are you sure you wish to so this?", + uih::InfoBoxType::Neutral, uih::InfoBoxModalType::YesNo)) { deinitialise_tree(wnd); HWND wnd_combo = GetDlgItem(wnd, IDC_PRESETS); ComboBox_ResetContent(wnd_combo); diff --git a/foo_ui_columns/tab_main.cpp b/foo_ui_columns/tab_main.cpp index 30f432a6..efb75992 100644 --- a/foo_ui_columns/tab_main.cpp +++ b/foo_ui_columns/tab_main.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "fcl.h" #include "config.h" +#include "dark_mode_dialog.h" #include "rebar.h" #include "main_window.h" @@ -69,10 +70,9 @@ static class TabMain : public PreferencesTab { on_show_toolbars_change(); break; case IDC_RESET_TOOLBARS: { - if (win32_helpers::message_box(wnd, - _T("Warning! This will reset the toolbars to the default state. Continue?"), - _T("Reset toolbars?"), MB_YESNO) - == IDYES) { + if (cui::dark::modal_info_box(wnd, "Reset toolbars", + "Warning! This will reset the toolbars to the default state. Continue?", + uih::InfoBoxType::Neutral, uih::InfoBoxModalType::YesNo)) { if (cui::main_window.get_wnd()) cui::rebar::destroy_rebar(); cui::rebar::g_cfg_rebar.reset(); diff --git a/ui_helpers b/ui_helpers index aa87849d..5c72db61 160000 --- a/ui_helpers +++ b/ui_helpers @@ -1 +1 @@ -Subproject commit aa87849da0892b162069324606f564fe286e8a40 +Subproject commit 5c72db6113c0e5bf9984a9b78b31bf204222d0b3