DuiLib 之 UIVerticalLayout

来源:互联网 发布:les交友软件 编辑:程序博客网 时间:2024/06/08 06:03
#ifndef __UIVERTICALLAYOUT_H__#define __UIVERTICALLAYOUT_H__#pragma oncenamespace DuiLib{class UILIB_API CVerticalLayoutUI : public CContainerUI{public:CVerticalLayoutUI();LPCTSTR GetClass() const;LPVOID GetInterface(LPCTSTR pstrName);UINT GetControlFlags() const;void SetSepHeight(int iHeight);int GetSepHeight() const;void SetSepImmMode(bool bImmediately);bool IsSepImmMode() const;void SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue);void DoEvent(TEventUI& event);void SetPos(RECT rc);void DoPostPaint(HDC hDC, const RECT& rcPaint);RECT GetThumbRect(bool bUseNew = false) const;protected:int m_iSepHeight;UINT m_uButtonState;POINT ptLastMouse;RECT m_rcNewPos;bool m_bImmMode;};}#endif // __UIVERTICALLAYOUT_H__



#include "stdafx.h"#include "UIVerticalLayout.h"namespace DuiLib{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( _tcscmp(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){CControlUI::SetPos(rc);rc = m_rcItem;// Adjust for insetrc.left += m_rcInset.left;rc.top += m_rcInset.top;rc.right -= m_rcInset.right;rc.bottom -= m_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;}// Determine the minimum sizeSIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top };if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange();int nAdjustables = 0;int cyFixed = 0;int nEstimateNum = 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;SIZE sz = pControl->EstimateSize(szAvailable);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;nEstimateNum++;}cyFixed += (nEstimateNum - 1) * m_iChildPadding;// Place elementsint cyNeeded = 0;int cyExpand = 0;if( nAdjustables > 0 ) cyExpand = MAX(0, (szAvailable.cy - cyFixed) / nAdjustables);// Position the elementsSIZE szRemaining = szAvailable;int iPosY = rc.top;if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) {iPosY -= m_pVerticalScrollBar->GetScrollPos();}int iPosX = rc.left;if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) {iPosX -= m_pHorizontalScrollBar->GetScrollPos();}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;}RECT rcPadding = pControl->GetPadding();szRemaining.cy -= rcPadding.top;SIZE sz = pControl->EstimateSize(szRemaining);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 = pControl->GetFixedWidth();if( sz.cx == 0 ) sz.cx = szAvailable.cx - rcPadding.left - rcPadding.right;if( sz.cx < 0 ) sz.cx = 0;if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth();if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth();RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top + rcPadding.bottom };pControl->SetPos(rcCtrl);iPosY += sz.cy + m_iChildPadding + rcPadding.top + rcPadding.bottom;cyNeeded += sz.cy + rcPadding.top + rcPadding.bottom;szRemaining.cy -= sz.cy + m_iChildPadding + rcPadding.bottom;}cyNeeded += (nEstimateNum - 1) * m_iChildPadding;// Process the scrollbarProcessScrollBar(rc, 0, 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{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( _tcscmp(pstrName, _T("sepheight")) == 0 ) SetSepHeight(_ttoi(pstrValue));else if( _tcscmp(pstrName, _T("sepimm")) == 0 ) SetSepImmMode(_tcscmp(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 = 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));}}}