nim_duilib/duilib/Core/Control.cpp

1694 lines
43 KiB
C++
Raw Normal View History

2019-04-19 17:19:57 +08:00
#include "StdAfx.h"
#include "shlwapi.h"
#include "../Animation/AnimationPlayer.h"
namespace ui
{
const int Control::m_nVirtualEventGifStop = 1;
Control::Control() :
OnXmlEvent(),
OnEvent(),
m_pUserDataBase(),
m_bMenuUsed(false),
m_bEnabled(true),
m_bMouseEnabled(true),
m_bKeyboardEnabled(true),
m_bFocused(false),
m_bMouseFocused(false),
m_bSetPos(false),
m_bNoFocus(false),
m_bClip(true),
m_bGifPlay(true),
m_bReceivePointerMsg(true),
m_bNeedButtonUpWhenKillFocus(false),
m_szEstimateSize(),
m_renderOffset(),
m_cxyBorderRound(),
m_rcMargin(),
m_rcPaint(),
m_rcBorderSize(),
m_cursorType(kCursorArrow),
m_uButtonState(kControlStateNormal),
m_nBorderSize(0),
m_nTooltipWidth(300),
m_nAlpha(255),
m_nHotAlpha(0),
m_sToolTipText(),
m_sToolTipTextId(),
m_sUserData(),
m_strBkColor(),
m_colorMap(),
m_strBorderColor(),
m_gifWeakFlag(),
m_animationManager(),
m_imageMap(),
m_bkImage(),
m_loadBkImageWeakFlag()
{
m_colorMap.SetControl(this);
m_imageMap.SetControl(this);
m_animationManager.Init(this);
}
Control::Control(const Control& r) :
PlaceHolder(r),
OnXmlEvent(),
OnEvent(),
m_pUserDataBase(),
m_bMenuUsed(r.m_bMenuUsed),
m_bEnabled(r.m_bEnabled),
m_bMouseEnabled(r.m_bMouseEnabled),
m_bKeyboardEnabled(r.m_bKeyboardEnabled),
m_bFocused(r.m_bFocused),
m_bMouseFocused(r.m_bMouseFocused),
m_bSetPos(r.m_bSetPos),
m_bNoFocus(r.m_bNoFocus),
m_bClip(r.m_bClip),
m_bGifPlay(r.m_bGifPlay),
m_bReceivePointerMsg(r.m_bReceivePointerMsg),
m_bNeedButtonUpWhenKillFocus(r.m_bNeedButtonUpWhenKillFocus),
m_szEstimateSize(r.m_szEstimateSize),
m_renderOffset(r.m_renderOffset),
m_cxyBorderRound(r.m_cxyBorderRound),
m_rcMargin(r.m_rcMargin),
m_rcPaint(r.m_rcPaint),
m_rcBorderSize(r.m_rcBorderSize),
m_cursorType(r.m_cursorType),
m_uButtonState(kControlStateNormal),
m_nBorderSize(r.m_nBorderSize),
m_nTooltipWidth(r.m_nTooltipWidth),
m_nAlpha(r.m_nAlpha),
m_nHotAlpha(r.m_nHotAlpha),
m_sToolTipText(r.m_sToolTipText),
m_sToolTipTextId(r.m_sToolTipTextId),
m_sUserData(r.m_sUserData),
m_strBkColor(r.m_strBkColor),
m_colorMap(r.m_colorMap),
m_strBorderColor(r.m_strBorderColor),
m_gifWeakFlag(),
m_animationManager(r.m_animationManager),
m_imageMap(r.m_imageMap),
m_bkImage(r.m_bkImage),
m_loadBkImageWeakFlag()
{
m_colorMap.SetControl(this);
m_imageMap.SetControl(this);
m_animationManager.Init(this);
if (r.m_bGifPlay)
{
this->GifPlay();
}
}
Control::~Control()
{
if (m_pWindow) {
m_pWindow->ReapObjects(this);
}
}
std::wstring Control::GetBkColor() const
{
return m_strBkColor;
}
void Control::SetBkColor(const std::wstring& strColor)
{
ASSERT(strColor.empty() || GlobalManager::GetTextColor(strColor) != 0);
if( m_strBkColor == strColor ) return;
m_strBkColor = strColor;
Invalidate();
}
std::wstring Control::GetStateColor(ControlStateType stateType)
{
return m_colorMap[stateType];
}
void Control::SetStateColor(ControlStateType stateType, const std::wstring& strColor)
{
ASSERT(GlobalManager::GetTextColor(strColor) != 0);
if( m_colorMap[stateType] == strColor ) return;
if (stateType == kControlStateHot) {
m_animationManager.SetFadeHot(true);
}
m_colorMap[stateType] = strColor;
Invalidate();
}
std::wstring Control::GetBkImage() const
{
return m_bkImage.imageAttribute.simageString;
}
std::string Control::GetUTF8BkImage() const
{
std::string strOut;
StringHelper::UnicodeToMBCS(m_bkImage.imageAttribute.simageString.c_str(), strOut, CP_UTF8);
return strOut;
}
void Control::SetBkImage(const std::wstring& strImage)
{
StopGifPlay();
m_bkImage.SetImageString(strImage);
m_bGifPlay = m_bkImage.imageAttribute.nPlayCount != 0;
if (GetFixedWidth() == DUI_LENGTH_AUTO || GetFixedHeight() == DUI_LENGTH_AUTO) {
ArrangeAncestor();
}
else {
Invalidate();
}
}
void Control::SetUTF8BkImage(const std::string& strImage)
{
std::wstring strOut;
StringHelper::MBCSToUnicode(strImage, strOut, CP_UTF8);
SetBkImage(strOut);
}
std::wstring Control::GetStateImage(ControlStateType stateType)
{
return m_imageMap.GetImagePath(kStateImageBk, stateType);
}
void Control::SetStateImage(ControlStateType stateType, const std::wstring& strImage)
{
if (stateType == kControlStateHot) {
m_animationManager.SetFadeHot(true);
}
m_imageMap.SetImage(kStateImageBk, stateType, strImage);
if (GetFixedWidth() == DUI_LENGTH_AUTO || GetFixedHeight() == DUI_LENGTH_AUTO) {
ArrangeAncestor();
}
else {
Invalidate();
}
}
std::wstring Control::GetForeStateImage(ControlStateType stateType)
{
return m_imageMap.GetImagePath(kStateImageFore, stateType);
}
void Control::SetForeStateImage(ControlStateType stateType, const std::wstring& strImage)
{
if (stateType == kControlStateHot) {
m_animationManager.SetFadeHot(true);
}
m_imageMap.SetImage(kStateImageFore, stateType, strImage);
Invalidate();
}
ControlStateType Control::GetState() const
{
return m_uButtonState;
}
void Control::SetState(ControlStateType pStrState)
{
if (pStrState == kControlStateNormal) {
m_nHotAlpha = 0;
}
else if (pStrState == kControlStateHot) {
m_nHotAlpha = 255;
}
m_uButtonState = pStrState;
Invalidate();
}
Image* Control::GetEstimateImage()
{
Image* estimateImage = nullptr;
if (!m_bkImage.imageAttribute.sImageName.empty()) {
estimateImage = &m_bkImage;
}
else {
estimateImage = m_imageMap.GetEstimateImage(kStateImageBk);
}
return estimateImage;
}
int Control::GetBorderSize() const
{
return m_nBorderSize;
}
void Control::SetBorderSize(int nSize)
{
DpiManager::GetInstance()->ScaleInt(nSize);
if (m_nBorderSize == nSize) return;
m_nBorderSize = nSize;
Invalidate();
}
std::wstring Control::GetBorderColor() const
{
return m_strBorderColor;
}
void Control::SetBorderColor(const std::wstring& strBorderColor)
{
if( m_strBorderColor == strBorderColor ) return;
m_strBorderColor = strBorderColor;
Invalidate();
}
void Control::SetBorderSize(UiRect rc)
{
DpiManager::GetInstance()->ScaleRect(rc);
m_rcBorderSize = rc;
Invalidate();
}
int Control::GetLeftBorderSize() const
{
return m_rcBorderSize.left;
}
void Control::SetLeftBorderSize(int nSize)
{
DpiManager::GetInstance()->ScaleInt(nSize);
m_rcBorderSize.left = nSize;
Invalidate();
}
int Control::GetTopBorderSize() const
{
return m_rcBorderSize.top;
}
void Control::SetTopBorderSize(int nSize)
{
DpiManager::GetInstance()->ScaleInt(nSize);
m_rcBorderSize.top = nSize;
Invalidate();
}
int Control::GetRightBorderSize() const
{
return m_rcBorderSize.right;
}
void Control::SetRightBorderSize(int nSize)
{
DpiManager::GetInstance()->ScaleInt(nSize);
m_rcBorderSize.right = nSize;
Invalidate();
}
int Control::GetBottomBorderSize() const
{
return m_rcBorderSize.bottom;
}
void Control::SetBottomBorderSize(int nSize)
{
DpiManager::GetInstance()->ScaleInt(nSize);
m_rcBorderSize.bottom = nSize;
Invalidate();
}
CSize Control::GetBorderRound() const
{
return m_cxyBorderRound;
}
void Control::SetBorderRound(CSize cxyRound)
{
DpiManager::GetInstance()->ScaleSize(cxyRound);
m_cxyBorderRound = cxyRound;
Invalidate();
}
CursorType Control::GetCursorType() const
{
return m_cursorType;
}
void Control::SetCursorType(CursorType flag)
{
m_cursorType = flag;
}
std::wstring Control::GetToolTipText() const
{
std::wstring strText = m_sToolTipText;
if (strText.empty() && !m_sToolTipTextId.empty()) {
strText = MutiLanSupport::GetInstance()->GetStringViaID(m_sToolTipTextId);
}
return strText;
}
std::string Control::GetUTF8ToolTipText() const
{
std::string strOut;
StringHelper::UnicodeToMBCS(GetToolTipText(), strOut, CP_UTF8);
return strOut;
}
void Control::SetToolTipText(const std::wstring& strText)
{
std::wstring strTemp(strText);
StringHelper::ReplaceAll(_T("<n>"),_T("\r\n"), strTemp);
m_sToolTipText = strTemp;
Invalidate();
}
void Control::SetUTF8ToolTipText(const std::string& strText)
{
std::wstring strOut;
StringHelper::MBCSToUnicode(strText, strOut, CP_UTF8);
if (strOut.empty()) {
m_sToolTipText = _T("");
Invalidate();//Ϊ<><CEAA><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ˢ
return ;
}
if (m_sToolTipText != strOut) {
SetToolTipText(strOut);
}
}
void Control::SetToolTipTextId(const std::wstring& strTextId)
{
if (m_sToolTipTextId == strTextId) return;
m_sToolTipTextId = strTextId;
Invalidate();
}
void Control::SetUTF8ToolTipTextId(const std::string& strTextId)
{
std::wstring strOut;
StringHelper::MBCSToUnicode(strTextId, strOut, CP_UTF8);
SetToolTipTextId(strOut);
}
void Control::SetToolTipWidth( int nWidth )
{
DpiManager::GetInstance()->ScaleInt(nWidth);
m_nTooltipWidth=nWidth;
}
int Control::GetToolTipWidth(void) const
{
return m_nTooltipWidth;
}
bool Control::IsContextMenuUsed() const
{
return m_bMenuUsed;
}
void Control::SetContextMenuUsed(bool bMenuUsed)
{
m_bMenuUsed = bMenuUsed;
}
std::wstring Control::GetDataID() const
{
return m_sUserData;
}
std::string Control::GetUTF8DataID() const
{
std::string strOut;
StringHelper::UnicodeToMBCS(m_sUserData, strOut, CP_UTF8);
return strOut;
}
void Control::SetDataID(const std::wstring& strText)
{
m_sUserData = strText;
}
void Control::SetUTF8DataID(const std::string& strText)
{
std::wstring strOut;
StringHelper::MBCSToUnicode(strText, strOut, CP_UTF8);
m_sUserData = strOut;
}
UserDataBase* Control::GetUserDataBase() const
{
return m_pUserDataBase.get();
}
void Control::SetUserDataBase(UserDataBase* pUserDataBase)
{
m_pUserDataBase.reset(pUserDataBase);
}
void Control::SetVisible(bool bVisible)
{
if (bVisible) {
m_animationManager.Appear();
}
else {
m_animationManager.Disappear();
}
}
void Control::SetInternVisible(bool bVisible)
{
m_bInternVisible = bVisible;
if (!bVisible && m_pWindow && m_pWindow->GetFocus() == this) {
m_pWindow->SetFocus(NULL) ;
}
if (!IsVisible()) {
StopGifPlay();
}
}
void Control::SetVisible_(bool bVisible)
{
if (m_bVisible == bVisible) return;
bool v = IsVisible();
m_bVisible = bVisible;
if (m_bFocused) m_bFocused = false;
if (!bVisible && m_pWindow && m_pWindow->GetFocus() == this) {
m_pWindow->SetFocus(NULL);
}
if (IsVisible() != v) {
ArrangeAncestor();
}
if (!IsVisible()) {
StopGifPlay();
}
}
bool Control::IsEnabled() const
{
return m_bEnabled;
}
void Control::SetEnabled(bool bEnabled)
{
if( m_bEnabled == bEnabled ) return;
m_bEnabled = bEnabled;
if (m_bEnabled) {
m_uButtonState = kControlStateNormal;
m_nHotAlpha = 0;
}
else {
m_uButtonState = kControlStateDisabled;
}
Invalidate();
}
bool Control::IsMouseEnabled() const
{
return m_bMouseEnabled;
}
void Control::SetMouseEnabled(bool bEnabled)
{
m_bMouseEnabled = bEnabled;
}
bool Control::IsKeyboardEnabled() const
{
return m_bKeyboardEnabled ;
}
void Control::SetKeyboardEnabled(bool bEnabled)
{
m_bKeyboardEnabled = bEnabled ;
}
bool Control::IsFocused() const
{
return m_bFocused;
}
void Control::SetFocus()
{
if( m_bNoFocus )
return;
if( m_pWindow != NULL ) m_pWindow->SetFocus(this);
}
UINT Control::GetControlFlags() const
{
return UIFLAG_TABSTOP;
}
2019-04-19 17:19:57 +08:00
void Control::SetNoFocus()
{
m_bNoFocus = true;
}
void Control::Activate()
{
}
bool Control::IsActivatable() const
{
if (!IsVisible()) return false;
if (!IsEnabled()) return false;
return true;
}
Control* Control::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags, CPoint scrollPos)
{
if( (uFlags & UIFIND_VISIBLE) != 0 && !IsVisible() ) return NULL;
if( (uFlags & UIFIND_ENABLED) != 0 && !IsEnabled() ) return NULL;
if( (uFlags & UIFIND_HITTEST) != 0 && (!m_bMouseEnabled || !::PtInRect(&m_rcItem, * static_cast<LPPOINT>(pData))) ) return NULL;
return Proc(this, pData);
}
UiRect Control::GetPos(bool bContainShadow) const
{
UiRect pos = m_rcItem;
if (m_pWindow && !bContainShadow) {
UiRect shadowLength = m_pWindow->GetShadowCorner();
pos.Offset(-shadowLength.left, -shadowLength.top);
}
return pos;
}
void Control::SetPos(UiRect rc)
{
if (rc.right < rc.left) rc.right = rc.left;
if (rc.bottom < rc.top) rc.bottom = rc.top;
if (m_rcItem.Equal(rc)) {
m_bIsArranged = false;
return;
}
UiRect invalidateRc = m_rcItem;
if (::IsRectEmpty(&invalidateRc)) invalidateRc = rc;
m_rcItem = rc;
if (m_pWindow == NULL) return;
if (!m_bSetPos) {
m_bSetPos = true;
m_pWindow->SendNotify(this, kEventResize, NULL, NULL);
m_bSetPos = false;
}
m_bIsArranged = false;
invalidateRc.Union(m_rcItem);
Control* pParent = this;
UiRect rcTemp;
UiRect rcParent;
CPoint offset = GetScrollOffset();
invalidateRc.Offset(-offset.x, -offset.y);
while ((pParent = pParent->GetParent()) != nullptr)
{
rcTemp = invalidateRc;
rcParent = pParent->GetPos();
if (!::IntersectRect(&invalidateRc, &rcTemp, &rcParent)) {
return;
}
}
m_pWindow->Invalidate(invalidateRc);
}
UiRect Control::GetMargin() const
{
return m_rcMargin;
}
void Control::SetMargin(UiRect rcMargin, bool bNeedDpiScale)
{
if (bNeedDpiScale)
DpiManager::GetInstance()->ScaleRect(rcMargin);
if (!m_rcMargin.Equal(rcMargin)) {
m_rcMargin = rcMargin;
ArrangeAncestor();
}
}
CSize Control::EstimateSize(CSize szAvailable)
{
CSize imageSize = m_cxyFixed;
if (GetFixedWidth() == DUI_LENGTH_AUTO || GetFixedHeight() == DUI_LENGTH_AUTO) {
if (!m_bReEstimateSize) {
return m_szEstimateSize;
}
Image* image = GetEstimateImage();
if (image) {
auto imageAttribute = image->imageAttribute;
if (imageAttribute.rcSource.left != DUI_NOSET_VALUE && imageAttribute.rcSource.top != DUI_NOSET_VALUE
&& imageAttribute.rcSource.right != DUI_NOSET_VALUE && imageAttribute.rcSource.bottom != DUI_NOSET_VALUE) {
if ((GetFixedWidth() != imageAttribute.rcSource.right - imageAttribute.rcSource.left)) {
SetFixedWidth(imageAttribute.rcSource.right - imageAttribute.rcSource.left);
}
if ((GetFixedHeight() != imageAttribute.rcSource.bottom - imageAttribute.rcSource.top)) {
SetFixedHeight(imageAttribute.rcSource.bottom - imageAttribute.rcSource.top);
}
return m_cxyFixed;
}
GetImage(*image);
if (image->imageCache) {
if (GetFixedWidth() == DUI_LENGTH_AUTO) {
int image_width = image->imageCache->nX;
DpiManager::GetInstance()->ScaleInt(image_width);
imageSize.cx = image_width;
}
if (GetFixedHeight() == DUI_LENGTH_AUTO) {
int image_height = image->imageCache->nY;
DpiManager::GetInstance()->ScaleInt(image_height);
imageSize.cy = image_height;
}
}
}
m_bReEstimateSize = false;
CSize textSize = EstimateText(szAvailable, m_bReEstimateSize);
if (GetFixedWidth() == DUI_LENGTH_AUTO && imageSize.cx < textSize.cx) {
imageSize.cx = textSize.cx;
}
if (GetFixedHeight() == DUI_LENGTH_AUTO && imageSize.cy < textSize.cy) {
imageSize.cy = textSize.cy;
}
m_szEstimateSize = imageSize;
}
return imageSize;
}
CSize Control::EstimateText(CSize szAvailable, bool& bReEstimateSize)
{
return CSize();
}
bool Control::IsPointInWithScrollOffset(const CPoint& point) const
{
CPoint scrollOffset = GetScrollOffset();
CPoint newPoint = point;
newPoint.Offset(scrollOffset);
return m_rcItem.IsPointIn(newPoint);
}
void Control::HandleMessageTemplate(EventType eventType, WPARAM wParam, LPARAM lParam, TCHAR tChar, CPoint mousePos, FLOAT pressure)
{
EventArgs msg;
msg.pSender = this;
msg.Type = eventType;
msg.chKey = tChar;
msg.wParam = wParam;
msg.lParam = lParam;
msg.pressure = pressure;
if (0 == mousePos.x == mousePos.y)
msg.ptMouse = m_pWindow->GetLastMousePos();
else
msg.ptMouse = mousePos;
msg.dwTimestamp = ::GetTickCount();
HandleMessageTemplate(msg);
}
void Control::HandleMessageTemplate(EventArgs& msg)
{
if (msg.Type == kEventInternalDoubleClick || msg.Type == kEventInternalMenu
|| msg.Type == kEventInternalSetFocus || msg.Type == kEventInternalKillFocus) {
HandleMessage(msg);
return;
}
bool bRet = true;
if (this == msg.pSender) {
std::weak_ptr<nbase::WeakFlag> weakflag = GetWeakFlag();
auto callback = OnEvent.find(msg.Type);
if (callback != OnEvent.end()) {
bRet = callback->second(&msg);
}
if (weakflag.expired()) {
return;
}
callback = OnEvent.find(kEventAll);
if (callback != OnEvent.end()) {
bRet = callback->second(&msg);
}
if (weakflag.expired()) {
return;
}
if (bRet) {
auto callback = OnXmlEvent.find(msg.Type);
if (callback != OnXmlEvent.end()) {
bRet = callback->second(&msg);
}
if (weakflag.expired()) {
return;
}
callback = OnXmlEvent.find(kEventAll);
if (callback != OnXmlEvent.end()) {
bRet = callback->second(&msg);
}
if (weakflag.expired()) {
return;
}
}
}
else {
ASSERT(FALSE);
}
if(bRet) {
HandleMessage(msg);
}
}
void Control::HandleMessage(EventArgs& msg)
{
if( !IsMouseEnabled() && msg.Type > kEventMouseBegin && msg.Type < kEventMouseEnd ) {
if( m_pParent != NULL ) m_pParent->HandleMessageTemplate(msg);
return;
}
else if( msg.Type == kEventSetCursor ) {
if (m_cursorType == kCursorHand) {
if (IsEnabled()) {
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_HAND)));
}
else {
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
}
return;
}
else if (m_cursorType == kCursorArrow){
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));
return;
}
else if (m_cursorType == kCursorHandIbeam){
::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_IBEAM)));
return;
}
else {
ASSERT(FALSE);
}
}
else if (msg.Type == kEventInternalSetFocus) {
SetState(kControlStateHot);
2019-04-19 17:19:57 +08:00
m_bFocused = true;
Invalidate();
return;
}
else if (msg.Type == kEventInternalKillFocus) {
SetState(kControlStateNormal);
2019-04-19 17:19:57 +08:00
m_bFocused = false;
Invalidate();
return;
}
else if (msg.Type == kEventInternalMenu && IsEnabled()) {
if( IsContextMenuUsed() ) {
m_pWindow->SendNotify(this, kEventMouseMenu, msg.wParam, msg.lParam);
return;
}
}
else if( msg.Type == kEventMouseEnter ) {
if (msg.pSender != this && m_pWindow) {
if (!IsChild(this, m_pWindow->GetNewHover())) {
return;
}
}
MouseEnter(msg);
}
else if( msg.Type == kEventMouseLeave ) {
if (msg.pSender != this && m_pWindow) {
if (IsChild(this, m_pWindow->GetNewHover())) {
return;
}
}
MouseLeave(msg);
}
else if (msg.Type == kEventMouseButtonDown || msg.Type == kEventInternalDoubleClick) {
ButtonDown(msg);
return;
}
else if (msg.Type == kEventMouseButtonUp) {
ButtonUp(msg);
return;
}
else if (msg.Type == kEventPointDown && m_bReceivePointerMsg) {
ButtonDown(msg);
return;
}
else if (msg.Type == kEventPointUp && m_bReceivePointerMsg) {
ButtonUp(msg);
return;
}
if( m_pParent != NULL ) m_pParent->HandleMessageTemplate(msg);
}
bool Control::HasHotState()
{
// <20>жϱ<D0B6><CFB1>ؼ<EFBFBD><D8BC>Ƿ<EFBFBD><C7B7><EFBFBD>hot״̬
return m_colorMap.HasHotColor() || m_imageMap.HasHotImage();
}
bool Control::MouseEnter(EventArgs& msg)
{
if( IsEnabled() ) {
if ( m_uButtonState == kControlStateNormal) {
m_uButtonState = kControlStateHot;
if (HasHotState()) {
m_animationManager.MouseEnter();
Invalidate();
}
return true;
}
}
return false;
}
bool Control::MouseLeave(EventArgs& msg)
{
if( IsEnabled() ) {
if (m_uButtonState == kControlStateHot) {
m_uButtonState = kControlStateNormal;
if (HasHotState()) {
m_animationManager.MouseLeave();
Invalidate();
}
return true;
}
}
return false;
}
bool Control::ButtonDown(EventArgs& msg)
{
bool ret = false;
if( IsEnabled() ) {
m_uButtonState = kControlStatePushed;
SetMouseFocused(true);
Invalidate();
ret = true;
}
return ret;
}
bool Control::ButtonUp(EventArgs& msg)
{
bool ret = false;
if( IsMouseFocused() ) {
SetMouseFocused(false);
auto player = m_animationManager.GetAnimationPlayer(kAnimationHot);
if (player)
player->Stop();
Invalidate();
if( IsPointInWithScrollOffset(msg.ptMouse) ) {
if (msg.Type == kEventPointUp) {
m_uButtonState = kControlStateNormal;
m_nHotAlpha = 0;
}
else {
m_uButtonState = kControlStateHot;
m_nHotAlpha = 255;
}
Activate();
ret = true;
}
else {
m_uButtonState = kControlStateNormal;
m_nHotAlpha = 0;
}
}
return ret;
}
void Control::SetAttribute(const std::wstring& strName, const std::wstring& strValue)
{
if ( strName == _T("class") ) {
SetClass(strValue);
}
else if( strName == _T("halign") ) {
if (strValue == _T("left")) {
SetHorAlignType(kHorAlignLeft);
}
else if (strValue == _T("center")) {
SetHorAlignType(kHorAlignCenter);
}
else if (strValue == _T("right")) {
SetHorAlignType(kHorAlignRight);
}
else {
ASSERT(FALSE);
}
}
else if( strName == _T("valign") ) {
if (strValue == _T("top")) {
SetVerAlignType(kVerAlignTop);
}
else if (strValue == _T("center")) {
SetVerAlignType(kVerAlignCenter);
}
else if (strValue == _T("bottom")) {
SetVerAlignType(kVerAlignBottom);
}
else {
ASSERT(FALSE);
}
}
else if( strName == _T("margin") ) {
UiRect rcMargin;
LPTSTR pstr = NULL;
rcMargin.left = _tcstol(strValue.c_str(), &pstr, 10); ASSERT(pstr);
rcMargin.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcMargin.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcMargin.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
SetMargin(rcMargin);
}
else if( strName == _T("bkcolor") || strName == _T("bkcolor1") ) {
LPCTSTR pValue = strValue.c_str();
while( *pValue > _T('\0') && *pValue <= _T(' ') ) pValue = ::CharNext(pValue);
SetBkColor(pValue);
}
else if (strName == _T("bordersize")) {
std::wstring nValue = strValue;
if (nValue.find(',') == std::wstring::npos) {
SetBorderSize(_ttoi(strValue.c_str()));
UiRect rcBorder;
SetBorderSize(rcBorder);
}
else {
UiRect rcBorder;
LPTSTR pstr = NULL;
rcBorder.left = _tcstol(strValue.c_str(), &pstr, 10); ASSERT(pstr);
rcBorder.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcBorder.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
rcBorder.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
SetBorderSize(rcBorder);
}
}
else if( strName == _T("borderround") ) {
CSize cxyRound;
LPTSTR pstr = NULL;
cxyRound.cx = _tcstol(strValue.c_str(), &pstr, 10); ASSERT(pstr);
cxyRound.cy = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
SetBorderRound(cxyRound);
}
else if( strName == _T("width") ) {
if ( strValue == _T("stretch") ) {
SetFixedWidth(DUI_LENGTH_STRETCH);
}
else if ( strValue == _T("auto") ) {
SetFixedWidth(DUI_LENGTH_AUTO);
}
else {
ASSERT(_ttoi(strValue.c_str()) >= 0);
SetFixedWidth(_ttoi(strValue.c_str()));
}
}
else if( strName == _T("height") ) {
if ( strValue == _T("stretch") ) {
SetFixedHeight(DUI_LENGTH_STRETCH);
}
else if ( strValue == _T("auto") ) {
SetFixedHeight(DUI_LENGTH_AUTO);
}
else {
ASSERT(_ttoi(strValue.c_str()) >= 0);
SetFixedHeight(_ttoi(strValue.c_str()));
}
}
else if( strName == _T("maxwidth") ) {
if ( strValue == _T("stretch") ) {
SetMaxWidth(DUI_LENGTH_STRETCH);
}
else if ( strValue == _T("auto") ) {
SetMaxWidth(DUI_LENGTH_AUTO);
}
else {
ASSERT(_ttoi(strValue.c_str()) >= 0);
SetMaxWidth(_ttoi(strValue.c_str()));
}
}
else if( strName == _T("maxheight") ) {
if ( strValue == _T("stretch") ) {
SetMaxHeight(DUI_LENGTH_STRETCH);
}
else if ( strValue == _T("auto") ) {
SetMaxHeight(DUI_LENGTH_AUTO);
}
else {
ASSERT(_ttoi(strValue.c_str()) >= 0);
SetMaxHeight(_ttoi(strValue.c_str()));
}
}
else if( strName == _T("state") ) {
if( strValue == _T("normal") ) SetState(kControlStateNormal);
else if( strValue == _T("hot") ) SetState(kControlStateHot);
else if( strValue == _T("pushed") ) SetState(kControlStatePushed);
else if( strValue == _T("disabled") ) SetState(kControlStateDisabled);
else ASSERT(FALSE);
}
else if( strName == _T("cursortype") ) {
if (strValue == _T("arrow")) {
SetCursorType(kCursorArrow);
}
else if ( strValue == _T("hand") ) {
SetCursorType(kCursorHand);
}
else if (strValue == _T("ibeam")) {
SetCursorType(kCursorHandIbeam);
}
else {
ASSERT(FALSE);
}
}
else if (strName == _T("renderoffset")) {
CPoint renderOffset;
LPTSTR pstr = NULL;
renderOffset.x = _tcstol(strValue.c_str(), &pstr, 10); ASSERT(pstr);
renderOffset.y = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
DpiManager::GetInstance()->ScalePoint(renderOffset);
SetRenderOffset(renderOffset);
}
else if (strName == _T("normalcolor")) SetStateColor(kControlStateNormal, strValue);
else if (strName == _T("hotcolor")) SetStateColor(kControlStateHot, strValue);
else if (strName == _T("pushedcolor")) SetStateColor(kControlStatePushed, strValue);
else if (strName == _T("disabledcolor")) SetStateColor(kControlStateDisabled, strValue);
else if (strName == _T("bordercolor")) SetBorderColor(strValue);
else if (strName == _T("leftbordersize")) SetLeftBorderSize(_ttoi(strValue.c_str()));
else if (strName == _T("topbordersize")) SetTopBorderSize(_ttoi(strValue.c_str()));
else if (strName == _T("rightbordersize")) SetRightBorderSize(_ttoi(strValue.c_str()));
else if (strName == _T("bottombordersize")) SetBottomBorderSize(_ttoi(strValue.c_str()));
else if (strName == _T("bkimage")) SetBkImage(strValue);
else if (strName == _T("minwidth")) SetMinWidth(_ttoi(strValue.c_str()));
else if (strName == _T("minheight")) SetMinHeight(_ttoi(strValue.c_str()));
else if (strName == _T("name")) SetName(strValue);
else if (strName == _T("tooltiptext")) SetToolTipText(strValue);
else if (strName == _T("tooltiptextid")) SetToolTipTextId(strValue);
else if (strName == _T("dataid")) SetDataID(strValue);
else if (strName == _T("enabled")) SetEnabled(strValue == _T("true"));
else if (strName == _T("mouse")) SetMouseEnabled(strValue == _T("true"));
else if (strName == _T("keyboard")) SetKeyboardEnabled(strValue == _T("true"));
else if (strName == _T("visible")) SetVisible_(strValue == _T("true"));
else if (strName == _T("fadevisible")) SetVisible(strValue == _T("true"));
else if (strName == _T("float")) SetFloat(strValue == _T("true"));
else if (strName == _T("menu")) SetContextMenuUsed(strValue == _T("true"));
else if (strName == _T("cache")) SetUseCache(strValue == _T("true"));
else if (strName == _T("nofocus")) SetNoFocus();
else if (strName == _T("alpha")) SetAlpha(_ttoi(strValue.c_str()));
else if (strName == _T("normalimage") ) SetStateImage(kControlStateNormal, strValue);
else if (strName == _T("hotimage") ) SetStateImage(kControlStateHot, strValue);
else if (strName == _T("pushedimage") ) SetStateImage(kControlStatePushed, strValue);
else if (strName == _T("disabledimage") ) SetStateImage(kControlStateDisabled, strValue);
else if (strName == _T("forenormalimage") ) SetForeStateImage(kControlStateNormal, strValue);
else if (strName == _T("forehotimage") ) SetForeStateImage(kControlStateHot, strValue);
else if (strName == _T("forepushedimage") ) SetForeStateImage(kControlStatePushed, strValue);
else if (strName == _T("foredisabledimage") ) SetForeStateImage(kControlStateDisabled, strValue);
else if (strName == _T("fadealpha")) m_animationManager.SetFadeAlpha(strValue == _T("true"));
else if (strName == _T("fadehot")) m_animationManager.SetFadeHot(strValue == _T("true"));
else if (strName == _T("fadewidth")) m_animationManager.SetFadeWidth(strValue == _T("true"));
else if (strName == _T("fadeheight")) m_animationManager.SetFadeHeight(strValue == _T("true"));
else if (strName == _T("fadeinoutxfromleft")) m_animationManager.SetFadeInOutX(strValue == _T("true"), false);
else if (strName == _T("fadeinoutxfromright")) m_animationManager.SetFadeInOutX(strValue == _T("true"), true);
else if (strName == _T("fadeinoutyfromtop")) m_animationManager.SetFadeInOutY(strValue == _T("true"), false);
else if (strName == _T("fadeinoutyfrombottom")) m_animationManager.SetFadeInOutY(strValue == _T("true"), true);
else if (strName == _T("receivepointer")) SetReceivePointerMsg(strValue == _T("true"));
else
{
ASSERT(FALSE);
}
}
void Control::SetClass(const std::wstring& strClass)
{
std::list<std::wstring> splitList = StringHelper::Split(strClass, L" ");
for (auto it = splitList.begin(); it != splitList.end(); it++) {
std::wstring pDefaultAttributes = GlobalManager::GetClassAttributes((*it));
if (pDefaultAttributes.empty() && m_pWindow) {
pDefaultAttributes = m_pWindow->GetClassAttributes(*it);
}
ASSERT(!pDefaultAttributes.empty());
if( !pDefaultAttributes.empty() ) {
ApplyAttributeList(pDefaultAttributes);
}
}
}
void Control::ApplyAttributeList(const std::wstring& strList)
{
std::wstring sItem;
std::wstring sValue;
LPCTSTR pstrList = strList.c_str();
while( *pstrList != _T('\0') ) {
sItem.clear();
sValue.clear();
while( *pstrList != _T('\0') && *pstrList != _T('=') ) {
LPTSTR pstrTemp = ::CharNext(pstrList);
while( pstrList < pstrTemp) {
sItem += *pstrList++;
}
}
ASSERT( *pstrList == _T('=') );
if( *pstrList++ != _T('=') ) return;
ASSERT( *pstrList == _T('\"') );
if( *pstrList++ != _T('\"') ) return;
while( *pstrList != _T('\0') && *pstrList != _T('\"') ) {
LPTSTR pstrTemp = ::CharNext(pstrList);
while( pstrList < pstrTemp) {
sValue += *pstrList++;
}
}
ASSERT( *pstrList == _T('\"') );
if( *pstrList++ != _T('\"') ) return;
SetAttribute(sItem, sValue);
if( *pstrList++ != _T(' ') ) return;
}
return;
}
bool Control::OnApplyAttributeList(const std::wstring& strReceiver, const std::wstring& strList, EventArgs* eventArgs)
{
Control* pReceiverControl;
if (strReceiver.substr(0, 2) == L".\\" || strReceiver.substr(0, 2) == L"./") {
pReceiverControl = ((Box*)this)->FindSubControl(strReceiver.substr(2));
}
else {
pReceiverControl = GetWindow()->FindControl(strReceiver);
}
if (pReceiverControl) {
pReceiverControl->ApplyAttributeList(strList);
}
else {
ASSERT(FALSE);
}
return true;
}
void Control::GetImage(Image& duiImage) const
{
if (duiImage.imageCache) {
return;
}
std::wstring sImageName = duiImage.imageAttribute.sImageName;
std::wstring imageFullPath = sImageName;
if (::PathIsRelative(sImageName.c_str())) {
imageFullPath = GlobalManager::GetResourcePath() + m_pWindow->GetWindowResourcePath() + sImageName;
}
imageFullPath = StringHelper::ReparsePath(imageFullPath);
if (!duiImage.imageCache || duiImage.imageCache->sImageFullPath != imageFullPath) {
duiImage.imageCache = GlobalManager::GetImage(imageFullPath);
}
}
bool Control::DrawImage(IRenderContext* pRender, Image& duiImage, const std::wstring& strModify /*= L""*/, int nFade /*= DUI_NOSET_VALUE*/)
{
if (duiImage.imageAttribute.sImageName.empty()) {
return false;
}
GetImage(duiImage);
if (!duiImage.imageCache) {
ASSERT(FALSE);
duiImage.imageAttribute.Init();
return false;
}
ImageAttribute newImageAttribute = duiImage.imageAttribute;
if (!strModify.empty()) {
ImageAttribute::ModifyAttribute(newImageAttribute, strModify);
}
UiRect rcNewDest = m_rcItem;
if (newImageAttribute.rcDest.left != DUI_NOSET_VALUE && newImageAttribute.rcDest.top != DUI_NOSET_VALUE
&& newImageAttribute.rcDest.right != DUI_NOSET_VALUE && newImageAttribute.rcDest.bottom != DUI_NOSET_VALUE) {
rcNewDest.left = m_rcItem.left + newImageAttribute.rcDest.left;
rcNewDest.right = m_rcItem.left + newImageAttribute.rcDest.right;
rcNewDest.top = m_rcItem.top + newImageAttribute.rcDest.top;
rcNewDest.bottom = m_rcItem.top + newImageAttribute.rcDest.bottom;
}
UiRect rcNewSource = newImageAttribute.rcSource;
if (rcNewSource.left == DUI_NOSET_VALUE || rcNewSource.top == DUI_NOSET_VALUE
|| rcNewSource.right == DUI_NOSET_VALUE || rcNewSource.bottom == DUI_NOSET_VALUE) {
rcNewSource.left = 0;
rcNewSource.top = 0;
rcNewSource.right = duiImage.imageCache->nX;
rcNewSource.bottom = duiImage.imageCache->nY;
}
if (m_bkImage.imageCache && m_bkImage.imageCache->IsGif() && m_bGifPlay && !m_bkImage.IsPlaying()) {
GifPlay();
}
else {
int iFade = nFade == DUI_NOSET_VALUE ? newImageAttribute.bFade : nFade;
ImageInfo* imageInfo = duiImage.imageCache.get();
pRender->DrawImage(m_rcPaint, duiImage.GetCurrentHBitmap(), imageInfo->IsAlpha(),
rcNewDest, rcNewSource, newImageAttribute.rcCorner, iFade, newImageAttribute.bTiledX, newImageAttribute.bTiledY);
}
return true;
}
ui::IRenderContext* Control::GetRenderContext()
{
if (!m_renderContext) {
m_renderContext = GlobalManager::CreateRenderContext();
}
return m_renderContext.get();
}
void Control::ClearRenderContext()
{
if (m_renderContext) {
m_renderContext.reset();
}
}
void Control::AlphaPaint(IRenderContext* pRender, const UiRect& rcPaint)
{
if (m_nAlpha == 0) {
return;
}
UiRect rcUnion;
if( !::IntersectRect(&rcUnion, &rcPaint, &m_rcItem) ) return;
bool bRoundClip = false;
if (m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0) {
bRoundClip = true;
}
if (IsAlpha()) {
CSize size;
size.cx = m_rcItem.right - m_rcItem.left;
size.cy = m_rcItem.bottom - m_rcItem.top;
auto pCacheRender = GetRenderContext();
if (pCacheRender) {
if (pCacheRender->Resize(size.cx, size.cy)) {
SetCacheDirty(true);
}
// IsCacheDirty<74><79>m_bCacheDirty<74><79><EFBFBD>һ<E5B2BB><D2BB>
if (m_bCacheDirty) {
pCacheRender->Clear();
UiRect rcClip = { 0, 0, size.cx, size.cy };
AutoClip alphaClip(pCacheRender, rcClip, m_bClip);
AutoClip roundAlphaClip(pCacheRender, rcClip, m_cxyBorderRound.cx, m_cxyBorderRound.cy, bRoundClip);
bool bOldCanvasTrans = m_pWindow->SetRenderTransparent(true);
CPoint ptOffset(m_rcItem.left + m_renderOffset.x, m_rcItem.top + m_renderOffset.y);
CPoint ptOldOrg = pCacheRender->OffsetWindowOrg(ptOffset);
Paint(pCacheRender, m_rcItem);
PaintChild(pRender, rcPaint);
pCacheRender->SetWindowOrg(ptOldOrg);
m_pWindow->SetRenderTransparent(bOldCanvasTrans);
SetCacheDirty(false);
}
pRender->AlphaBlend(rcUnion.left, rcUnion.top, rcUnion.right - rcUnion.left, rcUnion.bottom - rcUnion.top, pCacheRender->GetDC(),
rcUnion.left - m_rcItem.left, rcUnion.top - m_rcItem.top, rcUnion.right - rcUnion.left, rcUnion.bottom - rcUnion.top, m_nAlpha);
m_renderContext.reset();
}
}
else if (IsUseCache()) {
CSize size;
size.cx = m_rcItem.right - m_rcItem.left;
size.cy = m_rcItem.bottom - m_rcItem.top;
auto pCacheRender = GetRenderContext();
if (pCacheRender) {
if (pCacheRender->Resize(size.cx, size.cy)) {
SetCacheDirty(true);
}
if (IsCacheDirty()) {
pCacheRender->Clear();
UiRect rcClip = { 0, 0, size.cx, size.cy };
AutoClip alphaClip(pCacheRender, rcClip, m_bClip);
AutoClip roundAlphaClip(pCacheRender, rcClip, m_cxyBorderRound.cx, m_cxyBorderRound.cy, bRoundClip);
bool bOldCanvasTrans = m_pWindow->SetRenderTransparent(true);
CPoint ptOffset(m_rcItem.left + m_renderOffset.x, m_rcItem.top + m_renderOffset.y);
CPoint ptOldOrg = pCacheRender->OffsetWindowOrg(ptOffset);
Paint(pCacheRender, m_rcItem);
pCacheRender->SetWindowOrg(ptOldOrg);
m_pWindow->SetRenderTransparent(bOldCanvasTrans);
SetCacheDirty(false);
}
pRender->AlphaBlend(rcUnion.left, rcUnion.top, rcUnion.right - rcUnion.left, rcUnion.bottom - rcUnion.top, pCacheRender->GetDC(),
rcUnion.left - m_rcItem.left, rcUnion.top - m_rcItem.top, rcUnion.right - rcUnion.left, rcUnion.bottom - rcUnion.top, m_nAlpha);
PaintChild(pRender, rcPaint);
}
}
else {
AutoClip clip(pRender, m_rcItem, m_bClip);
AutoClip roundClip(pRender, m_rcItem, m_cxyBorderRound.cx, m_cxyBorderRound.cy, bRoundClip);
CPoint ptOldOrg = pRender->OffsetWindowOrg(m_renderOffset);
Paint(pRender, rcPaint);
PaintChild(pRender, rcPaint);
pRender->SetWindowOrg(ptOldOrg);
}
}
void Control::Paint(IRenderContext* pRender, const UiRect& rcPaint)
{
if( !::IntersectRect(&m_rcPaint, &rcPaint, &m_rcItem) ) return;
PaintBkColor(pRender);
PaintBkImage(pRender);
PaintStatusColor(pRender);
PaintStatusImage(pRender);
PaintText(pRender);
PaintBorder(pRender);
}
void Control::PaintBkColor(IRenderContext* pRender)
{
if (m_strBkColor.empty()) {
return;
}
DWORD dwBackColor = GlobalManager::GetTextColor(m_strBkColor);
if(dwBackColor != 0) {
if (dwBackColor >= 0xFF000000) pRender->DrawColor(m_rcPaint, dwBackColor);
else pRender->DrawColor(m_rcItem, dwBackColor);
}
}
void Control::PaintBkImage(IRenderContext* pRender)
{
DrawImage(pRender, m_bkImage);
}
void Control::PaintStatusColor(IRenderContext* pRender)
{
m_colorMap.PaintStatusColor(pRender, m_rcPaint, m_uButtonState);
}
void Control::PaintStatusImage(IRenderContext* pRender)
{
m_imageMap.PaintStatusImage(pRender, kStateImageBk, m_uButtonState);
m_imageMap.PaintStatusImage(pRender, kStateImageFore, m_uButtonState);
}
void Control::PaintText(IRenderContext* pRender)
{
return;
}
void Control::PaintBorder(IRenderContext* pRender)
{
if (m_strBorderColor.empty()) {
return;
}
DWORD dwBorderColor = 0;
if (!m_strBorderColor.empty()) {
dwBorderColor = GlobalManager::GetTextColor(m_strBorderColor);
}
if (dwBorderColor != 0) {
if (m_rcBorderSize.left > 0 || m_rcBorderSize.top > 0 || m_rcBorderSize.right > 0 || m_rcBorderSize.bottom > 0) {
UiRect rcBorder;
if (m_rcBorderSize.left > 0) {
rcBorder = m_rcItem;
rcBorder.right = rcBorder.left = m_rcItem.left + m_rcBorderSize.left / 2;
if (m_rcBorderSize.left == 1) {
rcBorder.bottom -= 1;
}
pRender->DrawLine(rcBorder, m_rcBorderSize.left, dwBorderColor);
}
if (m_rcBorderSize.top > 0) {
rcBorder = m_rcItem;
rcBorder.bottom = rcBorder.top = m_rcItem.top + m_rcBorderSize.top / 2;
if (m_rcBorderSize.top == 1) {
rcBorder.right -= 1;
}
pRender->DrawLine(rcBorder, m_rcBorderSize.top, dwBorderColor);
}
if (m_rcBorderSize.right > 0) {
rcBorder = m_rcItem;
rcBorder.left = rcBorder.right = m_rcItem.right - (m_rcBorderSize.right + 1) / 2;
if (m_rcBorderSize.right == 1) {
rcBorder.bottom -= 1;
}
pRender->DrawLine(rcBorder, m_rcBorderSize.right, dwBorderColor);
}
if (m_rcBorderSize.bottom > 0) {
rcBorder = m_rcItem;
rcBorder.top = rcBorder.bottom = m_rcItem.bottom - (m_rcBorderSize.bottom + 1) / 2;
if (m_rcBorderSize.bottom == 1) {
rcBorder.right -= 1;
}
pRender->DrawLine(rcBorder, m_rcBorderSize.bottom, dwBorderColor);
}
}
else if (m_nBorderSize > 0) {
2019-04-19 17:19:57 +08:00
UiRect rcDraw = m_rcItem;
int nDeltaValue = m_nBorderSize / 2;
rcDraw.top += nDeltaValue;
rcDraw.bottom -= nDeltaValue;
if (m_nBorderSize % 2 != 0) {
rcDraw.bottom -= 1;
}
rcDraw.left += nDeltaValue;
rcDraw.right -= nDeltaValue;
if (m_nBorderSize % 2 != 0) {
rcDraw.right -= 1;
}
if (m_cxyBorderRound.cx > 0 || m_cxyBorderRound.cy > 0)
pRender->DrawRoundRect(rcDraw, m_cxyBorderRound, m_nBorderSize, dwBorderColor);
else
2019-08-01 11:56:05 +08:00
pRender->DrawRect(rcDraw, m_nBorderSize, dwBorderColor);
2019-04-19 17:19:57 +08:00
}
}
}
void Control::SetAlpha(int alpha)
{
ASSERT(alpha >= 0 && alpha <= 255);
m_nAlpha = alpha;
Invalidate();
}
void Control::SetHotAlpha(int nHotAlpha)
{
ASSERT(nHotAlpha >= 0 && nHotAlpha <= 255);
m_nHotAlpha = nHotAlpha;
Invalidate();
}
void Control::SetRenderOffset(CPoint renderOffset)
{
m_renderOffset = renderOffset;
Invalidate();
}
void Control::SetRenderOffsetX(int renderOffsetX)
{
m_renderOffset.x = renderOffsetX;
Invalidate();
}
void Control::SetRenderOffsetY(int renderOffsetY)
{
m_renderOffset.y = renderOffsetY;
Invalidate();
}
void Control::GifPlay()
{
if (!m_bkImage.IsValid() || !m_bkImage.imageCache->IsGif() || !m_bkImage.ContinuePlay()) {
m_bkImage.SetPlaying(false);
m_gifWeakFlag.Cancel();
return;
}
if (!m_bkImage.IsPlaying()) {
m_bkImage.SetCurrentFrame(0);
m_gifWeakFlag.Cancel();
int lPause = m_bkImage.GetCurrentInterval();
if (lPause == 0)
return;
m_bkImage.SetPlaying(true);
auto gifPlayCallback = nbase::Bind(&Control::GifPlay, this);
TimerManager::GetInstance()->AddCancelableTimer(m_gifWeakFlag.GetWeakFlag(), gifPlayCallback,
lPause, TimerManager::REPEAT_FOREVER);
}
else {
int lPrePause = m_bkImage.GetCurrentInterval();
m_bkImage.IncrementCurrentFrame();
int lPause = m_bkImage.GetCurrentInterval();
if (!m_bkImage.ContinuePlay())
{
StopGifPlayForUI(true, kGifStopLast);
}
else
{
if (lPrePause == 0 || lPause == 0) {//0<><30>ʾGetCurrentInterval<61><6C><EFBFBD><EFBFBD>
m_bkImage.SetPlaying(false);
m_gifWeakFlag.Cancel();
return;
}
if (lPrePause != lPause) {
m_gifWeakFlag.Cancel();
auto gifPlayCallback = nbase::Bind(&Control::GifPlay, this);
TimerManager::GetInstance()->AddCancelableTimer(m_gifWeakFlag.GetWeakFlag(), gifPlayCallback,
lPause, TimerManager::REPEAT_FOREVER);
}
}
}
Invalidate();
}
void Control::StopGifPlay(GifStopType frame)
{
if (m_bkImage.imageCache && m_bkImage.imageCache->IsGif()) {
m_bkImage.SetPlaying(false);
m_gifWeakFlag.Cancel();
int index = GetGifFrameIndex(frame);
m_bkImage.SetCurrentFrame(index);
Invalidate();
}
}
void Control::StartGifPlayForUI(GifStopType frame, int playcount)
{
GetImage(m_bkImage);
if (!m_bkImage.IsValid() || !m_bkImage.imageCache->IsGif()) {
m_bGifPlay = false;
m_bkImage.SetPlaying(false);
m_gifWeakFlag.Cancel();
return;
}
if (playcount == 0)
{
StopGifPlayForUI(false);
}
else
{
m_gifWeakFlag.Cancel();
m_bGifPlay = true;
m_bkImage.SetCurrentFrame(GetGifFrameIndex(frame));
int lPause = m_bkImage.GetCurrentInterval();
if (lPause == 0) {
m_bGifPlay = false;
return;
}
m_bkImage.SetPlaying(true);
m_bkImage.imageAttribute.nPlayCount = playcount;
m_bkImage.ClearCycledCount();
auto gifPlayCallback = nbase::Bind(&Control::GifPlay, this);
TimerManager::GetInstance()->AddCancelableTimer(m_gifWeakFlag.GetWeakFlag(), gifPlayCallback,
lPause, TimerManager::REPEAT_FOREVER);
Invalidate();
}
}
void Control::StopGifPlayForUI(bool transfer, GifStopType frame)
{
m_bGifPlay = false;
StopGifPlay(frame);
if (transfer)
BroadcastGifEvent(m_nVirtualEventGifStop);
}
int Control::GetGifFrameIndex(GifStopType frame)
{
int ret = frame;
switch (frame)
{
case kGifStopCurrent:
ret = m_bkImage.GetCurrentFrameIndex();
break;
case kGifStopFirst:
ret = 0;
break;
case kGifStopLast:
{
int nFrameCount = m_bkImage.imageCache->GetFrameCount();
ret = nFrameCount > 0 ? nFrameCount - 1 : 0;
}
break;
}
return ret;
}
void Control::BroadcastGifEvent(int nVirtualEvent)
{
auto callback = OnGifEvent.find(nVirtualEvent);
if (callback != OnGifEvent.end()) {
EventArgs param;
param.pSender = this;
callback->second(&param);
}
}
void Control::InvokeLoadImageCache()
{
if (m_loadBkImageWeakFlag.HasUsed()) {
return;
}
std::wstring sImageName = m_bkImage.imageAttribute.sImageName;
if (sImageName.empty()) {
return;
}
std::wstring imageFullPath = sImageName;
if (::PathIsRelative(sImageName.c_str())) {
imageFullPath = GlobalManager::GetResourcePath() + m_pWindow->GetWindowResourcePath() + sImageName;
}
imageFullPath = StringHelper::ReparsePath(imageFullPath);
if (!m_bkImage.imageCache || m_bkImage.imageCache->sImageFullPath != imageFullPath) {
auto shared_image = GlobalManager::IsImageCached(imageFullPath);
if (shared_image) {
m_bkImage.imageCache = shared_image;
return;
}
}
}
void Control::UnLoadImageCache()
{
m_loadBkImageWeakFlag.Cancel();
m_bkImage.ClearCache();
}
void Control::ClearImageCache()
{
m_imageMap.ClearCache();
m_bkImage.ClearCache();
}
void Control::DetachEvent(EventType type)
{
auto event = OnEvent.find(type);
if (event != OnEvent.end())
{
OnEvent.erase(event);
}
}
} // namespace ui