123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- #include "StdAfx.h"
- #include "UIVerticalLayout.h"
- namespace DuiLib
- {
- IMPLEMENT_DUICONTROL(CVerticalLayoutUI)
- CVerticalLayoutUI::CVerticalLayoutUI() : m_iSepHeight(0), m_uButtonState(0), m_bImmMode(false)
- {
- ptLastMouse.x = ptLastMouse.y = 0;
- ::ZeroMemory(&m_rcNewPos, sizeof(m_rcNewPos));
- }
- LPCTSTR CVerticalLayoutUI::GetClass() const
- {
- return _T("VerticalLayoutUI");
- }
- LPVOID CVerticalLayoutUI::GetInterface(LPCTSTR pstrName)
- {
- if( _tcsicmp(pstrName, DUI_CTR_VERTICALLAYOUT) == 0 ) return static_cast<CVerticalLayoutUI*>(this);
- return CContainerUI::GetInterface(pstrName);
- }
- UINT CVerticalLayoutUI::GetControlFlags() const
- {
- if( IsEnabled() && m_iSepHeight != 0 ) return UIFLAG_SETCURSOR;
- else return 0;
- }
- void CVerticalLayoutUI::SetPos(RECT rc, bool bNeedInvalidate)
- {
- CControlUI::SetPos(rc, bNeedInvalidate);
- rc = m_rcItem;
- // Adjust for inset
- RECT rcInset = GetInset();
- rc.left += rcInset.left;
- rc.top += rcInset.top;
- rc.right -= rcInset.right;
- rc.bottom -= rcInset.bottom;
- if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth();
- if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight();
- if( m_items.GetSize() == 0) {
- ProcessScrollBar(rc, 0, 0);
- return;
- }
- int iChildPadding = GetChildPadding();
- // Determine the minimum size
- SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };
- if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() )
- szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange();
- if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() )
- szAvailable.cy += m_pVerticalScrollBar->GetScrollRange();
- int cxNeeded = 0;
- int nAdjustables = 0;
- int cyFixed = 0;
- int nEstimateNum = 0;
- SIZE szControlAvailable;
- int iControlMaxWidth = 0;
- int iControlMaxHeight = 0;
- for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) {
- CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]);
- if( !pControl->IsVisible() ) continue;
- if( pControl->IsFloat() ) continue;
- szControlAvailable = szAvailable;
- RECT rcPadding = pControl->GetPadding();
- szControlAvailable.cx -= rcPadding.left + rcPadding.right;
- iControlMaxWidth = pControl->GetFixedWidth();
- iControlMaxHeight = pControl->GetFixedHeight();
- if (iControlMaxWidth <= 0) iControlMaxWidth = pControl->GetMaxWidth();
- if (iControlMaxHeight <= 0) iControlMaxHeight = pControl->GetMaxHeight();
- if (szControlAvailable.cx > iControlMaxWidth) szControlAvailable.cx = iControlMaxWidth;
- if (szControlAvailable.cy > iControlMaxHeight) szControlAvailable.cy = iControlMaxHeight;
- SIZE sz = pControl->EstimateSize(szControlAvailable);
- if( sz.cy == 0 ) {
- nAdjustables++;
- }
- else {
- if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
- if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
- }
- cyFixed += sz.cy + pControl->GetPadding().top + pControl->GetPadding().bottom;
- sz.cx = MAX(sz.cx, 0);
- if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
- if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();
- cxNeeded = MAX(cxNeeded, sz.cx + rcPadding.left + rcPadding.right);
- nEstimateNum++;
- }
- cyFixed += (nEstimateNum - 1) * iChildPadding;
- // Place elements
- int cyNeeded = 0;
- int cyExpand = 0;
- if( nAdjustables > 0 ) cyExpand = MAX(0, (szAvailable.cy - cyFixed) / nAdjustables);
- // Position the elements
- SIZE szRemaining = szAvailable;
- int iPosY = rc.top;
- if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {
- iPosY -= m_pVerticalScrollBar->GetScrollPos();
- }
- else {
- // ×ӿؼþ´¹Ö±¶ÔÆ䷽ʽ
- if(nAdjustables <= 0) {
- UINT iChildAlign = GetChildVAlign();
- if (iChildAlign == DT_VCENTER) {
- iPosY += (szAvailable.cy -cyFixed) / 2;
- }
- else if (iChildAlign == DT_BOTTOM) {
- iPosY += (szAvailable.cy - cyFixed);
- }
- }
- }
- int iEstimate = 0;
- int iAdjustable = 0;
- int cyFixedRemaining = cyFixed;
- for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) {
- CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]);
- if( !pControl->IsVisible() ) continue;
- if( pControl->IsFloat() ) {
- SetFloatPos(it2);
- continue;
- }
- iEstimate += 1;
- RECT rcPadding = pControl->GetPadding();
- szRemaining.cy -= rcPadding.top;
- szControlAvailable = szRemaining;
- szControlAvailable.cx -= rcPadding.left + rcPadding.right;
- iControlMaxWidth = pControl->GetFixedWidth();
- iControlMaxHeight = pControl->GetFixedHeight();
- if (iControlMaxWidth <= 0) iControlMaxWidth = pControl->GetMaxWidth();
- if (iControlMaxHeight <= 0) iControlMaxHeight = pControl->GetMaxHeight();
- if (szControlAvailable.cx > iControlMaxWidth) szControlAvailable.cx = iControlMaxWidth;
- if (szControlAvailable.cy > iControlMaxHeight) szControlAvailable.cy = iControlMaxHeight;
- cyFixedRemaining = cyFixedRemaining - (rcPadding.top + rcPadding.bottom);
- if (iEstimate > 1) cyFixedRemaining = cyFixedRemaining - iChildPadding;
- SIZE sz = pControl->EstimateSize(szControlAvailable);
- if( sz.cy == 0 ) {
- iAdjustable++;
- sz.cy = cyExpand;
- // Distribute remaining to last element (usually round-off left-overs)
- if( iAdjustable == nAdjustables ) {
- sz.cy = MAX(0, szRemaining.cy - rcPadding.bottom - cyFixedRemaining);
- }
- if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
- if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
- }
- else {
- if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight();
- if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight();
- cyFixedRemaining -= sz.cy;
- }
- sz.cx = MAX(sz.cx, 0);
- if( sz.cx == 0 ) sz.cx = szAvailable.cx - rcPadding.left - rcPadding.right;
- if( sz.cx > szControlAvailable.cx ) sz.cx = szControlAvailable.cx;
- if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();
- UINT iChildAlign = GetChildAlign();
- if (iChildAlign == DT_CENTER) {
- int iPosX = (rc.right + rc.left) / 2;
- if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
- iPosX += m_pHorizontalScrollBar->GetScrollRange() / 2;
- iPosX -= m_pHorizontalScrollBar->GetScrollPos();
- }
- RECT rcCtrl = { iPosX - sz.cx/2, iPosY + rcPadding.top, iPosX + sz.cx - sz.cx/2, iPosY + sz.cy + rcPadding.top };
- pControl->SetPos(rcCtrl, false);
- }
- else if (iChildAlign == DT_RIGHT) {
- int iPosX = rc.right;
- if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
- iPosX += m_pHorizontalScrollBar->GetScrollRange();
- iPosX -= m_pHorizontalScrollBar->GetScrollPos();
- }
- RECT rcCtrl = { iPosX - rcPadding.right - sz.cx, iPosY + rcPadding.top, iPosX - rcPadding.right, iPosY + sz.cy + rcPadding.top };
- pControl->SetPos(rcCtrl, false);
- }
- else {
- int iPosX = rc.left;
- if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {
- iPosX -= m_pHorizontalScrollBar->GetScrollPos();
- }
- RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top };
- pControl->SetPos(rcCtrl, false);
- }
- iPosY += sz.cy + iChildPadding + rcPadding.top + rcPadding.bottom;
- cyNeeded += sz.cy + rcPadding.top + rcPadding.bottom;
- szRemaining.cy -= sz.cy + iChildPadding + rcPadding.bottom;
- }
- cyNeeded += (nEstimateNum - 1) * iChildPadding;
- // Process the scrollbar
- ProcessScrollBar(rc, cxNeeded, cyNeeded);
- }
- void CVerticalLayoutUI::DoPostPaint(HDC hDC, const RECT& rcPaint)
- {
- if( (m_uButtonState & UISTATE_CAPTURED) != 0 && !m_bImmMode ) {
- RECT rcSeparator = GetThumbRect(true);
- CRenderEngine::DrawColor(hDC, rcSeparator, 0xAA000000);
- }
- }
- void CVerticalLayoutUI::SetSepHeight(int iHeight)
- {
- m_iSepHeight = iHeight;
- }
- int CVerticalLayoutUI::GetSepHeight() const
- {
- if(m_pManager != NULL) m_pManager->GetDPIObj()->Scale(m_iSepHeight);
- return m_iSepHeight;
- }
- void CVerticalLayoutUI::SetSepImmMode(bool bImmediately)
- {
- if( m_bImmMode == bImmediately ) return;
- if( (m_uButtonState & UISTATE_CAPTURED) != 0 && !m_bImmMode && m_pManager != NULL ) {
- m_pManager->RemovePostPaint(this);
- }
- m_bImmMode = bImmediately;
- }
- bool CVerticalLayoutUI::IsSepImmMode() const
- {
- return m_bImmMode;
- }
- void CVerticalLayoutUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
- {
- if( _tcsicmp(pstrName, _T("sepheight")) == 0 ) SetSepHeight(_ttoi(pstrValue));
- else if( _tcsicmp(pstrName, _T("sepimm")) == 0 ) SetSepImmMode(_tcsicmp(pstrValue, _T("true")) == 0);
- else CContainerUI::SetAttribute(pstrName, pstrValue);
- }
- void CVerticalLayoutUI::DoEvent(TEventUI& event)
- {
- if( m_iSepHeight != 0 ) {
- if( event.Type == UIEVENT_BUTTONDOWN && IsEnabled() )
- {
- RECT rcSeparator = GetThumbRect(false);
- if( ::PtInRect(&rcSeparator, event.ptMouse) ) {
- m_uButtonState |= UISTATE_CAPTURED;
- ptLastMouse = event.ptMouse;
- m_rcNewPos = m_rcItem;
- if( !m_bImmMode && m_pManager ) m_pManager->AddPostPaint(this);
- return;
- }
- }
- if( event.Type == UIEVENT_BUTTONUP )
- {
- if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
- m_uButtonState &= ~UISTATE_CAPTURED;
- m_rcItem = m_rcNewPos;
- if( !m_bImmMode && m_pManager ) m_pManager->RemovePostPaint(this);
- NeedParentUpdate();
- return;
- }
- }
- if( event.Type == UIEVENT_MOUSEMOVE )
- {
- if( (m_uButtonState & UISTATE_CAPTURED) != 0 ) {
- LONG cy = event.ptMouse.y - ptLastMouse.y;
- ptLastMouse = event.ptMouse;
- RECT rc = m_rcNewPos;
- if( m_iSepHeight >= 0 ) {
- if( cy > 0 && event.ptMouse.y < m_rcNewPos.bottom + m_iSepHeight ) return;
- if( cy < 0 && event.ptMouse.y > m_rcNewPos.bottom ) return;
- rc.bottom += cy;
- if( rc.bottom - rc.top <= GetMinHeight() ) {
- if( m_rcNewPos.bottom - m_rcNewPos.top <= GetMinHeight() ) return;
- rc.bottom = rc.top + GetMinHeight();
- }
- if( rc.bottom - rc.top >= GetMaxHeight() ) {
- if( m_rcNewPos.bottom - m_rcNewPos.top >= GetMaxHeight() ) return;
- rc.bottom = rc.top + GetMaxHeight();
- }
- }
- else {
- if( cy > 0 && event.ptMouse.y < m_rcNewPos.top ) return;
- if( cy < 0 && event.ptMouse.y > m_rcNewPos.top + m_iSepHeight ) return;
- rc.top += cy;
- if( rc.bottom - rc.top <= GetMinHeight() ) {
- if( m_rcNewPos.bottom - m_rcNewPos.top <= GetMinHeight() ) return;
- rc.top = rc.bottom - GetMinHeight();
- }
- if( rc.bottom - rc.top >= GetMaxHeight() ) {
- if( m_rcNewPos.bottom - m_rcNewPos.top >= GetMaxHeight() ) return;
- rc.top = rc.bottom - GetMaxHeight();
- }
- }
- CDuiRect rcInvalidate = GetThumbRect(true);
- m_rcNewPos = rc;
- m_cxyFixed.cy = GetManager()->GetDPIObj()->Scale(m_rcNewPos.bottom - m_rcNewPos.top);
- if( m_bImmMode ) {
- m_rcItem = m_rcNewPos;
- NeedParentUpdate();
- }
- else {
- rcInvalidate.Join(GetThumbRect(true));
- rcInvalidate.Join(GetThumbRect(false));
- if( m_pManager ) m_pManager->Invalidate(rcInvalidate);
- }
- return;
- }
- }
- if( event.Type == UIEVENT_SETCURSOR )
- {
- RECT rcSeparator = GetThumbRect(false);
- if( IsEnabled() && ::PtInRect(&rcSeparator, event.ptMouse) ) {
- ::SetCursor(::LoadCursor(NULL, MAKEINTRESOURCE(IDC_SIZENS)));
- return;
- }
- }
- }
- CContainerUI::DoEvent(event);
- }
- RECT CVerticalLayoutUI::GetThumbRect(bool bUseNew) const
- {
- if( (m_uButtonState & UISTATE_CAPTURED) != 0 && bUseNew) {
- if( m_iSepHeight >= 0 )
- return CDuiRect(m_rcNewPos.left, MAX(m_rcNewPos.bottom - m_iSepHeight, m_rcNewPos.top),
- m_rcNewPos.right, m_rcNewPos.bottom);
- else
- return CDuiRect(m_rcNewPos.left, m_rcNewPos.top, m_rcNewPos.right,
- MIN(m_rcNewPos.top - m_iSepHeight, m_rcNewPos.bottom));
- }
- else {
- if( m_iSepHeight >= 0 )
- return CDuiRect(m_rcItem.left, MAX(m_rcItem.bottom - m_iSepHeight, m_rcItem.top), m_rcItem.right,
- m_rcItem.bottom);
- else
- return CDuiRect(m_rcItem.left, m_rcItem.top, m_rcItem.right,
- MIN(m_rcItem.top - m_iSepHeight, m_rcItem.bottom));
- }
- }
- }
|