Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/helpers/dsp_dialog.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/dsp_dialog.h Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,85 @@ +#pragma once +#ifdef _WIN32 +#include "atl-misc.h" + +// dsp_dialog.h +// DSP UI helper +// Simplifies implementation of DSP configuration popups, removes the need for separate blocking/nonblocking dialog routing all calls to one dialog class. +// Your dialog_t class must be WTL dialog taking dsp_preset_edit_callback_v2::ptr parameter in constructor. +// Do not call EndDialog(), DestroyWindow() etc, only use the provided callback's dsp_dialog_done() to make your dialog disappear. + +template<typename dialog_t> +void dsp_dialog_v2(const dsp_preset& p_data, HWND p_parent, dsp_preset_edit_callback& p_callback) { + core_api::ensure_main_thread(); + + class mycallback : public dsp_preset_edit_callback_v2 { + public: + void get_preset(dsp_preset& outPreset) override { + outPreset = m_state; + } + void set_preset(const dsp_preset& inPreset) { m_state = inPreset; if (m_chain) m_chain->on_preset_changed(inPreset); } + void dsp_dialog_done(bool bOK) override { + if (m_dialog) m_dialog->EndDialog(bOK ? IDOK : IDCANCEL); + } + + dsp_preset_impl m_state; + dsp_preset_edit_callback* m_chain = nullptr; + dialog_t* m_dialog = nullptr; + }; + + + auto cb = fb2k::service_new<mycallback>(); + cb->m_state = p_data; + auto toggle = pfc::autoToggle(cb->m_chain, &p_callback); + ImplementModalTracking< dialog_t > dialog(cb); + auto toggle2 = pfc::autoToggle(cb->m_dialog, &dialog); + dialog.DoModal(p_parent); +} + +template<typename dialog_t> +class _dialog_as_service : public dialog_t, public service_base { +public: + template<typename ... arg_t> _dialog_as_service(arg_t && ... arg) : dialog_t(std::forward<arg_t>(arg) ...) {} +}; + +template<typename dialog_t> +service_ptr dsp_dialog_v3(HWND parent, dsp_preset_edit_callback_v2::ptr callback) { + class mycallback : public dsp_preset_edit_callback_v2 { + public: + void get_preset(dsp_preset& outPreset) override { m_chain->get_preset(outPreset); } + void set_preset(const dsp_preset& inPreset) { m_chain->set_preset(inPreset); } + void dsp_dialog_done(bool bOK) override { + m_chain->dsp_dialog_done(bOK); + m_dialog->DestroyWindow(); + } + dsp_preset_edit_callback_v2::ptr m_chain; + dialog_t* m_dialog = nullptr; + }; + auto cb = fb2k::service_new< mycallback >(); + cb->m_chain = callback; + auto obj = fb2k::service_new_window<ImplementModelessTracking< _dialog_as_service< dialog_t > > >(cb); + cb->m_dialog = &*obj; + WIN32_OP_D(obj->Create(parent)); obj->ShowWindow(SW_SHOW); + return obj; +} +#endif + +template<typename dsp_t, typename dialog_t> +class dsp_impl_with_ui : public dsp_entry_common_t<dsp_t, dsp_entry_v3> { +public: + void get_display_name(const dsp_preset& arg, pfc::string_base& out) override { + dsp_t::g_get_display_name(arg, out); + } +#ifdef _WIN32 + void show_config_popup_v2(const dsp_preset& p_data, fb2k::hwnd_t p_parent, dsp_preset_edit_callback& p_callback) override { + dsp_dialog_v2<dialog_t>(p_data, p_parent, p_callback); + } + service_ptr show_config_popup_v3(fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback) override { + return dsp_dialog_v3<dialog_t>(parent, callback); + } +#else + service_ptr show_config_popup(fb2k::hwnd_t parent, dsp_preset_edit_callback_v2::ptr callback) override { + return dialog_t::show_config_popup(parent, callback); + } +#endif +};
