You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
8.1 KiB
311 lines
8.1 KiB
#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; i<GetItemCount(); i++)
|
|
{
|
|
dwState=WndState_Normal;
|
|
if(i == m_nCurrentPage) dwState=WndState_PushDown;
|
|
else if(i== m_nHoverTabItem) dwState=WndState_Hover;
|
|
|
|
GetItemRect(i,rcItem);
|
|
//画分隔线
|
|
if(i>0 && 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<IFont> oldFont;
|
|
if(font) pRT->SelectObject(font,(IRenderObj**)&oldFont);
|
|
COLORREF crOld = 0;
|
|
if(crTxt != CR_INVALID) crOld = pRT->SetTextColor(crTxt);
|
|
|
|
STabPage2 *pPage = sobj_cast<STabPage2>(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<STabPage2>(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<EventTabItemHover>(pEvt);
|
|
STabPage2 *pPage = sobj_cast<STabPage2>(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<EventTabItemLeave>(pEvt);
|
|
STabPage2 *pPage = sobj_cast<STabPage2>(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);
|
|
}
|
|
|
|
}
|
|
|