diff foosdk/sdk/foobar2000/helpers/BumpableElem.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/BumpableElem.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <libPPUI/CFlashWindow.h>
+#include "atl-misc.h"
+
+#include <utility>
+
+template<typename TClass>
+class ImplementBumpableElem : public TClass {
+private:
+	typedef ImplementBumpableElem<TClass> TSelf;
+public:
+	template<typename ... arg_t> ImplementBumpableElem( arg_t && ... arg ) : TClass(std::forward<arg_t>(arg) ... ) {_init(); }
+
+	BEGIN_MSG_MAP_EX(ImplementBumpableElem)
+		MSG_WM_DESTROY(OnDestroy)
+		CHAIN_MSG_MAP(__super)
+	END_MSG_MAP_HOOK()
+
+	void notify(const GUID & p_what, t_size p_param1, const void * p_param2, t_size p_param2size) override {
+		if (p_what == ui_element_notify_visibility_changed && p_param1 == 0 && m_flash.m_hWnd != NULL) m_flash.Deactivate();
+		__super::notify(p_what, p_param1, p_param2, p_param2size);
+	}
+
+	static bool Bump() {
+		for (auto& walk : instances) {
+			if (walk->_bump()) return true;
+		}
+		return false;
+	}
+	~ImplementBumpableElem() throw() {
+		PFC_ASSERT(core_api::is_main_thread());
+		instances -= this;
+	}
+private:
+	void OnDestroy() throw() {
+		m_selfDestruct = true;
+		m_flash.CleanUp();
+		SetMsgHandled(FALSE);
+	}
+	bool _bump() {
+		if (m_selfDestruct || this->m_hWnd == NULL) return false;
+		//PROBLEM: This assumes we're implementing service_base methods at this point. Explodes if called during constructors/destructors.
+		if (!this->m_callback->request_activation(this)) return false;
+		m_flash.Activate(*this);
+		this->set_default_focus();
+		return true;
+	}
+	void _init() {
+		PFC_ASSERT(core_api::is_main_thread());
+		instances += this;
+	}
+	static pfc::avltree_t<TSelf*> instances;
+	bool m_selfDestruct = false;
+	CFlashWindow m_flash;
+};
+
+template<typename TClass>
+pfc::avltree_t<ImplementBumpableElem<TClass> *> ImplementBumpableElem<TClass>::instances;
+
+
+template<typename TImpl, typename TInterface = ui_element_v2> class ui_element_impl_withpopup : public ui_element_impl<ImplementBumpableElem<TImpl>, TInterface> {
+public:
+	t_uint32 get_flags() {return ui_element_v2::KFlagHavePopupCommand | ui_element_v2::KFlagSupportsBump;}
+	bool bump() {return ImplementBumpableElem<TImpl>::Bump();}
+};
+
+template<typename TImpl, typename TInterface = ui_element_v2> class ui_element_impl_visualisation : public ui_element_impl<ImplementBumpableElem<TImpl>, TInterface> {
+public:
+	t_uint32 get_flags() {return ui_element_v2::KFlagsVisualisation | ui_element_v2::KFlagSupportsBump;}
+	bool bump() {return ImplementBumpableElem<TImpl>::Bump();}
+};