1710 lines
46 KiB
C++
1710 lines
46 KiB
C++
#include "StdAfx.h"
|
||
|
||
namespace ui
|
||
{
|
||
Layout::Layout() :
|
||
m_rcPadding(0, 0, 0, 0),
|
||
m_iChildMargin(0),
|
||
m_pOwner(nullptr)
|
||
{
|
||
|
||
}
|
||
|
||
void Layout::SetOwner(Box* pOwner)
|
||
{
|
||
m_pOwner = pOwner;
|
||
}
|
||
|
||
CSize Layout::SetFloatPos(Control* pControl, UiRect rcContainer)
|
||
{
|
||
if (!pControl->IsVisible()) return CSize();
|
||
|
||
int childLeft = 0;
|
||
int childRight = 0;
|
||
int childTop = 0;
|
||
int childBottm = 0;
|
||
UiRect rcMargin = pControl->GetMargin();
|
||
int iPosLeft = rcContainer.left + rcMargin.left;
|
||
int iPosRight = rcContainer.right - rcMargin.right;
|
||
int iPosTop = rcContainer.top + rcMargin.top;
|
||
int iPosBottom = rcContainer.bottom - rcMargin.bottom;
|
||
CSize szAvailable(iPosRight - iPosLeft, iPosBottom - iPosTop);
|
||
CSize childSize = pControl->EstimateSize(szAvailable);
|
||
if (pControl->GetFixedWidth() == DUI_LENGTH_AUTO && pControl->GetFixedHeight() == DUI_LENGTH_AUTO
|
||
&& pControl->GetMaxWidth() == DUI_LENGTH_STRETCH) {
|
||
int maxwidth = MAX(0, szAvailable.cx);
|
||
if (childSize.cx > maxwidth) {
|
||
pControl->SetFixedWidth(maxwidth, false);
|
||
childSize = pControl->EstimateSize(szAvailable);
|
||
pControl->SetFixedWidth(DUI_LENGTH_AUTO, false);
|
||
}
|
||
}
|
||
if (childSize.cx == DUI_LENGTH_STRETCH) {
|
||
childSize.cx = MAX(0, szAvailable.cx);
|
||
}
|
||
if (childSize.cx < pControl->GetMinWidth()) childSize.cx = pControl->GetMinWidth();
|
||
if (pControl->GetMaxWidth() >= 0 && childSize.cx > pControl->GetMaxWidth()) childSize.cx = pControl->GetMaxWidth();
|
||
|
||
if (childSize.cy == DUI_LENGTH_STRETCH) {
|
||
childSize.cy = MAX(0, szAvailable.cy);
|
||
}
|
||
if (childSize.cy < pControl->GetMinHeight()) childSize.cy = pControl->GetMinHeight();
|
||
if (childSize.cy > pControl->GetMaxHeight()) childSize.cy = pControl->GetMaxHeight();
|
||
|
||
|
||
int childWidth = childSize.cx;
|
||
int childHeight = childSize.cy;
|
||
HorAlignType horAlignType = pControl->GetHorAlignType();
|
||
VerAlignType verAlignType = pControl->GetVerAlignType();
|
||
|
||
if (horAlignType == kHorAlignLeft) {
|
||
childLeft = iPosLeft;
|
||
childRight = childLeft + childWidth;
|
||
}
|
||
else if (horAlignType == kHorAlignRight) {
|
||
childRight = iPosRight;
|
||
childLeft = childRight - childWidth;
|
||
}
|
||
else if (horAlignType == kHorAlignCenter) {
|
||
childLeft = iPosLeft + (iPosRight - iPosLeft - childWidth) / 2;
|
||
childRight = childLeft + childWidth;
|
||
}
|
||
|
||
if (verAlignType == kVerAlignTop) {
|
||
childTop = iPosTop;
|
||
childBottm = childTop + childHeight;
|
||
}
|
||
else if (verAlignType == kVerAlignBottom) {
|
||
childBottm = iPosBottom;
|
||
childTop = childBottm - childHeight;
|
||
}
|
||
else if (verAlignType == kVerAlignCenter) {
|
||
childTop = iPosTop + (iPosBottom - iPosTop - childHeight) / 2;
|
||
childBottm = childTop + childHeight;
|
||
}
|
||
|
||
UiRect childPos(childLeft, childTop, childRight, childBottm);
|
||
pControl->SetPos(childPos);
|
||
return CSize(childPos.GetWidth(), childPos.GetHeight());
|
||
}
|
||
|
||
bool Layout::SetAttribute(const std::wstring& strName, const std::wstring& strValue)
|
||
{
|
||
bool hasAttribute = true;
|
||
if( strName == _T("padding") ) {
|
||
UiRect rcPadding;
|
||
LPTSTR pstr = NULL;
|
||
rcPadding.left = _tcstol(strValue.c_str(), &pstr, 10); ASSERT(pstr);
|
||
rcPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
rcPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
rcPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
SetPadding(rcPadding);
|
||
}
|
||
else if( strName == _T("childmargin") ) {
|
||
SetChildMargin(_ttoi(strValue.c_str()));
|
||
}
|
||
else {
|
||
hasAttribute = false;
|
||
}
|
||
|
||
return hasAttribute;
|
||
}
|
||
|
||
CSize Layout::ArrangeChild(const std::vector<Control*>& items, UiRect rc)
|
||
{
|
||
CSize size;
|
||
for (auto it = items.begin(); it != items.end(); it++)
|
||
{
|
||
Control* pControl = *it;
|
||
if( !pControl->IsVisible() ) continue;
|
||
CSize new_size = SetFloatPos(pControl, rc);
|
||
size.cx = MAX(size.cx, new_size.cx);
|
||
size.cy = MAX(size.cy, new_size.cy);
|
||
}
|
||
|
||
return size;
|
||
}
|
||
|
||
CSize Layout::AjustSizeByChild(const std::vector<Control*>& items, CSize szAvailable)
|
||
{
|
||
CSize maxSize(-9999, -9999);
|
||
CSize itemSize;
|
||
for (auto it = items.begin(); it != items.end(); it++)
|
||
{
|
||
if (!(*it)->IsVisible())
|
||
continue;
|
||
|
||
itemSize = (*it)->EstimateSize(szAvailable);
|
||
if( itemSize.cx < (*it)->GetMinWidth() ) itemSize.cx = (*it)->GetMinWidth();
|
||
if( (*it)->GetMaxWidth() >= 0 && itemSize.cx > (*it)->GetMaxWidth() ) itemSize.cx = (*it)->GetMaxWidth();
|
||
if( itemSize.cy < (*it)->GetMinHeight() ) itemSize.cy = (*it)->GetMinHeight();
|
||
if( itemSize.cy > (*it)->GetMaxHeight() ) itemSize.cy = (*it)->GetMaxHeight();
|
||
maxSize.cx = MAX(itemSize.cx + (*it)->GetMargin().left + (*it)->GetMargin().right, maxSize.cx);
|
||
maxSize.cy = MAX(itemSize.cy + (*it)->GetMargin().top + (*it)->GetMargin().bottom, maxSize.cy);
|
||
}
|
||
maxSize.cx += m_rcPadding.left + m_rcPadding.right;
|
||
maxSize.cy += m_rcPadding.top + m_rcPadding.bottom;
|
||
return maxSize;
|
||
}
|
||
|
||
UiRect Layout::GetPadding() const
|
||
{
|
||
return m_rcPadding;
|
||
}
|
||
|
||
void Layout::SetPadding(UiRect rcPadding, bool bNeedDpiScale /*= true*/)
|
||
{
|
||
if (bNeedDpiScale)
|
||
DpiManager::GetInstance()->ScaleRect(rcPadding);
|
||
|
||
m_rcPadding = rcPadding;
|
||
m_pOwner->Arrange();
|
||
}
|
||
|
||
int Layout::GetChildMargin() const
|
||
{
|
||
return m_iChildMargin;
|
||
}
|
||
|
||
void Layout::SetChildMargin(int iMargin)
|
||
{
|
||
DpiManager::GetInstance()->ScaleInt(iMargin);
|
||
m_iChildMargin = iMargin;
|
||
m_pOwner->Arrange();
|
||
}
|
||
|
||
UiRect Layout::GetInternalPos() const
|
||
{
|
||
UiRect internalPos = m_pOwner->GetPos();
|
||
internalPos.Deflate(m_rcPadding);
|
||
return internalPos;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
//
|
||
|
||
Box::Box(Layout* pLayout) :
|
||
m_pLayout(pLayout),
|
||
m_bAutoDestroy(true),
|
||
m_bDelayedDestroy(true),
|
||
m_bMouseChildEnabled(true),
|
||
m_items(),
|
||
OnBubbledEvent()
|
||
{
|
||
m_pLayout->SetOwner(this);
|
||
}
|
||
|
||
Box::Box(const Box& r) :
|
||
Control(r),
|
||
m_bAutoDestroy(r.m_bAutoDestroy),
|
||
m_bDelayedDestroy(r.m_bDelayedDestroy),
|
||
m_bMouseChildEnabled(r.m_bMouseChildEnabled),
|
||
m_items(),
|
||
OnBubbledEvent()
|
||
{
|
||
m_pLayout.reset(new Layout(*r.m_pLayout)),
|
||
m_pLayout->SetOwner(this);
|
||
}
|
||
|
||
Box::~Box()
|
||
{
|
||
m_bDelayedDestroy = false;
|
||
RemoveAll();
|
||
}
|
||
|
||
void Box::SetWindow(Window* pManager, Box* pParent, bool bInit)
|
||
{
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->SetWindow(pManager, this, bInit);
|
||
}
|
||
|
||
Control::SetWindow(pManager, pParent, bInit);
|
||
}
|
||
|
||
void Box::SetAttribute(const std::wstring& strName, const std::wstring& strValue)
|
||
{
|
||
if (m_pLayout->SetAttribute(strName, strValue)) {
|
||
|
||
}
|
||
else if( strName == _T("mousechild") ) SetMouseChildEnabled(strValue == _T("true"));
|
||
else Control::SetAttribute(strName, strValue);
|
||
}
|
||
|
||
void Box::SetPos(UiRect rc)
|
||
{
|
||
Control::SetPos(rc);
|
||
rc.left += m_pLayout->GetPadding().left;
|
||
rc.top += m_pLayout->GetPadding().top;
|
||
rc.right -= m_pLayout->GetPadding().right;
|
||
rc.bottom -= m_pLayout->GetPadding().bottom;
|
||
|
||
CSize requiredSize;
|
||
if( m_items.size() == 0) {
|
||
requiredSize.cx = 0;
|
||
requiredSize.cy = 0;
|
||
}
|
||
else {
|
||
requiredSize = m_pLayout->ArrangeChild(m_items, rc);
|
||
}
|
||
}
|
||
|
||
void Box::HandleMessageTemplate(EventArgs& msg)
|
||
{
|
||
if (msg.Type == kEventInternalDoubleClick || msg.Type == kEventInternalMenu
|
||
|| msg.Type == kEventInternalSetFocus || msg.Type == kEventInternalKillFocus) {
|
||
HandleMessage(msg);
|
||
return;
|
||
}
|
||
|
||
bool bRet = true;
|
||
std::weak_ptr<nbase::WeakFlag> weakflag = GetWeakFlag();
|
||
if (this == msg.pSender) {
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
auto callback = OnBubbledEvent.find(msg.Type);
|
||
if (callback != OnBubbledEvent.end()) {
|
||
bRet = callback->second(&msg);
|
||
}
|
||
if (weakflag.expired()) {
|
||
return;
|
||
}
|
||
|
||
callback = OnBubbledEvent.find(kEventAll);
|
||
if (callback != OnBubbledEvent.end()) {
|
||
bRet = callback->second(&msg);
|
||
}
|
||
if (weakflag.expired()) {
|
||
return;
|
||
}
|
||
|
||
if (bRet) {
|
||
auto callback = OnXmlBubbledEvent.find(msg.Type);
|
||
if (callback != OnXmlBubbledEvent.end()) {
|
||
bRet = callback->second(&msg);
|
||
}
|
||
if (weakflag.expired()) {
|
||
return;
|
||
}
|
||
|
||
callback = OnXmlBubbledEvent.find(kEventAll);
|
||
if (callback != OnXmlBubbledEvent.end()) {
|
||
bRet = callback->second(&msg);
|
||
}
|
||
if (weakflag.expired()) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (bRet) {
|
||
HandleMessage(msg);
|
||
}
|
||
}
|
||
|
||
void Box::PaintChild(IRenderContext* pRender, const UiRect& rcPaint)
|
||
{
|
||
UiRect rcTemp;
|
||
if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return;
|
||
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
Control* pControl = *it;
|
||
if( !pControl->IsVisible() ) continue;
|
||
pControl->AlphaPaint(pRender, rcPaint);
|
||
}
|
||
}
|
||
|
||
void Box::SetVisible_(bool bVisible)
|
||
{
|
||
__super::SetVisible_(bVisible);
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->SetInternVisible(IsVisible());
|
||
}
|
||
}
|
||
|
||
// <20><EFBFBD><DFBC>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD>Container<65>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˷<EFBFBD><CBB7><EFBFBD>
|
||
// <20><><EFBFBD>ô˷<C3B4><CBB7><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3>ڲ<EFBFBD><DAB2>ӿؼ<D3BF><D8BC><EFBFBD><EFBFBD>أ<EFBFBD><D8A3>ؼ<EFBFBD><D8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
void Box::SetInternVisible(bool bVisible)
|
||
{
|
||
Control::SetInternVisible(bVisible);
|
||
if (m_items.empty()) return;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ӿؼ<D3BF><D8BC><EFBFBD>ʾ״̬
|
||
// InternVisible״̬Ӧ<CCAC><D3A6><EFBFBD>ӿؼ<D3BF><D8BC>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD>
|
||
(*it)->SetInternVisible(IsVisible());
|
||
}
|
||
}
|
||
|
||
void Box::SetEnabled(bool bEnabled)
|
||
{
|
||
if (m_bEnabled == bEnabled) return;
|
||
|
||
Control::SetEnabled(bEnabled);
|
||
if (m_items.empty()) return;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->SetEnabled(bEnabled);
|
||
}
|
||
|
||
Invalidate();
|
||
}
|
||
|
||
CSize Box::EstimateSize(CSize szAvailable)
|
||
{
|
||
CSize fixedSize = m_cxyFixed;
|
||
if (GetFixedWidth() == DUI_LENGTH_AUTO || GetFixedHeight() == DUI_LENGTH_AUTO) {
|
||
if (!m_bReEstimateSize) {
|
||
return m_szEstimateSize;
|
||
}
|
||
|
||
szAvailable.cx -= m_pLayout->GetPadding().left + m_pLayout->GetPadding().right;
|
||
szAvailable.cy -= m_pLayout->GetPadding().top + m_pLayout->GetPadding().bottom;
|
||
CSize sizeByChild = m_pLayout->AjustSizeByChild(m_items, szAvailable);
|
||
if (GetFixedWidth() == DUI_LENGTH_AUTO) {
|
||
fixedSize.cx = sizeByChild.cx;
|
||
}
|
||
if (GetFixedHeight() == DUI_LENGTH_AUTO) {
|
||
fixedSize.cy = sizeByChild.cy;
|
||
}
|
||
|
||
m_bReEstimateSize = false;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if (!(*it)->IsVisible()) {
|
||
continue;
|
||
}
|
||
if ((*it)->GetFixedWidth() == DUI_LENGTH_AUTO || (*it)->GetFixedHeight() == DUI_LENGTH_AUTO) {
|
||
if ((*it)->IsReEstimateSize()) {
|
||
m_bReEstimateSize = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
m_szEstimateSize = fixedSize;
|
||
}
|
||
|
||
return fixedSize;
|
||
}
|
||
|
||
Control* Box::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags, CPoint scrollPos)
|
||
{
|
||
// Check if this guy is valid
|
||
if ((uFlags & UIFIND_VISIBLE) != 0 && !IsVisible()) return NULL;
|
||
if ((uFlags & UIFIND_ENABLED) != 0 && !IsEnabled()) return NULL;
|
||
if ((uFlags & UIFIND_HITTEST) != 0) {
|
||
if (!::PtInRect(&m_rcItem, *(static_cast<LPPOINT>(pData)))) return NULL;
|
||
if (!m_bMouseChildEnabled) {
|
||
Control* pResult = NULL;
|
||
if (pResult == NULL) pResult = Control::FindControl(Proc, pData, uFlags);
|
||
return pResult;
|
||
}
|
||
}
|
||
|
||
Control* pResult = NULL;
|
||
if (pResult != NULL) return pResult;
|
||
|
||
if ((uFlags & UIFIND_ME_FIRST) != 0) {
|
||
Control* pControl = Control::FindControl(Proc, pData, uFlags);
|
||
if (pControl != NULL) return pControl;
|
||
}
|
||
UiRect rc = m_rcItem;
|
||
rc.left += m_pLayout->GetPadding().left;
|
||
rc.top += m_pLayout->GetPadding().top;
|
||
rc.right -= m_pLayout->GetPadding().right;
|
||
rc.bottom -= m_pLayout->GetPadding().bottom;
|
||
|
||
if ((uFlags & UIFIND_TOP_FIRST) != 0) {
|
||
for (int it = (int)m_items.size() - 1; it >= 0; it--) {
|
||
Control* pControl;
|
||
if ((uFlags & UIFIND_HITTEST) != 0) {
|
||
CPoint newPoint = *(static_cast<LPPOINT>(pData));
|
||
newPoint.Offset(scrollPos);
|
||
pControl = m_items[it]->FindControl(Proc, &newPoint, uFlags);
|
||
}
|
||
else {
|
||
pControl = m_items[it]->FindControl(Proc, pData, uFlags);
|
||
}
|
||
if (pControl != NULL) {
|
||
if ((uFlags & UIFIND_HITTEST) != 0 && !pControl->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))))
|
||
continue;
|
||
else
|
||
return pControl;
|
||
}
|
||
}
|
||
}
|
||
else {
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
Control* pControl;
|
||
if ((uFlags & UIFIND_HITTEST) != 0) {
|
||
CPoint newPoint = *(static_cast<LPPOINT>(pData));
|
||
newPoint.Offset(scrollPos);
|
||
pControl = (*it)->FindControl(Proc, &newPoint, uFlags);
|
||
}
|
||
else {
|
||
pControl = (*it)->FindControl(Proc, pData, uFlags);
|
||
}
|
||
if (pControl != NULL) {
|
||
if ((uFlags & UIFIND_HITTEST) != 0 && !pControl->IsFloat() && !::PtInRect(&rc, *(static_cast<LPPOINT>(pData))))
|
||
continue;
|
||
else
|
||
return pControl;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (pResult == NULL && (uFlags & UIFIND_ME_FIRST) == 0) pResult = Control::FindControl(Proc, pData, uFlags);
|
||
return pResult;
|
||
}
|
||
|
||
Control* Box::FindSubControl(const std::wstring& pstrSubControlName)
|
||
{
|
||
Control* pSubControl = NULL;
|
||
pSubControl = static_cast<Control*>(GetWindow()->FindSubControlByName(this, pstrSubControlName));
|
||
return pSubControl;
|
||
}
|
||
|
||
int Box::FindSelectable(int iIndex, bool bForward /*= true*/) const
|
||
{
|
||
// NOTE: This is actually a helper-function for the list/combo/ect controls
|
||
// that allow them to find the next enabled/available selectable item
|
||
if (GetCount() == 0) return -1;
|
||
iIndex = CLAMP(iIndex, 0, GetCount() - 1);
|
||
if (bForward) {
|
||
for (int i = iIndex; i < GetCount(); i++) {
|
||
if (dynamic_cast<ListContainerElement*>(GetItemAt(i)) != NULL
|
||
&& GetItemAt(i)->IsVisible()
|
||
&& GetItemAt(i)->IsEnabled()) return i;
|
||
}
|
||
return -1;
|
||
}
|
||
else {
|
||
for (int i = iIndex; i >= 0; --i) {
|
||
if (dynamic_cast<ListContainerElement*>(GetItemAt(i)) != NULL
|
||
&& GetItemAt(i)->IsVisible()
|
||
&& GetItemAt(i)->IsEnabled()) return i;
|
||
}
|
||
return FindSelectable(0, true);
|
||
}
|
||
}
|
||
|
||
Control* Box::GetItemAt(std::size_t iIndex) const
|
||
{
|
||
if( iIndex < 0 || iIndex >= m_items.size() ) return NULL;
|
||
return static_cast<Control*>(m_items[iIndex]);
|
||
}
|
||
|
||
int Box::GetItemIndex(Control* pControl) const
|
||
{
|
||
auto it = std::find(m_items.begin(), m_items.end(), pControl);
|
||
if (it == m_items.end()) {
|
||
return -1;
|
||
}
|
||
return it - m_items.begin();
|
||
}
|
||
|
||
bool Box::SetItemIndex(Control* pControl, std::size_t iIndex)
|
||
{
|
||
if( iIndex < 0 || iIndex >= m_items.size() ) return false;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if( *it == pControl ) {
|
||
Arrange();
|
||
m_items.erase(it);
|
||
m_items.insert(m_items.begin() + iIndex, pControl);
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
int Box::GetCount() const
|
||
{
|
||
return (int)m_items.size();
|
||
}
|
||
|
||
bool Box::Add(Control* pControl)
|
||
{
|
||
if( pControl == NULL) return false;
|
||
|
||
if( m_pWindow != NULL ) m_pWindow->InitControls(pControl, this);
|
||
if( IsVisible() )
|
||
Arrange();
|
||
else
|
||
pControl->SetInternVisible(false);
|
||
m_items.push_back(pControl);
|
||
return true;
|
||
}
|
||
|
||
bool Box::AddAt(Control* pControl, std::size_t iIndex)
|
||
{
|
||
if( pControl == NULL) return false;
|
||
if( iIndex < 0 || iIndex > m_items.size() ) {
|
||
ASSERT(FALSE);
|
||
return false;
|
||
}
|
||
if( m_pWindow != NULL ) m_pWindow->InitControls(pControl, this);
|
||
if( IsVisible() )
|
||
Arrange();
|
||
else
|
||
pControl->SetInternVisible(false);
|
||
m_items.insert(m_items.begin() + iIndex, pControl);
|
||
return true;
|
||
}
|
||
|
||
bool Box::Remove(Control* pControl)
|
||
{
|
||
if( pControl == NULL) return false;
|
||
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if( *it == pControl ) {
|
||
Arrange();
|
||
if( m_bAutoDestroy ) {
|
||
if( m_bDelayedDestroy && m_pWindow ) m_pWindow->AddDelayedCleanup(pControl);
|
||
else delete pControl;
|
||
}
|
||
m_items.erase(it);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool Box::RemoveAt(std::size_t iIndex)
|
||
{
|
||
Control* pControl = GetItemAt(iIndex);
|
||
if (pControl != NULL) {
|
||
return Box::Remove(pControl);
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
void Box::RemoveAll()
|
||
{
|
||
if (m_bAutoDestroy) {
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if( m_bDelayedDestroy && m_pWindow ) m_pWindow->AddDelayedCleanup((*it));
|
||
else delete (*it);
|
||
}
|
||
}
|
||
|
||
m_items.clear();
|
||
Arrange();
|
||
}
|
||
|
||
void Box::SwapChild(Control* pChild1, Control* pChild2)
|
||
{
|
||
ASSERT(std::find(m_items.begin(), m_items.end(), pChild1) != m_items.end());
|
||
ASSERT(std::find(m_items.begin(), m_items.end(), pChild2) != m_items.end());
|
||
|
||
std::vector<Control*>::iterator it1, it2;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if (*it == pChild1 || *it == pChild2) {
|
||
Control* child = (*it == pChild1) ? pChild2 : pChild1;
|
||
it = m_items.erase(it);
|
||
it = m_items.insert(it, child);
|
||
}
|
||
}
|
||
}
|
||
|
||
void Box::ResetChildIndex(Control* pChild, std::size_t iIndex)
|
||
{
|
||
ASSERT(std::find(m_items.begin(), m_items.end(), pChild) != m_items.end());
|
||
|
||
std::size_t oldIndex = 0;
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
if (*it == pChild) {
|
||
m_items.erase(it);
|
||
if (oldIndex >= iIndex) {
|
||
AddAt(pChild, iIndex);
|
||
}
|
||
else {
|
||
AddAt(pChild, iIndex - 1);
|
||
}
|
||
|
||
break;
|
||
}
|
||
oldIndex++;
|
||
}
|
||
}
|
||
|
||
bool Box::IsAutoDestroy() const
|
||
{
|
||
return m_bAutoDestroy;
|
||
}
|
||
|
||
void Box::SetAutoDestroy(bool bAuto)
|
||
{
|
||
m_bAutoDestroy = bAuto;
|
||
}
|
||
|
||
bool Box::IsDelayedDestroy() const
|
||
{
|
||
return m_bDelayedDestroy;
|
||
}
|
||
|
||
void Box::SetDelayedDestroy(bool bDelayed)
|
||
{
|
||
m_bDelayedDestroy = bDelayed;
|
||
}
|
||
|
||
bool Box::IsMouseChildEnabled() const
|
||
{
|
||
return m_bMouseChildEnabled;
|
||
}
|
||
|
||
void Box::SetMouseChildEnabled(bool bEnable)
|
||
{
|
||
m_bMouseChildEnabled = bEnable;
|
||
}
|
||
|
||
Layout* Box::GetLayout() const
|
||
{
|
||
return m_pLayout.get();
|
||
}
|
||
|
||
void Box::RetSetLayout(Layout* pLayout)
|
||
{
|
||
m_pLayout.reset(pLayout);
|
||
}
|
||
|
||
UiRect Box::GetPaddingPos() const
|
||
{
|
||
UiRect pos = GetPos();
|
||
UiRect padding = m_pLayout->GetPadding();
|
||
pos.left += padding.left;
|
||
pos.top += padding.top;
|
||
pos.right -= padding.right;
|
||
pos.bottom -= padding.bottom;
|
||
|
||
return pos;
|
||
}
|
||
|
||
void Box::InvokeLoadImageCache()
|
||
{
|
||
__super::InvokeLoadImageCache();
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->InvokeLoadImageCache();
|
||
}
|
||
}
|
||
|
||
void Box::UnLoadImageCache()
|
||
{
|
||
__super::UnLoadImageCache();
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->UnLoadImageCache();
|
||
}
|
||
}
|
||
|
||
void Box::ClearImageCache()
|
||
{
|
||
__super::ClearImageCache();
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
(*it)->ClearImageCache();
|
||
}
|
||
}
|
||
|
||
UINT Box::GetControlFlags() const
|
||
{
|
||
return UIFLAG_DEFAULT; // Box Ĭ<>ϲ<EFBFBD>֧<EFBFBD><D6A7> TAB <20>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD>
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////
|
||
//
|
||
//
|
||
|
||
ScrollableBox::ScrollableBox(Layout* pLayout) :
|
||
Box(pLayout),
|
||
m_pVerticalScrollBar(),
|
||
m_pHorizontalScrollBar(),
|
||
m_nVerScrollUnitPixels(30),
|
||
m_nHerScrollUnitPixels(30),
|
||
m_bScrollProcess(false),
|
||
m_bScrollBarFloat(true),
|
||
m_bHoldEnd(false),
|
||
m_bDefaultDisplayScrollbar(true),
|
||
m_rcScrollBarPadding(),
|
||
m_ptLastTouchPos(-1, -1),
|
||
m_scrollAnimation(),
|
||
m_renderOffsetYAnimation()
|
||
{
|
||
m_rcScrollBarPadding.left = m_rcScrollBarPadding.top = m_rcScrollBarPadding.right = m_rcScrollBarPadding.bottom = 0;
|
||
}
|
||
|
||
ScrollableBox::ScrollableBox(const ScrollableBox& r):
|
||
Box(r),
|
||
m_nVerScrollUnitPixels(r.m_nVerScrollUnitPixels),
|
||
m_nHerScrollUnitPixels(r.m_nHerScrollUnitPixels),
|
||
m_bScrollProcess(r.m_bScrollProcess),
|
||
m_bScrollBarFloat(r.m_bScrollBarFloat),
|
||
m_bHoldEnd(r.m_bHoldEnd),
|
||
m_bDefaultDisplayScrollbar(r.m_bDefaultDisplayScrollbar),
|
||
m_rcScrollBarPadding(r.m_rcScrollBarPadding),
|
||
m_ptLastTouchPos(r.m_ptLastTouchPos),
|
||
m_scrollAnimation(),
|
||
m_renderOffsetYAnimation()
|
||
{
|
||
m_pVerticalScrollBar.reset(new ScrollBar(*m_pVerticalScrollBar.get()));
|
||
m_pVerticalScrollBar->SetOwner(this);
|
||
m_pHorizontalScrollBar.reset(new ScrollBar(*m_pHorizontalScrollBar.get()));
|
||
m_pHorizontalScrollBar->SetOwner(this);
|
||
}
|
||
|
||
void ScrollableBox::SetAttribute(const std::wstring& pstrName, const std::wstring& pstrValue)
|
||
{
|
||
if( pstrName == _T("vscrollbar") ) {
|
||
EnableScrollBar(pstrValue == _T("true"), GetHorizontalScrollBar() != NULL);
|
||
}
|
||
else if( pstrName == _T("vscrollbarstyle") ) {
|
||
EnableScrollBar(true, GetHorizontalScrollBar() != NULL);
|
||
if( GetVerticalScrollBar() ) GetVerticalScrollBar()->ApplyAttributeList(pstrValue);
|
||
}
|
||
else if( pstrName == _T("hscrollbar") ) {
|
||
EnableScrollBar(GetVerticalScrollBar() != NULL, pstrValue == _T("true"));
|
||
}
|
||
else if( pstrName == _T("hscrollbarstyle") ) {
|
||
EnableScrollBar(GetVerticalScrollBar() != NULL, true);
|
||
if( GetHorizontalScrollBar() ) GetHorizontalScrollBar()->ApplyAttributeList(pstrValue);
|
||
}
|
||
else if( pstrName == _T("scrollbarpadding") ) {
|
||
UiRect rcScrollbarPadding;
|
||
LPTSTR pstr = NULL;
|
||
rcScrollbarPadding.left = _tcstol(pstrValue.c_str(), &pstr, 10); ASSERT(pstr);
|
||
rcScrollbarPadding.top = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
rcScrollbarPadding.right = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
rcScrollbarPadding.bottom = _tcstol(pstr + 1, &pstr, 10); ASSERT(pstr);
|
||
SetScrollBarPadding(rcScrollbarPadding);
|
||
}
|
||
else if( pstrName == _T("vscrollunit") ) SetVerScrollUnitPixels(_ttoi(pstrValue.c_str()));
|
||
else if (pstrName == _T("hscrollunit")) SetHorScrollUnitPixels(_ttoi(pstrValue.c_str()));
|
||
else if( pstrName == _T("scrollbarfloat") ) SetScrollBarFloat(pstrValue == _T("true"));
|
||
else if( pstrName == _T("defaultdisplayscrollbar") ) SetDefaultDisplayScrollbar(pstrValue == _T("true"));
|
||
else if( pstrName == _T("holdend") ) SetHoldEnd(pstrValue == _T("true"));
|
||
else Box::SetAttribute(pstrName, pstrValue);
|
||
}
|
||
|
||
void ScrollableBox::SetPos(UiRect rc)
|
||
{
|
||
bool bEndDown = false;
|
||
if (IsHoldEnd() && IsVScrollBarValid() && GetScrollRange().cy - GetScrollPos().cy == 0) {
|
||
bEndDown = true;
|
||
}
|
||
SetPosInternally(rc);
|
||
if (bEndDown && IsVScrollBarValid()) {
|
||
EndDown(false, false);
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::SetPosInternally(UiRect rc)
|
||
{
|
||
Control::SetPos(rc);
|
||
UiRect rcRaw = rc;
|
||
rc.left += m_pLayout->GetPadding().left;
|
||
rc.top += m_pLayout->GetPadding().top;
|
||
rc.right -= m_pLayout->GetPadding().right;
|
||
rc.bottom -= m_pLayout->GetPadding().bottom;
|
||
|
||
CSize requiredSize = CalcRequiredSize(rc);
|
||
ProcessVScrollBar(rcRaw, requiredSize.cy);
|
||
ProcessHScrollBar(rcRaw, requiredSize.cx);
|
||
}
|
||
CSize ScrollableBox::CalcRequiredSize(const UiRect& rc)
|
||
{
|
||
CSize requiredSize;
|
||
if (m_items.size() == 0) {
|
||
requiredSize.cx = 0;
|
||
requiredSize.cy = 0;
|
||
}
|
||
else {
|
||
UiRect childSize = rc;
|
||
if (!m_bScrollBarFloat && m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid()) {
|
||
childSize.right -= m_pVerticalScrollBar->GetFixedWidth();
|
||
}
|
||
if (!m_bScrollBarFloat && m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid()) {
|
||
childSize.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
|
||
}
|
||
requiredSize = m_pLayout->ArrangeChild(m_items, childSize);
|
||
}
|
||
return requiredSize;
|
||
}
|
||
void ScrollableBox::HandleMessage(EventArgs& event)
|
||
{
|
||
if( !IsMouseEnabled() && event.Type > kEventMouseBegin && event.Type < kEventMouseEnd ) {
|
||
if( m_pParent != NULL ) m_pParent->HandleMessageTemplate(event);
|
||
else Box::HandleMessage(event);
|
||
return;
|
||
}
|
||
|
||
if( m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsValid() && m_pVerticalScrollBar->IsEnabled() ) {
|
||
if( event.Type == kEventKeyDown ) {
|
||
switch( event.chKey ) {
|
||
case VK_DOWN:
|
||
LineDown();
|
||
return;
|
||
case VK_UP:
|
||
LineUp();
|
||
return;
|
||
case VK_NEXT:
|
||
PageDown();
|
||
return;
|
||
case VK_PRIOR:
|
||
PageUp();
|
||
return;
|
||
case VK_HOME:
|
||
HomeUp();
|
||
return;
|
||
case VK_END:
|
||
EndDown();
|
||
return;
|
||
}
|
||
}
|
||
else if( event.Type == kEventMouseScrollWheel ) {
|
||
int deltaValue = event.wParam;
|
||
if (deltaValue > 0 ) {
|
||
LineUp(abs(deltaValue));
|
||
}
|
||
else {
|
||
LineDown(abs(deltaValue));
|
||
}
|
||
|
||
return;
|
||
}
|
||
else if (event.Type == kEventTouchDown || event.Type == kEventPointDown) {
|
||
if (IsEnabled()) {
|
||
SetMouseFocused(true);
|
||
m_ptLastTouchPos = event.ptMouse;
|
||
return;
|
||
}
|
||
}
|
||
else if (event.Type == kEventTouchMove || event.Type == kEventPointMove) {
|
||
if (IsMouseFocused()) {
|
||
int detaValue = event.ptMouse.y - m_ptLastTouchPos.y;
|
||
if (detaValue == 0)
|
||
return;
|
||
|
||
m_ptLastTouchPos = event.ptMouse;
|
||
|
||
if (detaValue > 0) {
|
||
TouchUp(abs(detaValue));
|
||
}
|
||
else {
|
||
TouchDown(abs(detaValue));
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
else if (event.Type == kEventTouchUp || event.Type == kEventPointUp) {
|
||
if (IsMouseFocused()) {
|
||
SetMouseFocused(false);
|
||
m_ptLastTouchPos = event.ptMouse;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
else if( m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsValid() && m_pHorizontalScrollBar->IsEnabled() ) {
|
||
if( event.Type == kEventKeyDown ) {
|
||
switch( event.chKey ) {
|
||
case VK_DOWN:
|
||
LineRight();
|
||
return;
|
||
case VK_UP:
|
||
LineLeft();
|
||
return;
|
||
case VK_NEXT:
|
||
PageRight();
|
||
return;
|
||
case VK_PRIOR:
|
||
PageLeft();
|
||
return;
|
||
case VK_HOME:
|
||
HomeLeft();
|
||
return;
|
||
case VK_END:
|
||
EndRight();
|
||
return;
|
||
}
|
||
}
|
||
else if( event.Type == kEventMouseScrollWheel ) {
|
||
int deltaValue = event.wParam;
|
||
if (deltaValue > 0 ) {
|
||
LineLeft();
|
||
return;
|
||
}
|
||
else {
|
||
LineRight();
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
Box::HandleMessage(event);
|
||
}
|
||
|
||
bool ScrollableBox::MouseEnter(EventArgs& msg)
|
||
{
|
||
bool bRet = __super::MouseEnter(msg);
|
||
if (bRet && m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsValid() && m_pVerticalScrollBar->IsEnabled()) {
|
||
if (m_pVerticalScrollBar->IsAutoHideScroll()) {
|
||
m_pVerticalScrollBar->SetVisible(true);
|
||
}
|
||
}
|
||
if (bRet && m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsValid() && m_pHorizontalScrollBar->IsEnabled()) {
|
||
if (m_pHorizontalScrollBar->IsAutoHideScroll()) {
|
||
m_pHorizontalScrollBar->SetVisible(true);
|
||
}
|
||
}
|
||
|
||
return bRet;
|
||
}
|
||
|
||
bool ScrollableBox::MouseLeave(EventArgs& msg)
|
||
{
|
||
bool bRet = __super::MouseLeave(msg);
|
||
if (bRet && m_pVerticalScrollBar != NULL && m_pVerticalScrollBar->IsValid() && m_pVerticalScrollBar->IsEnabled()) {
|
||
if (m_pVerticalScrollBar->GetThumbState() == kControlStateNormal
|
||
&& m_pVerticalScrollBar->IsAutoHideScroll()) {
|
||
m_pVerticalScrollBar->SetVisible(false);
|
||
}
|
||
}
|
||
if (bRet && m_pHorizontalScrollBar != NULL && m_pHorizontalScrollBar->IsValid() && m_pHorizontalScrollBar->IsEnabled()) {
|
||
if (m_pHorizontalScrollBar->GetThumbState() == kControlStateNormal
|
||
&& m_pHorizontalScrollBar->IsAutoHideScroll()) {
|
||
m_pHorizontalScrollBar->SetVisible(false);
|
||
}
|
||
}
|
||
|
||
return bRet;
|
||
}
|
||
|
||
void ScrollableBox::PaintChild(IRenderContext* pRender, const UiRect& rcPaint)
|
||
{
|
||
UiRect rcTemp;
|
||
if( !::IntersectRect(&rcTemp, &rcPaint, &m_rcItem) ) return;
|
||
|
||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||
Control* pControl = *it;
|
||
if( !pControl->IsVisible() ) continue;
|
||
if (pControl->IsFloat()) {
|
||
pControl->AlphaPaint(pRender, rcPaint);
|
||
}
|
||
else {
|
||
CSize scrollPos = GetScrollPos();
|
||
UiRect rcNewPaint = GetPaddingPos();
|
||
AutoClip alphaClip(pRender, rcNewPaint, m_bClip);
|
||
rcNewPaint.Offset(scrollPos.cx, scrollPos.cy);
|
||
rcNewPaint.Offset(GetRenderOffset().x, GetRenderOffset().y);
|
||
|
||
CPoint ptOffset(scrollPos.cx, scrollPos.cy);
|
||
CPoint ptOldOrg = pRender->OffsetWindowOrg(ptOffset);
|
||
pControl->AlphaPaint(pRender, rcNewPaint);
|
||
pRender->SetWindowOrg(ptOldOrg);
|
||
}
|
||
}
|
||
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) {
|
||
m_pHorizontalScrollBar->AlphaPaint(pRender, rcPaint);
|
||
}
|
||
|
||
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible()) {
|
||
m_pVerticalScrollBar->AlphaPaint(pRender, rcPaint);
|
||
}
|
||
|
||
static bool bFirstPaint = true;
|
||
if (bFirstPaint) {
|
||
bFirstPaint = false;
|
||
LoadImageCache(true);
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::SetMouseEnabled(bool bEnabled)
|
||
{
|
||
if (m_pVerticalScrollBar != NULL) m_pVerticalScrollBar->SetMouseEnabled(bEnabled);
|
||
if (m_pHorizontalScrollBar != NULL) m_pHorizontalScrollBar->SetMouseEnabled(bEnabled);
|
||
Box::SetMouseEnabled(bEnabled);
|
||
}
|
||
|
||
void ScrollableBox::SetWindow(Window* pManager, Box* pParent, bool bInit)
|
||
{
|
||
if (m_pVerticalScrollBar != NULL) m_pVerticalScrollBar->SetWindow(pManager, this, bInit);
|
||
if (m_pHorizontalScrollBar != NULL) m_pHorizontalScrollBar->SetWindow(pManager, this, bInit);
|
||
Box::SetWindow(pManager, pParent, bInit);
|
||
}
|
||
|
||
Control* ScrollableBox::FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags, CPoint scrollPos)
|
||
{
|
||
// Check if this guy is valid
|
||
if ((uFlags & UIFIND_VISIBLE) != 0 && !IsVisible()) return NULL;
|
||
if ((uFlags & UIFIND_ENABLED) != 0 && !IsEnabled()) return NULL;
|
||
if ((uFlags & UIFIND_HITTEST) != 0) {
|
||
if (!::PtInRect(&m_rcItem, *(static_cast<LPPOINT>(pData)))) return NULL;
|
||
if (!m_bMouseChildEnabled) {
|
||
Control* pResult = NULL;
|
||
if (m_pVerticalScrollBar != NULL) pResult = m_pVerticalScrollBar->FindControl(Proc, pData, uFlags);
|
||
if (pResult == NULL && m_pHorizontalScrollBar != NULL) pResult = m_pHorizontalScrollBar->FindControl(Proc, pData, uFlags);
|
||
if (pResult == NULL) pResult = Control::FindControl(Proc, pData, uFlags);
|
||
return pResult;
|
||
}
|
||
}
|
||
|
||
Control* pResult = NULL;
|
||
if (m_pVerticalScrollBar != NULL) pResult = m_pVerticalScrollBar->FindControl(Proc, pData, uFlags);
|
||
if (pResult == NULL && m_pHorizontalScrollBar != NULL) pResult = m_pHorizontalScrollBar->FindControl(Proc, pData, uFlags);
|
||
if (pResult != NULL) return pResult;
|
||
|
||
CPoint ptNewScrollPos(GetScrollPos().cx, GetScrollPos().cy);
|
||
return Box::FindControl(Proc, pData, uFlags, ptNewScrollPos);
|
||
}
|
||
|
||
CSize ScrollableBox::GetScrollPos() const
|
||
{
|
||
CSize sz;
|
||
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid() ) sz.cy = m_pVerticalScrollBar->GetScrollPos();
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid() ) sz.cx = m_pHorizontalScrollBar->GetScrollPos();
|
||
return sz;
|
||
}
|
||
|
||
CSize ScrollableBox::GetScrollRange() const
|
||
{
|
||
CSize sz;
|
||
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid() ) sz.cy = m_pVerticalScrollBar->GetScrollRange();
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid() ) sz.cx = m_pHorizontalScrollBar->GetScrollRange();
|
||
return sz;
|
||
}
|
||
|
||
void ScrollableBox::SetScrollPos(CSize szPos)
|
||
{
|
||
if (szPos.cy < 0) {
|
||
szPos.cy = 0;
|
||
m_scrollAnimation.Reset();
|
||
}
|
||
else if (szPos.cy > GetScrollRange().cy) {
|
||
szPos.cy = GetScrollRange().cy;
|
||
m_scrollAnimation.Reset();
|
||
}
|
||
|
||
int cx = 0;
|
||
int cy = 0;
|
||
if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid() ) {
|
||
int iLastScrollPos = m_pVerticalScrollBar->GetScrollPos();
|
||
m_pVerticalScrollBar->SetScrollPos(szPos.cy);
|
||
cy = m_pVerticalScrollBar->GetScrollPos() - iLastScrollPos;
|
||
}
|
||
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid() ) {
|
||
int iLastScrollPos = m_pHorizontalScrollBar->GetScrollPos();
|
||
m_pHorizontalScrollBar->SetScrollPos(szPos.cx);
|
||
cx = m_pHorizontalScrollBar->GetScrollPos() - iLastScrollPos;
|
||
}
|
||
|
||
if( cx == 0 && cy == 0 ) return;
|
||
LoadImageCache(cy > 0);
|
||
Invalidate();
|
||
if( m_pWindow != NULL ) {
|
||
m_pWindow->SendNotify(this, kEventScrollChange);
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::LoadImageCache(bool bFromTopLeft)
|
||
{
|
||
CSize scrollPos = GetScrollPos();
|
||
|
||
auto forEach = [this, scrollPos](ui::Control* pControl) {
|
||
if (!pControl->IsVisible()) return;
|
||
if (pControl->IsFloat()) return;
|
||
UiRect rcTemp;
|
||
UiRect rcImageCachePos = GetPos();
|
||
rcImageCachePos.Offset(scrollPos.cx, scrollPos.cy);
|
||
rcImageCachePos.Offset(GetRenderOffset().x, GetRenderOffset().y);
|
||
rcImageCachePos.Inflate(UiRect(0, 730, 0, 730));
|
||
UiRect controlPos = pControl->GetPos();
|
||
if (!::IntersectRect(&rcTemp, &rcImageCachePos, &controlPos)) {
|
||
pControl->UnLoadImageCache();
|
||
}
|
||
else {
|
||
pControl->InvokeLoadImageCache();
|
||
}
|
||
};
|
||
|
||
if (!bFromTopLeft) {
|
||
std::for_each(m_items.rbegin(), m_items.rend(), forEach);
|
||
}
|
||
else {
|
||
std::for_each(m_items.begin(), m_items.end(), forEach);
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::SetScrollPosY(int y)
|
||
{
|
||
CSize scrollPos = GetScrollPos();
|
||
scrollPos.cy = y;
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
|
||
void ScrollableBox::SetScrollPosX(int x)
|
||
{
|
||
CSize scrollPos = GetScrollPos();
|
||
scrollPos.cx = x;
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
|
||
void ScrollableBox::LineUp(int deltaValue, bool withAnimation)
|
||
{
|
||
int cyLine = GetVerScrollUnitPixels();
|
||
if (cyLine == 0) {
|
||
cyLine = 20;
|
||
}
|
||
if (deltaValue != DUI_NOSET_VALUE) {
|
||
cyLine = min(cyLine, deltaValue);
|
||
}
|
||
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cy <= 0) {
|
||
return;
|
||
}
|
||
|
||
if (!withAnimation) {
|
||
scrollPos.cy -= cyLine;
|
||
if (scrollPos.cy < 0)
|
||
{
|
||
scrollPos.cy = 0;
|
||
}
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetStartValue(scrollPos.cy);
|
||
if (m_scrollAnimation.IsPlaying()) {
|
||
if (m_scrollAnimation.GetEndValue() > m_scrollAnimation.GetStartValue()) {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cy - cyLine);
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(m_scrollAnimation.GetEndValue() - cyLine);
|
||
}
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cy - cyLine);
|
||
}
|
||
m_scrollAnimation.SetSpeedUpRatio(0);
|
||
m_scrollAnimation.SetSpeedDownfactorA(-0.012);
|
||
m_scrollAnimation.SetSpeedDownRatio(0.5);
|
||
m_scrollAnimation.SetTotalMillSeconds(DUI_NOSET_VALUE);
|
||
m_scrollAnimation.SetCallback(nbase::Bind(&ScrollableBox::SetScrollPosY, this, std::placeholders::_1));
|
||
m_scrollAnimation.Start();
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::LineDown(int deltaValue, bool withAnimation)
|
||
{
|
||
int cyLine = GetVerScrollUnitPixels();
|
||
if (cyLine == 0) {
|
||
cyLine = 20;
|
||
}
|
||
if (deltaValue != DUI_NOSET_VALUE) {
|
||
cyLine = min(cyLine, deltaValue);
|
||
}
|
||
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cy >= GetScrollRange().cy) {
|
||
return;
|
||
}
|
||
|
||
if (!withAnimation) {
|
||
scrollPos.cy += cyLine;
|
||
if (scrollPos.cy < 0)
|
||
{
|
||
scrollPos.cy = 0;
|
||
}
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetStartValue(scrollPos.cy);
|
||
if (m_scrollAnimation.IsPlaying()) {
|
||
if (m_scrollAnimation.GetEndValue() < m_scrollAnimation.GetStartValue()) {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cy + cyLine);
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(m_scrollAnimation.GetEndValue() + cyLine);
|
||
}
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cy + cyLine);
|
||
}
|
||
m_scrollAnimation.SetSpeedUpRatio(0);
|
||
m_scrollAnimation.SetSpeedDownfactorA(-0.012);
|
||
m_scrollAnimation.SetSpeedDownRatio(0.5);
|
||
m_scrollAnimation.SetTotalMillSeconds(DUI_NOSET_VALUE);
|
||
m_scrollAnimation.SetCallback(nbase::Bind(&ScrollableBox::SetScrollPosY, this, std::placeholders::_1));
|
||
m_scrollAnimation.Start();
|
||
}
|
||
}
|
||
void ScrollableBox::LineLeft(int detaValue)
|
||
{
|
||
int cxLine = GetHorScrollUnitPixels();
|
||
if (cxLine == 0) {
|
||
cxLine = 20;
|
||
}
|
||
if (detaValue != DUI_NOSET_VALUE) {
|
||
cxLine = min(cxLine, detaValue);
|
||
}
|
||
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cx <= 0) {
|
||
return;
|
||
}
|
||
scrollPos.cx -= cxLine;
|
||
if (scrollPos.cx < 0)
|
||
{
|
||
scrollPos.cx = 0;
|
||
}
|
||
SetScrollPos(scrollPos);
|
||
/*m_scrollAnimation.SetStartValue(scrollPos.cx);
|
||
if (m_scrollAnimation.IsPlaying()) {
|
||
if (m_scrollAnimation.GetEndValue() > m_scrollAnimation.GetStartValue()) {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cx - cxLine);
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(m_scrollAnimation.GetEndValue() - cxLine);
|
||
}
|
||
}
|
||
else {
|
||
m_scrollAnimation.SetEndValue(scrollPos.cx - cxLine);
|
||
}
|
||
m_scrollAnimation.SetSpeedUpRatio(0);
|
||
m_scrollAnimation.SetSpeedDownfactorA(-0.012);
|
||
m_scrollAnimation.SetSpeedDownRatio(0.5);
|
||
m_scrollAnimation.SetTotalMillSeconds(DUI_NOSET_VALUE);
|
||
m_scrollAnimation.SetCallback(nbase::Bind(&ScrollableBox::SetScrollPosX, this, std::placeholders::_1));
|
||
m_scrollAnimation.Start();*/
|
||
|
||
}
|
||
|
||
void ScrollableBox::LineRight(int detaValue)
|
||
{
|
||
int cxLine = GetHorScrollUnitPixels();
|
||
if (cxLine == 0) {
|
||
cxLine = 20;
|
||
}
|
||
if (detaValue != DUI_NOSET_VALUE) {
|
||
cxLine = min(cxLine, detaValue);
|
||
}
|
||
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cx >= GetScrollRange().cx) {
|
||
return;
|
||
}
|
||
scrollPos.cx += cxLine;
|
||
if (scrollPos.cx > GetScrollRange().cx)
|
||
{
|
||
scrollPos.cx = GetScrollRange().cx;
|
||
}
|
||
SetScrollPos(scrollPos);
|
||
//m_scrollAnimation.SetStartValue(scrollPos.cx);
|
||
//if (m_scrollAnimation.IsPlaying()) {
|
||
// if (m_scrollAnimation.GetEndValue() < m_scrollAnimation.GetStartValue()) {
|
||
// m_scrollAnimation.SetEndValue(scrollPos.cx + cxLine);
|
||
// }
|
||
// else {
|
||
// m_scrollAnimation.SetEndValue(m_scrollAnimation.GetEndValue() + cxLine);
|
||
// }
|
||
//}
|
||
//else {
|
||
// m_scrollAnimation.SetEndValue(scrollPos.cx + cxLine);
|
||
//}
|
||
//m_scrollAnimation.SetSpeedUpRatio(0);
|
||
//m_scrollAnimation.SetSpeedDownfactorA(-0.012);
|
||
//m_scrollAnimation.SetSpeedDownRatio(0.5);
|
||
//m_scrollAnimation.SetTotalMillSeconds(DUI_NOSET_VALUE);
|
||
//m_scrollAnimation.SetCallback(nbase::Bind(&ScrollableBox::SetScrollPosX, this, std::placeholders::_1));
|
||
//m_scrollAnimation.Start();
|
||
}
|
||
void ScrollableBox::PageUp()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
int iOffset = m_rcItem.bottom - m_rcItem.top - m_pLayout->GetPadding().top - m_pLayout->GetPadding().bottom;
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
|
||
sz.cy -= iOffset;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::PageDown()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
int iOffset = m_rcItem.bottom - m_rcItem.top - m_pLayout->GetPadding().top - m_pLayout->GetPadding().bottom;
|
||
if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsValid() ) iOffset -= m_pHorizontalScrollBar->GetFixedHeight();
|
||
sz.cy += iOffset;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::HomeUp()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
sz.cy = 0;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::EndDown(bool arrange, bool withAnimation)
|
||
{
|
||
if (arrange) {
|
||
SetPosInternally(GetPos());
|
||
}
|
||
|
||
int renderOffsetY = GetScrollRange().cy - GetScrollPos().cy + (m_renderOffsetYAnimation.GetEndValue() - GetRenderOffset().y);
|
||
if (withAnimation == true && IsVScrollBarValid() && renderOffsetY > 0) {
|
||
PlayRenderOffsetYAnimation(-renderOffsetY);
|
||
}
|
||
|
||
CSize sz = GetScrollPos();
|
||
sz.cy = GetScrollRange().cy;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::PageLeft()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
int iOffset = m_rcItem.right - m_rcItem.left - m_pLayout->GetPadding().left - m_pLayout->GetPadding().right;
|
||
//if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
|
||
sz.cx -= iOffset;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::PageRight()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
int iOffset = m_rcItem.right - m_rcItem.left - m_pLayout->GetPadding().left - m_pLayout->GetPadding().right;
|
||
//if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsValid() ) iOffset -= m_pVerticalScrollBar->GetFixedWidth();
|
||
sz.cx += iOffset;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::HomeLeft()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
sz.cx = 0;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::EndRight()
|
||
{
|
||
CSize sz = GetScrollPos();
|
||
sz.cx = GetScrollRange().cx;
|
||
SetScrollPos(sz);
|
||
}
|
||
|
||
void ScrollableBox::TouchUp(int deltaValue)
|
||
{
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cy <= 0) {
|
||
return;
|
||
}
|
||
|
||
scrollPos.cy = scrollPos.cy - deltaValue;
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
|
||
void ScrollableBox::TouchDown(int deltaValue)
|
||
{
|
||
CSize scrollPos = GetScrollPos();
|
||
if (scrollPos.cy >= GetScrollRange().cy) {
|
||
return;
|
||
}
|
||
|
||
scrollPos.cy = scrollPos.cy + deltaValue;
|
||
SetScrollPos(scrollPos);
|
||
}
|
||
|
||
void ScrollableBox::EnableScrollBar(bool bEnableVertical, bool bEnableHorizontal)
|
||
{
|
||
if( bEnableVertical && !m_pVerticalScrollBar ) {
|
||
m_pVerticalScrollBar.reset(new ScrollBar);
|
||
m_pVerticalScrollBar->SetVisible_(false);
|
||
m_pVerticalScrollBar->SetScrollRange(0);
|
||
m_pVerticalScrollBar->SetOwner(this);
|
||
m_pVerticalScrollBar->SetWindow(m_pWindow, NULL, false);
|
||
m_pVerticalScrollBar->SetClass(_T("vscrollbar"));
|
||
}
|
||
else if( !bEnableVertical && m_pVerticalScrollBar ) {
|
||
m_pVerticalScrollBar.reset();
|
||
}
|
||
|
||
if( bEnableHorizontal && !m_pHorizontalScrollBar ) {
|
||
m_pHorizontalScrollBar.reset(new ScrollBar);
|
||
m_pHorizontalScrollBar->SetVisible_(false);
|
||
m_pHorizontalScrollBar->SetScrollRange(0);
|
||
m_pHorizontalScrollBar->SetHorizontal(true);
|
||
m_pHorizontalScrollBar->SetOwner(this);
|
||
m_pHorizontalScrollBar->SetWindow(m_pWindow, NULL, false);
|
||
m_pHorizontalScrollBar->SetClass(_T("hscrollbar"));
|
||
}
|
||
else if( !bEnableHorizontal && m_pHorizontalScrollBar ) {
|
||
m_pHorizontalScrollBar.reset();
|
||
}
|
||
|
||
Arrange();
|
||
}
|
||
|
||
ScrollBar* ScrollableBox::GetVerticalScrollBar() const
|
||
{
|
||
return m_pVerticalScrollBar.get();
|
||
}
|
||
|
||
ScrollBar* ScrollableBox::GetHorizontalScrollBar() const
|
||
{
|
||
return m_pHorizontalScrollBar.get();
|
||
}
|
||
|
||
void ScrollableBox::ProcessVScrollBar(UiRect rc, int cyRequired)
|
||
{
|
||
UiRect rcScrollBarPos = rc;
|
||
rcScrollBarPos.left += m_rcScrollBarPadding.left;
|
||
rcScrollBarPos.top += m_rcScrollBarPadding.top;
|
||
rcScrollBarPos.right -= m_rcScrollBarPadding.right;
|
||
rcScrollBarPos.bottom -= m_rcScrollBarPadding.bottom;
|
||
|
||
if( m_pVerticalScrollBar == NULL ) return;
|
||
|
||
rc.left += m_pLayout->GetPadding().left;
|
||
rc.top += m_pLayout->GetPadding().top;
|
||
rc.right -= m_pLayout->GetPadding().right;
|
||
rc.bottom -= m_pLayout->GetPadding().bottom;
|
||
int nHeight = rc.bottom - rc.top;
|
||
if (cyRequired > nHeight && !m_pVerticalScrollBar->IsValid()) {
|
||
m_pVerticalScrollBar->SetScrollRange(cyRequired - nHeight);
|
||
m_pVerticalScrollBar->SetScrollPos(0);
|
||
m_bScrollProcess = true;
|
||
SetPos(m_rcItem);
|
||
m_bScrollProcess = false;
|
||
|
||
return;
|
||
}
|
||
// No scrollbar required
|
||
if( !m_pVerticalScrollBar->IsValid() ) return;
|
||
|
||
// Scroll not needed anymore?
|
||
int cyScroll = cyRequired - nHeight;
|
||
if( cyScroll <= 0 && !m_bScrollProcess) {
|
||
m_pVerticalScrollBar->SetScrollPos(0);
|
||
m_pVerticalScrollBar->SetScrollRange(0);
|
||
SetPos(m_rcItem);
|
||
}
|
||
else {
|
||
UiRect rcVerScrollBarPos(rcScrollBarPos.right - m_pVerticalScrollBar->GetFixedWidth(), rcScrollBarPos.top, rcScrollBarPos.right, rcScrollBarPos.bottom);
|
||
m_pVerticalScrollBar->SetPos(rcVerScrollBarPos);
|
||
|
||
if( m_pVerticalScrollBar->GetScrollRange() != cyScroll ) {
|
||
int iScrollPos = m_pVerticalScrollBar->GetScrollPos();
|
||
m_pVerticalScrollBar->SetScrollRange(::abs(cyScroll));
|
||
if( !m_pVerticalScrollBar->IsValid() ) {
|
||
m_pVerticalScrollBar->SetScrollPos(0);
|
||
}
|
||
|
||
if( iScrollPos > m_pVerticalScrollBar->GetScrollPos() ) {
|
||
SetPos(m_rcItem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::ProcessHScrollBar(UiRect rc, int cxRequired)
|
||
{
|
||
UiRect rcScrollBarPos = rc;
|
||
rcScrollBarPos.left += m_rcScrollBarPadding.left;
|
||
rcScrollBarPos.top += m_rcScrollBarPadding.top;
|
||
rcScrollBarPos.right -= m_rcScrollBarPadding.right;
|
||
rcScrollBarPos.bottom -= m_rcScrollBarPadding.bottom;
|
||
|
||
if (m_pHorizontalScrollBar == NULL) return;
|
||
|
||
rc.left += m_pLayout->GetPadding().left;
|
||
rc.top += m_pLayout->GetPadding().top;
|
||
rc.right -= m_pLayout->GetPadding().right;
|
||
rc.bottom -= m_pLayout->GetPadding().bottom;
|
||
int nWidth = rc.right - rc.left;
|
||
if (cxRequired > nWidth && !m_pHorizontalScrollBar->IsValid()) {
|
||
m_pHorizontalScrollBar->SetScrollRange(cxRequired - nWidth);
|
||
m_pHorizontalScrollBar->SetScrollPos(0);
|
||
m_bScrollProcess = true;
|
||
SetPos(m_rcItem);
|
||
m_bScrollProcess = false;
|
||
|
||
return;
|
||
}
|
||
// No scrollbar required
|
||
if (!m_pHorizontalScrollBar->IsValid()) return;
|
||
|
||
// Scroll not needed anymore?
|
||
int cxScroll = cxRequired - nWidth;
|
||
if (cxScroll <= 0 && !m_bScrollProcess) {
|
||
m_pHorizontalScrollBar->SetScrollPos(0);
|
||
m_pHorizontalScrollBar->SetScrollRange(0);
|
||
SetPos(m_rcItem);
|
||
}
|
||
else {
|
||
UiRect rcVerScrollBarPos(rcScrollBarPos.left, rcScrollBarPos.bottom - m_pHorizontalScrollBar->GetFixedHeight(), rcScrollBarPos.right, rcScrollBarPos.bottom);
|
||
m_pHorizontalScrollBar->SetPos(rcVerScrollBarPos);
|
||
|
||
if (m_pHorizontalScrollBar->GetScrollRange() != cxScroll) {
|
||
int iScrollPos = m_pHorizontalScrollBar->GetScrollPos();
|
||
m_pHorizontalScrollBar->SetScrollRange(::abs(cxScroll));
|
||
if (!m_pHorizontalScrollBar->IsValid()) {
|
||
m_pHorizontalScrollBar->SetScrollPos(0);
|
||
}
|
||
|
||
if (iScrollPos > m_pHorizontalScrollBar->GetScrollPos()) {
|
||
SetPos(m_rcItem);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
bool ScrollableBox::IsVScrollBarValid() const
|
||
{
|
||
if (m_pVerticalScrollBar) {
|
||
return m_pVerticalScrollBar->IsValid();
|
||
}
|
||
return false;
|
||
}
|
||
|
||
bool ScrollableBox::IsHScrollBarValid() const
|
||
{
|
||
if (m_pHorizontalScrollBar) {
|
||
return m_pHorizontalScrollBar->IsValid();
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void ScrollableBox::ReomveLastItemAnimation()
|
||
{
|
||
int nStartRang = GetScrollRange().cy;
|
||
SetPosInternally(GetPos());
|
||
int nEndRang = GetScrollRange().cy;
|
||
|
||
int nRenderOffset = nEndRang - nStartRang + (m_renderOffsetYAnimation.GetEndValue() - GetRenderOffset().y);
|
||
if (nRenderOffset < 0) {
|
||
PlayRenderOffsetYAnimation(-nRenderOffset);
|
||
}
|
||
}
|
||
|
||
void ScrollableBox::PlayRenderOffsetYAnimation(int nRenderY)
|
||
{
|
||
m_renderOffsetYAnimation.SetStartValue(nRenderY);
|
||
m_renderOffsetYAnimation.SetEndValue(0);
|
||
m_renderOffsetYAnimation.SetSpeedUpRatio(0.3);
|
||
m_renderOffsetYAnimation.SetSpeedUpfactorA(0.003);
|
||
m_renderOffsetYAnimation.SetSpeedDownRatio(0.7);
|
||
m_renderOffsetYAnimation.SetTotalMillSeconds(DUI_NOSET_VALUE);
|
||
m_renderOffsetYAnimation.SetMaxTotalMillSeconds(650);
|
||
std::function<void(int)> playCallback = nbase::Bind(&ScrollableBox::SetRenderOffsetY, this, std::placeholders::_1);
|
||
m_renderOffsetYAnimation.SetCallback(playCallback);
|
||
m_renderOffsetYAnimation.Start();
|
||
}
|
||
|
||
bool ScrollableBox::IsAtEnd() const
|
||
{
|
||
return GetScrollRange().cy <= GetScrollPos().cy;
|
||
}
|
||
|
||
bool ScrollableBox::IsHoldEnd() const
|
||
{
|
||
return m_bHoldEnd;
|
||
}
|
||
|
||
void ScrollableBox::SetHoldEnd(bool bHoldEnd)
|
||
{
|
||
m_bHoldEnd = bHoldEnd;
|
||
}
|
||
|
||
int ScrollableBox::GetVerScrollUnitPixels() const
|
||
{
|
||
return m_nVerScrollUnitPixels;
|
||
}
|
||
|
||
void ScrollableBox::SetVerScrollUnitPixels(int nUnitPixels)
|
||
{
|
||
DpiManager::GetInstance()->ScaleInt(nUnitPixels);
|
||
m_nVerScrollUnitPixels = nUnitPixels;
|
||
}
|
||
|
||
int ScrollableBox::GetHorScrollUnitPixels() const
|
||
{
|
||
return m_nHerScrollUnitPixels;
|
||
}
|
||
|
||
void ScrollableBox::SetHorScrollUnitPixels(int nUnitPixels)
|
||
{
|
||
DpiManager::GetInstance()->ScaleInt(nUnitPixels);
|
||
m_nHerScrollUnitPixels = nUnitPixels;
|
||
}
|
||
|
||
bool ScrollableBox::GetScrollBarFloat() const
|
||
{
|
||
return m_bScrollBarFloat;
|
||
}
|
||
|
||
void ScrollableBox::SetScrollBarFloat(bool bScrollBarFloat)
|
||
{
|
||
m_bScrollBarFloat = bScrollBarFloat;
|
||
}
|
||
|
||
ui::UiRect ScrollableBox::GetScrollBarPadding() const
|
||
{
|
||
return m_rcScrollBarPadding;
|
||
}
|
||
|
||
void ScrollableBox::SetScrollBarPadding(UiRect rcScrollBarPadding)
|
||
{
|
||
DpiManager::GetInstance()->ScaleRect(rcScrollBarPadding);
|
||
m_rcScrollBarPadding = rcScrollBarPadding;
|
||
}
|
||
|
||
bool ScrollableBox::GetDefaultDisplayScrollbar() const
|
||
{
|
||
return m_bDefaultDisplayScrollbar;
|
||
}
|
||
|
||
void ScrollableBox::SetDefaultDisplayScrollbar(bool bDefaultDisplay)
|
||
{
|
||
m_bDefaultDisplayScrollbar = bDefaultDisplay;
|
||
}
|
||
|
||
void ScrollableBox::ClearImageCache()
|
||
{
|
||
__super::ClearImageCache();
|
||
|
||
if (m_pHorizontalScrollBar)
|
||
m_pHorizontalScrollBar->ClearImageCache();
|
||
if (m_pVerticalScrollBar)
|
||
m_pVerticalScrollBar->ClearImageCache();
|
||
}
|
||
|
||
} // namespace ui
|