Files
foobar2000-sdk/foobar2000/ATLHelpers/BumpableElem.h

73 lines
2.3 KiB
C++

#pragma once
#include "CFlashWindow.h"
#include "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) {
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.cfirst(); walk.is_valid(); ++walk) {
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 || 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() {
m_selfDestruct = false;
PFC_ASSERT(core_api::is_main_thread());
instances += this;
}
static pfc::avltree_t<TSelf*> instances;
bool m_selfDestruct;
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 KFlagHavePopupCommand | 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 KFlagsVisualisation | KFlagSupportsBump;}
bool bump() {return ImplementBumpableElem<TImpl>::Bump();}
};