创建
窗口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
#ifndef COMMONLY_USED_TOOLS_DLG_H #define COMMONLY_USED_TOOLS_DLG_H #include "IXunYouFrameworkWrap.h" class CToolsAdapter; class CommonlyUsedToolsWnd : public SXYHostDialog { SOUI_CLASS_NAME(CommonlyUsedToolsWnd, L"CommonlyUsedToolsWnd"); public: class Delegate { public: virtual void UpdateFlowsData(unsigned long long data) = 0; virtual void AccelDisconnected() = 0; virtual void ReportGameFlow() = 0; }; CommonlyUsedToolsWnd(); ~CommonlyUsedToolsWnd(); void UpdateFlowData(unsigned long long data); void AccelDisconnected(); private: void InitControls(); void AniShow(); void AniHide(); bool OnBkgAlphaAniEx(EventArgs* pEvt); bool OnItemAlphaAniEx(EventArgs* pEvt); bool OnBackBtnAlphaAniEx(EventArgs* pEvt); bool OnTileviewAlphaAniEx(EventArgs* pEvt); private: int OnCreate(LPCREATESTRUCT lpCreateStruct); BOOL OnInitDialog(HWND wnd, LPARAM lInitParam); void OnShowWindow(BOOL bShow, UINT nStatus); void OnClose(); void OnCloseClick(); void ReportCloseAction(); protected: EVENT_MAP_BEGIN() EVENT_NAME_COMMAND(L"toolsbox_back_btn", OnCloseClick) EVENT_MAP_END() BEGIN_MSG_MAP_EX(CommonlyUsedToolsWnd) MSG_WM_CREATE(OnCreate) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_CLOSE(OnClose) MSG_WM_SHOWWINDOW(OnShowWindow) CHAIN_MSG_MAP(SXYHostDialog) REFLECT_NOTIFICATIONS_EX() END_MSG_MAP() private: CAutoRefPtr<CToolsAdapter> m_pAdapter; int m_nowaniitem; int m_aniitemendid; int m_enddialogcode; }; #endif // COMMONLY_USED_TOOLS_DLG_H |
动画事件
- 这个初始化函数会在OnInitDialog里面调用,OnInitDialog对应到了MSG_WM_INITDIALOG消息
- 可以看到,这里给目标对象,背景图片,添加了阿尔法值变化的相关事件(开始和结束),并绑定到了OnBkgAlphaAniEx函数上
- 当启动动画时,会在动画开始前触发EventAlphaAnimateStartEx,进到这个函数里来,动画完成后,会触发EventAlphaAnimateStopEx进到这个函数里来
- 这个地方另外还初始化了一些tileview的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
void CommonlyUsedToolsWnd::InitControls() { auto bkg = FindChildByName2<SWindow>(L"main_wnd"); if (bkg) { bkg->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStartEx)); bkg->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStopEx)); bkg->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_START_EX, Subscriber(&CommonlyUsedToolsWnd::OnBkgAlphaAniEx, this)); bkg->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_STOP_EX, Subscriber(&CommonlyUsedToolsWnd::OnBkgAlphaAniEx, this)); } SOUI::STileView* pTileView = FindChildByName2<SOUI::STileView>(L"accel_tileview"); if (pTileView) { m_pAdapter = new CToolsAdapter(); pTileView->SetAdapter(m_pAdapter); } } |
通知
- 别的地方会发通知,CommonlyUsedToolsUIComponent会响应对应通知,并调用Show
- 关于通知机制,在上一篇有介绍
1 2 3 4 5 6 |
HRESULT CommonlyUsedToolsUIComponent::Show(LPARAM lParam) { CommonlyUsedToolsWnd commonlyUsedToolsWnd; INT_PTR result = commonlyUsedToolsWnd.DoModal(g_pFramework->GetHostWnd()); return S_OK; } |
触发展示
- 窗口的真正展示是上面的Show
- 而动画的AniShow是在MSG_WM_SHOWWINDOW的消息映射函数OnShowWindow里面启动的。
- 可以看到,是针对阿尔法值的改变
1 2 3 4 5 6 7 8 |
void CommonlyUsedToolsWnd::AniShow() { auto alphaani = _AlphaAniHelper->Add(FindChildByName2<SWindow>(L"main_wnd"), 300, 0, 255, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (alphaani) { alphaani->StartAni(); } } |
- 然后触发以动画开始前的事件触发OnBkgAlphaAniEx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
bool CommonlyUsedToolsWnd::OnBkgAlphaAniEx(EventArgs* pEvt) { if (pEvt->GetID() == EventAlphaAnimateStartEx::EventID) { EventAlphaAnimateStartEx* e = static_cast<EventAlphaAnimateStartEx*>(pEvt); if (atv_out == e->nValue) { FindChildByName2<SWindow>(L"main_wnd")->EnableWindow(false, true); _SetUIObjectAlpha(sobj_cast<SWindow>(pEvt->sender), 0); FindChildByName2<SWindow>(L"toolsbox_back_btn")->SetVisible(false, true); FindChildByName2<SOUI::STileView>(L"accel_tileview")->SetVisible(false, true); } } if (pEvt->GetID() == EventAlphaAnimateStopEx::EventID) { EventAlphaAnimateStopEx* e = static_cast<EventAlphaAnimateStopEx*>(pEvt); if (atv_out == e->nValue) { for (size_t i = 0; i < m_pAdapter->GetAniItemCount(); i++) { auto item = m_pAdapter->GetAniItem(i); if (item && item->IsVisible()) { item->SetID(i); _SetUIObjectAlpha(item, 0); item->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStartEx)); item->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStopEx)); item->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStepEx)); item->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_START_EX, Subscriber(&CommonlyUsedToolsWnd::OnItemAlphaAniEx, this)); item->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_STOP_EX, Subscriber(&CommonlyUsedToolsWnd::OnItemAlphaAniEx, this)); item->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_STEP_EX, Subscriber(&CommonlyUsedToolsWnd::OnItemAlphaAniEx, this)); } } FindChildByName2<SOUI::STileView>(L"accel_tileview")->SetVisible(true, true); for (size_t i = 0; i < 2; i++) { auto item = m_pAdapter->GetAniItem(i); if (item && item->IsVisible()) { auto alphaani = _AlphaAniHelper->Add(item, 150, 0, 255, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (alphaani) { alphaani->StartAni(); } auto rect = item->GetWindowRect(); auto beginrect = CRect(rect.left, rect.top + 40, rect.right, rect.bottom + 40); auto posani = _PosAniHelper->Add(item, 150, beginrect, rect, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (posani) { m_nowaniitem = i; posani->StartAni(); } } } } if (atv_back == e->nValue) { FindChildByName2<SWindow>(L"main_wnd")->EnableWindow(true, true); EndDialog(m_enddialogcode); } } return true; } |
- 可以再上面看到,在开始主窗口的阿尔法变化之前,把窗口上的一些元素置为不可见
- 动画完成后,以动画完成的事件触发OnBkgAlphaAniEx,可以看到,针对tileview给每个item添加了阿尔法值变化的相关事件(开始,结束,步进变化),并绑定到了函数OnItemAlphaAniEx上了,才把tileview置为可见
- 然后针对tileview的每个item,先启动了一个阿尔法值变化的动画,紧接着启动了一个位置变化的动画
触发消失
tileview
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
#ifndef COMMONLY_USERD_TOOLS_ADAPTER_H #define COMMONLY_USERD_TOOLS_ADAPTER_H #include "..\..\helper\EnvHelper.h" #include <helper/SAdapterBase.h> #include "CommonlyUsedToolsWnd.h" class CToolsAdapter : public SAdapterBase, CommonlyUsedToolsWnd::Delegate { public: CToolsAdapter(); ~CToolsAdapter(); enum item { item_accel = 0, item_netreset, item_log, }; // from Delegate void UpdateFlowsData(unsigned long long data); void AccelDisconnected(); void ReportGameFlow(); // from SAdapterBase int getCount() override; void getView(int position, SWindow* pItem, pugi::xml_node xmlTemplate) override; int getItemViewType(int position, DWORD dwState) override; int getViewTypeCount() override; void ClearAniItem(); size_t GetAniItemCount(); SWindow* GetAniItem(size_t index); private: bool OnNetResetUseButtonClick(EventArgs* pEvt); bool OnLogUseButtonClick(EventArgs* pEvt); bool OnTemplateHover(EventArgs* pEvt); bool OnTemplateLeave(EventArgs* pEvt); void UpdateFlowText(SStatic* pTextFlow, SStatic* pTextFlowExt, SStatic* pTextGameName); SStringW ConvertFromFlowData(unsigned long long data, SStringW& strFormat); private: SStringW m_strFlow; SStringW m_strFormat; std::vector<SWindow*> m_aniitemlist; }; #endif // COMMONLY_USERD_TOOLS_ADAPTER_H |
- 这个被构造后,会根据xml的模板的定义,根据设置的数量,进入同次数的getview,对tileview的每个item,进行相关工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<tileview name="accel_tileview" pos="16,76,-0,-0" wantTab="1" sbSkin="skin_vertical_scrollbar" sbLeft="24" sbBottom="24" marginSize="-4"> <template itemWidth="412" itemHeight="158" trackMouseEvent="1" > <itemnormal colorSelected="#ffffff00"> <window name="accel_tileview_wnd" pos="0,0,-0,-0" skin="skin_toolsbox_item_bk" trackMouseEvent="1"> <text name="title_text" pos="128,36,@-1,@-1" colorText="@color/toolsboxTitleColor" /> <text name="detail_text" pos="{0,[8,@-1,@-1" colorText="@color/toolsboxDetailTextColor" font="adding:-2" multiLines="1" maxwidth="180"/> <imgbtn name="use_button" pos="-98,28,@64,@24" skin="skin_toolsbox_use_button" visible="0" cursor="hand" animate="1"/> </window> </itemnormal> <itemflow colorSelected="#ffffff00"> <window name="accel_tileview_wnd" pos="0,0,-0,-0" skin="skin_toolsbox_item_bk" trackMouseEvent="1"> <text name="flow_text" pos="49,51,@46,@18" colorText="@color/toolsboxTitleColor" align="center"/> <text name="flow_text_ext" pos="58,68,@29,@17" colorText="@color/toolsboxTitleColor" font="adding:-2" align="center"/> <text name="title_text" pos="128,36,@-1,@-1" colorText="@color/toolsboxTitleColor" /> <text name="game_name_text" pos="{0,[4,@180,@-1" colorText="@color/toolsboxGameNameColor" display="0" maxwidth="180" dotted="1" msgTransparent="0"/> <text name="detail_text" pos="{0,[8,@-1,@-1" colorText="@color/toolsboxDetailTextColor" font="adding:-2" multiLines="1" maxwidth="180"/> </window> </itemflow> </template> </tileview> |
1 2 3 4 |
int CToolsAdapter::getCount() { return toolsbox::tools_item_count; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
void CToolsAdapter::getView(int position, SWindow* pItem, pugi::xml_node xmlTemplate) { int nViewType = getItemViewType(position, pItem->GetState()); if (pItem->GetChildrenCount() == 0) { pItem->InitFromXml(xmlTemplate.child(toolsbox::KNodeName_Item[nViewType])); m_aniitemlist.push_back(pItem); } SWindow* pAccelIconWnd = pItem->FindChildByName2<SWindow>(L"accel_tileview_wnd"); if (nViewType == 0) { pAccelIconWnd->SetUserData(position); pAccelIconWnd->GetEventSet()->subscribeEvent(SOUI::EVT_MOUSE_HOVER, SOUI::Subscriber(&CToolsAdapter::OnTemplateHover, this)); pAccelIconWnd->GetEventSet()->subscribeEvent(SOUI::EVT_MOUSE_LEAVE, SOUI::Subscriber(&CToolsAdapter::OnTemplateLeave, this)); } SStatic* pTextTitle = pItem->FindChildByName2<SStatic>(L"title_text"); SStatic* pTextDetail = pItem->FindChildByName2<SStatic>(L"detail_text"); switch (position) { case item::item_accel: { pAccelIconWnd->SetAttribute(L"skin", L"skin_toolsbox_item_accel_icon"); pTextTitle->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_Accel")); pTextDetail->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_AccelDetail")); SStatic* pTextGameName = pItem->FindChildByName2<SStatic>(L"game_name_text"); SStatic* pTextFlow = pItem->FindChildByName2<SStatic>(L"flow_text"); SStatic* pTextFlowExt = pItem->FindChildByName2<SStatic>(L"flow_text_ext"); UpdateFlowText(pTextFlow, pTextFlowExt, pTextGameName); } break; case item::item_netreset: { pAccelIconWnd->SetAttribute(L"skin", L"skin_toolsbox_item_netreset_icon"); pTextTitle->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_NetReset")); pTextDetail->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_NetResetDetail")); SImageButton* pUseBtn = pItem->FindChildByName2<SImageButton>(L"use_button"); pUseBtn->GetEventSet()->subscribeEvent(SOUI::EVT_CMD, SOUI::Subscriber(&CToolsAdapter::OnNetResetUseButtonClick, this)); } break; case item::item_log: { pAccelIconWnd->SetAttribute(L"skin", L"skin_toolsbox_item_log_icon"); pTextTitle->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_Log")); pTextDetail->SetWindowTextW(GETSTRING(L"@string/toolsBoxText_LogDetail")); SImageButton* pUseBtn = pItem->FindChildByName2<SImageButton>(L"use_button"); pUseBtn->GetEventSet()->subscribeEvent(SOUI::EVT_CMD, SOUI::Subscriber(&CToolsAdapter::OnLogUseButtonClick, this)); } break; default: break; } } |
- 可以看到,根据我们既定的目标,对他们使用不同的template进行构造,并且在构造后,把所有的item做一个保存,目的是为了针对具体空间对象启动动画
1 2 3 4 5 6 7 8 9 10 11 |
namespace toolsbox { const int tools_item_count = 3; const wchar_t* KNodeName_Item[] = { L"itemnormal", L"itemflow" }; const wchar_t* format[] = { L"B", L"KB", L"MB", L"GB" }; } |
1 2 3 4 5 6 7 |
int CToolsAdapter::getItemViewType(int position, DWORD dwState) { if (position == item::item_accel) { return 1; } return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
bool CommonlyUsedToolsWnd::OnItemAlphaAniEx(EventArgs* pEvt) { if (pEvt->GetID() == EventAlphaAnimateStartEx::EventID) { EventAlphaAnimateStartEx* e = static_cast<EventAlphaAnimateStartEx*>(pEvt); if (atv_out == e->nValue) { } if (atv_back == e->nValue) { } } if (pEvt->GetID() == EventAlphaAnimateStopEx::EventID) { EventAlphaAnimateStopEx* e = static_cast<EventAlphaAnimateStopEx*>(pEvt); if (atv_out == e->nValue) { auto id = sobj_cast<SWindow>(pEvt->sender)->GetID(); if (id == m_aniitemendid) { m_aniitemendid = -1; m_nowaniitem = -1; m_pAdapter->ClearAniItem(); auto backbtn = FindChildByName2<SWindow>(L"toolsbox_back_btn"); backbtn->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStartEx)); backbtn->GetEventSet()->addEvent(EVENTID(EventAlphaAnimateStopEx)); backbtn->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_START_EX, Subscriber(&CommonlyUsedToolsWnd::OnBackBtnAlphaAniEx, this)); backbtn->GetEventSet()->subscribeEvent(EVT_ALPHA_ANI_STOP_EX, Subscriber(&CommonlyUsedToolsWnd::OnBackBtnAlphaAniEx, this)); auto alphaani = _AlphaAniHelper->Add(backbtn, 150, 0, 255, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (alphaani) { alphaani->StartAni(); } } } if (atv_back == e->nValue) { } } if (pEvt->GetID() == EventAlphaAnimateStepEx::EventID) { EventAlphaAnimateStepEx* e = static_cast<EventAlphaAnimateStepEx*>(pEvt); if (atv_out == e->nValue) { if (e->nStep == 8) { auto item = m_pAdapter->GetAniItem(++m_nowaniitem); if (item && item->IsVisible()) { auto alphaani = _AlphaAniHelper->Add(item, 150, 0, 255, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (alphaani) { alphaani->StartAni(); } auto rect = item->GetWindowRect(); auto beginrect = CRect(rect.left, rect.top + 40, rect.right, rect.bottom + 40); auto posani = _PosAniHelper->Add(item, 150, beginrect, rect, atv_out, CREATEINTERPOLATOR(SDecelerateInterpolator::GetClassName())); if (posani) { posani->StartAni(); } } if (!item) { m_aniitemendid = sobj_cast<SWindow>(e->sender)->GetID(); } } } if (atv_back == e->nValue) { } } return true; } |
- 可以看到,当tileview的item的动画结束后,启动关闭按钮的显示动画
本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ C++标准库_cfenv02/14
- ♥ C++11_第二篇12/03
- ♥ COM组件_101/31
- ♥ CLion:配置C++下lua开发环境06/03
- ♥ Windows进程通信相关03/10
- ♥ C++17_第二篇12/22