|
1
|
1 #pragma once
|
|
|
2
|
|
|
3 #include <libPPUI/CFlashWindow.h>
|
|
|
4 #include "atl-misc.h"
|
|
|
5
|
|
|
6 #include <utility>
|
|
|
7
|
|
|
8 template<typename TClass>
|
|
|
9 class ImplementBumpableElem : public TClass {
|
|
|
10 private:
|
|
|
11 typedef ImplementBumpableElem<TClass> TSelf;
|
|
|
12 public:
|
|
|
13 template<typename ... arg_t> ImplementBumpableElem( arg_t && ... arg ) : TClass(std::forward<arg_t>(arg) ... ) {_init(); }
|
|
|
14
|
|
|
15 BEGIN_MSG_MAP_EX(ImplementBumpableElem)
|
|
|
16 MSG_WM_DESTROY(OnDestroy)
|
|
|
17 CHAIN_MSG_MAP(__super)
|
|
|
18 END_MSG_MAP_HOOK()
|
|
|
19
|
|
|
20 void notify(const GUID & p_what, t_size p_param1, const void * p_param2, t_size p_param2size) override {
|
|
|
21 if (p_what == ui_element_notify_visibility_changed && p_param1 == 0 && m_flash.m_hWnd != NULL) m_flash.Deactivate();
|
|
|
22 __super::notify(p_what, p_param1, p_param2, p_param2size);
|
|
|
23 }
|
|
|
24
|
|
|
25 static bool Bump() {
|
|
|
26 for (auto& walk : instances) {
|
|
|
27 if (walk->_bump()) return true;
|
|
|
28 }
|
|
|
29 return false;
|
|
|
30 }
|
|
|
31 ~ImplementBumpableElem() throw() {
|
|
|
32 PFC_ASSERT(core_api::is_main_thread());
|
|
|
33 instances -= this;
|
|
|
34 }
|
|
|
35 private:
|
|
|
36 void OnDestroy() throw() {
|
|
|
37 m_selfDestruct = true;
|
|
|
38 m_flash.CleanUp();
|
|
|
39 SetMsgHandled(FALSE);
|
|
|
40 }
|
|
|
41 bool _bump() {
|
|
|
42 if (m_selfDestruct || this->m_hWnd == NULL) return false;
|
|
|
43 //PROBLEM: This assumes we're implementing service_base methods at this point. Explodes if called during constructors/destructors.
|
|
|
44 if (!this->m_callback->request_activation(this)) return false;
|
|
|
45 m_flash.Activate(*this);
|
|
|
46 this->set_default_focus();
|
|
|
47 return true;
|
|
|
48 }
|
|
|
49 void _init() {
|
|
|
50 PFC_ASSERT(core_api::is_main_thread());
|
|
|
51 instances += this;
|
|
|
52 }
|
|
|
53 static pfc::avltree_t<TSelf*> instances;
|
|
|
54 bool m_selfDestruct = false;
|
|
|
55 CFlashWindow m_flash;
|
|
|
56 };
|
|
|
57
|
|
|
58 template<typename TClass>
|
|
|
59 pfc::avltree_t<ImplementBumpableElem<TClass> *> ImplementBumpableElem<TClass>::instances;
|
|
|
60
|
|
|
61
|
|
|
62 template<typename TImpl, typename TInterface = ui_element_v2> class ui_element_impl_withpopup : public ui_element_impl<ImplementBumpableElem<TImpl>, TInterface> {
|
|
|
63 public:
|
|
|
64 t_uint32 get_flags() {return ui_element_v2::KFlagHavePopupCommand | ui_element_v2::KFlagSupportsBump;}
|
|
|
65 bool bump() {return ImplementBumpableElem<TImpl>::Bump();}
|
|
|
66 };
|
|
|
67
|
|
|
68 template<typename TImpl, typename TInterface = ui_element_v2> class ui_element_impl_visualisation : public ui_element_impl<ImplementBumpableElem<TImpl>, TInterface> {
|
|
|
69 public:
|
|
|
70 t_uint32 get_flags() {return ui_element_v2::KFlagsVisualisation | ui_element_v2::KFlagSupportsBump;}
|
|
|
71 bool bump() {return ImplementBumpableElem<TImpl>::Bump();}
|
|
|
72 };
|