#include "souistd.h" #include "Stabctrl2.h" #include "SAnimImg.h" namespace SOUI { SPageAniObj::SPageAniObj() :m_aniStatus(STATUS_NOR) ,m_iFrame(0) ,m_tmWaitFor(0) ,m_pAniIn(NULL) ,m_pAniOut(NULL) { } BOOL SPageAniObj::Draw(IRenderTarget *pRT,const CRect &rc) { if(m_aniStatus == STATUS_IN) { if(m_pAniIn) { m_pAniIn->DrawByIndex(pRT,rc, m_iFrame); return TRUE; } }else if(m_aniStatus == STATUS_OUT) { if(m_pAniOut) { m_pAniOut->DrawByIndex(pRT,rc, m_iFrame); return TRUE; } } return FALSE; } BOOL SPageAniObj::OnNextFrame(int nIntervel) { if(m_aniStatus == STATUS_NOR) return FALSE; m_tmWaitFor -= 10; if(m_tmWaitFor>0) return FALSE; m_iFrame++; if(m_aniStatus == STATUS_IN) { if(!m_pAniIn) m_aniStatus = STATUS_NOR; else if(m_iFrame>=m_pAniIn->GetStates() - 1) { m_iFrame = m_pAniIn->GetStates() - 1; } }else { if(!m_pAniOut || m_iFrame>=m_pAniOut->GetStates() -1 ) { m_aniStatus = STATUS_NOR; } } m_tmWaitFor = nIntervel; return TRUE; } void SPageAniObj::AnimateOut(int nInterval) { m_aniStatus = STATUS_OUT; m_iFrame = 0; m_tmWaitFor = nInterval; } void SPageAniObj::AnimateIn(int nInterval) { m_aniStatus = STATUS_IN; m_iFrame = 0; m_tmWaitFor = nInterval; } /////////////////////////////////////////////////////////////////////////////////////////// STabPage2::STabPage2(void) { } STabPage2::~STabPage2(void) { } STabCtrl2::STabCtrl2(void): m_pSkinHeadBg(NULL), m_iInterval(50) { } STabCtrl2::~STabCtrl2(void) { } void STabCtrl2::OnPaint(IRenderTarget *pRT) { SPainter painter; BeforePaint(pRT,painter); CRect rcItem,rcItemPrev,rcItem2Draw; CRect rcSplit; DWORD dwState; CRect rcTitle=GetTitleRect(); pRT->PushClipRect(&rcTitle,RGN_AND); if(m_pSkinHeadBg) { m_pSkinHeadBg->DrawByIndex(pRT,rcTitle,WndState_Normal); } for(size_t i=0; i0 && m_pSkinTabInter && ((i < (m_nCurrentPage)) || (i > (m_nCurrentPage+1))/*选中页左右不用画分隔线*/)) { rcSplit=rcItem; if(m_nTabAlign==AlignLeft) { rcSplit.top=rcItemPrev.bottom; rcSplit.bottom = rcSplit.top + m_nTabInterSize.toPixelSize(GetScale()); } else { rcSplit.left=rcItemPrev.right; rcSplit.right=rcSplit.left + m_nTabInterSize.toPixelSize(GetScale()); } m_pSkinTabInter->DrawByIndex(pRT,rcSplit,0); } rcItemPrev=rcItem; if (dwState == WndState_PushDown && m_pSkinTabInter) {//如果有分割线,这种状态覆盖掉(模仿360的某个subtab) if(m_nTabAlign ==AlignLeft) { rcItem.top -= m_nTabInterSize.toPixelSize(GetScale()); rcItem.bottom += m_nTabInterSize.toPixelSize(GetScale()); } else { rcItem.left -= m_nTabInterSize.toPixelSize(GetScale()); rcItem.right += m_nTabInterSize.toPixelSize(GetScale()); } } DrawItem(pRT,rcItem,i,dwState); } pRT->PopClip(); if (m_pSkinFrame) { CRect rcPage = GetChildrenLayoutRect(); m_pSkinFrame->DrawByIndex(pRT, rcPage, WndState_Normal); } if(IsFocused() && IsFocusable() && m_bDrawFocusRect) { CRect rc; GetItemRect(m_nCurrentPage,rc); rc.DeflateRect(2,2); DrawDefFocusRect(pRT,&rc); } AfterPaint(pRT,painter); } void STabCtrl2::DrawItem(IRenderTarget *pRT,const CRect &rcItem,int iItem,DWORD dwState ) { if(rcItem.IsRectEmpty()) return; int iState = SState2Index::GetDefIndex(dwState,false); if(m_pSkinTab) m_pSkinTab->DrawByIndex(pRT,rcItem,iState); //根据状态从style中获得字体,颜色 IFontPtr font=m_style.GetTextFont(iState); COLORREF crTxt = m_style.GetTextColor(iState); CAutoRefPtr oldFont; if(font) pRT->SelectObject(font,(IRenderObj**)&oldFont); COLORREF crOld = 0; if(crTxt != CR_INVALID) crOld = pRT->SetTextColor(crTxt); STabPage2 *pPage = sobj_cast(m_lstPages.GetAt(iItem)); CRect rcIcon(rcItem.left+m_ptIcon[0].toPixelSize(GetScale()), rcItem.top+m_ptIcon[1].toPixelSize(GetScale()),0,0); if(m_pSkinIcon) { rcIcon.right = rcIcon.left+m_pSkinIcon->GetSkinSize().cx; rcIcon.bottom = rcIcon.top+m_pSkinIcon->GetSkinSize().cy; } if(!pPage->m_aniObj.Draw(pRT,rcIcon) && m_pSkinIcon) { int iIcon=GetItem(iItem)->GetIconIndex(); if(iIcon == -1) iIcon = iItem; m_pSkinIcon->DrawByIndex(pRT,rcIcon,iIcon); } if(!m_ptText[0].valueEqual(-1.f) && !m_ptText[1].valueEqual(-1.f)) {//从指定位置开始绘制文字 pRT->TextOut(rcItem.left+m_ptText[0].toPixelSize(GetScale()),rcItem.top+m_ptText[1].toPixelSize(GetScale()),GetItem(iItem)->GetTitle(),-1); } else { CRect rcText=rcItem; UINT alignStyle=m_style.GetTextAlign(); UINT align=alignStyle; if(m_ptText[0].valueEqual(-1.f) && !m_ptText[1].valueEqual(-1.f)) {//指定了Y偏移,X居中 rcText.top+=m_ptText[1].toPixelSize(GetScale()); align=alignStyle&(DT_CENTER|DT_RIGHT|DT_SINGLELINE|DT_END_ELLIPSIS); } else if(!m_ptText[0].valueEqual(-1.f) && m_ptText[1].valueEqual(-1.f)) {//指定了X偏移,Y居中 rcText.left+=m_ptText[0].toPixelSize(GetScale()); align=alignStyle&(DT_VCENTER|DT_BOTTOM|DT_SINGLELINE|DT_END_ELLIPSIS); } pRT->DrawText(GetItem(iItem)->GetTitle(),-1,&rcText,align); } //恢复字体,颜色 if(font) pRT->SelectObject(oldFont); if(crTxt!=CR_INVALID) pRT->SetTextColor(crOld); } void STabCtrl2::OnStateChanged( DWORD dwOldState,DWORD dwNewState ) { InvalidateRect(GetTitleRect()); __super::OnStateChanged(dwOldState, dwNewState); } void STabCtrl2::OnNextFrame() { for (int i = 0; i < m_lstPages.GetCount(); i ++) { STabPage2 *pPage = sobj_cast(m_lstPages.GetAt(i)); if(pPage->m_aniObj.OnNextFrame(m_iInterval)) { CRect rc; GetItemRect(i,rc); InvalidateRect(rc); } } } void STabCtrl2::OnDestroy() { GetContainer()->UnregisterTimelineHandler(this); __super::OnDestroy(); } int STabCtrl2::OnCreate(void*) { int iRet = __super::OnCreate(NULL); GetContainer()->RegisterTimelineHandler(this); GetEventSet()->subscribeEvent(EventTabItemHover::EventID,Subscriber(&STabCtrl2::OnItemHover,this)); GetEventSet()->subscribeEvent(EventTabItemLeave::EventID,Subscriber(&STabCtrl2::OnItemLeave,this)); return iRet; } bool STabCtrl2::OnItemHover(EventArgs *pEvt) { bool bRet = true; EventTabItemHover *pEvt2 = sobj_cast(pEvt); STabPage2 *pPage = sobj_cast(m_lstPages.GetAt(pEvt2->iHover)); pPage->m_aniObj.AnimateIn(m_iInterval); CRect rc; GetItemRect(pEvt2->iHover,rc); InvalidateRect(rc); return bRet; } bool STabCtrl2::OnItemLeave(EventArgs *pEvt) { bool bRet = true; EventTabItemLeave *pEvt2 = sobj_cast(pEvt); STabPage2 *pPage = sobj_cast(m_lstPages.GetAt(pEvt2->iLeave)); pPage->m_aniObj.AnimateOut(m_iInterval); CRect rc; GetItemRect(pEvt2->iLeave,rc); InvalidateRect(rc); return bRet; } STabPage * STabCtrl2::CreatePageFromXml(pugi::xml_node xmlPage) { if (wcscmp(xmlPage.name(),STabPage2::GetClassName()) != 0) return NULL; return (STabPage *)SApplication::getSingleton().CreateWindowByName(STabPage2::GetClassName()); } void STabCtrl2::OnContainerChanged(ISwndContainer *pOldContainer,ISwndContainer *pNewContainer) { if(pOldContainer) pOldContainer->UnregisterTimelineHandler(this); if(pNewContainer) pNewContainer->RegisterTimelineHandler(this); SWindow::OnContainerChanged(pOldContainer,pNewContainer); } }