void CVerticalLayoutUI::SetPos(RECT rc) { m_rcItem = rc; // Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; if( m_hwndScroll != NULL ) rc.right -= m_pManager->GetSystemMetrics().cxvscroll; // Determine the minimum size SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; int nAdjustables = 0; int cyFixed = 0; for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]); if( !pControl->IsVisible() ) continue; SIZE sz = pControl->EstimateSize(szAvailable); if( sz.cy == 0 ) nAdjustables++; cyFixed += sz.cy + m_iPadding; } // 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 - m_iScrollPos; int iAdjustable = 0; for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]); if( !pControl->IsVisible() ) continue; 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, szAvailable.cy - (cyExpand * nAdjustables) - cyFixed); } RECT rcCtrl = { rc.left, iPosY, rc.right, iPosY + sz.cy }; pControl->SetPos(rcCtrl); iPosY += sz.cy + m_iPadding; cyNeeded += sz.cy + m_iPadding; szRemaining.cy -= sz.cy + m_iPadding; } // Handle overflow with scrollbars ProcessScrollbar(rc, cyNeeded); }
void CHorizontalLayoutUI::SetPos(RECT rc) { m_rcItem = rc; // Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; // Determine the width of elements that are sizeable SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; int nAdjustables = 0; int cxFixed = 0; for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]); if( !pControl->IsVisible() ) continue; SIZE sz = pControl->EstimateSize(szAvailable); if( sz.cx == 0 ) nAdjustables++; cxFixed += sz.cx + m_iPadding; } int cxExpand = 0; if( nAdjustables > 0 ) cxExpand = MAX(0, (szAvailable.cx - cxFixed) / nAdjustables); // Position the elements SIZE szRemaining = szAvailable; int iPosX = rc.left; int iAdjustable = 0; for( int it2 = 0; it2 < m_items.GetSize(); it2++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it2]); if( !pControl->IsVisible() ) continue; SIZE sz = pControl->EstimateSize(szRemaining); if( sz.cx == 0 ) { iAdjustable++; sz.cx = cxExpand; if( iAdjustable == nAdjustables ) sz.cx += MAX(0, szAvailable.cx - (cxExpand * nAdjustables) - cxFixed); } RECT rcCtrl = { iPosX, rc.top, iPosX + sz.cx, rc.bottom }; pControl->SetPos(rcCtrl); iPosX += sz.cx + m_iPadding; szRemaining.cx -= sz.cx + m_iPadding; } }
void CTabLayoutUI::SetPos(RECT rc) { CControlUI::SetPos(rc); rc = m_rcItem; // Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; for (int it = 0; it < m_items.GetSize(); it++) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it]); if (!pControl->IsVisible()) continue; if (pControl->IsFloat()) { SetFloatPos(it); continue; } if (it != m_nCurSel) continue; RECT rcPadding = pControl->GetPadding(); rc.left += rcPadding.left; rc.top += rcPadding.top; rc.right -= rcPadding.right; rc.bottom -= rcPadding.bottom; SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; SIZE sz = pControl->EstimateSize(szAvailable); if (sz.cx == 0) { sz.cx = MAX(0, szAvailable.cx); } if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); if (sz.cy == 0) { sz.cy = MAX(0, szAvailable.cy); } if (sz.cy < pControl->GetMinHeight()) sz.cy = pControl->GetMinHeight(); if (sz.cy > pControl->GetMaxHeight()) sz.cy = pControl->GetMaxHeight(); RECT rcCtrl = { rc.left, rc.top, rc.left + sz.cx, rc.top + sz.cy}; pControl->SetPos(rcCtrl); } }
SIZE CMenuUI::EstimateSize(SIZE szAvailable) { int cxFixed = 0; int cyFixed = 0; for( int it = 0; it < GetCount(); it++ ) { CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it)); if( !pControl->IsVisible() ) continue; SIZE sz = pControl->EstimateSize(szAvailable); cyFixed += sz.cy; if( cxFixed < sz.cx ) cxFixed = sz.cx; } return CDuiSize(cxFixed, cyFixed); }
SIZE CMenuElementUI::EstimateSize(SIZE szAvailable) { SIZE cXY = {0}; for( int it = 0; it < GetCount(); it++ ) { CControlUI* pControl = static_cast<CControlUI*>(GetItemAt(it)); if( !pControl->IsVisible() ) continue; SIZE sz = pControl->EstimateSize(szAvailable); cXY.cy += sz.cy; if( cXY.cx < sz.cx ) cXY.cx = sz.cx; } if(cXY.cy == 0) { TListInfoUI* pInfo = m_pOwner->GetListInfo(); DWORD iTextColor = pInfo->dwTextColor; if( (m_uButtonState & UISTATE_HOT) != 0 ) { iTextColor = pInfo->dwHotTextColor; } if( IsSelected() ) { iTextColor = pInfo->dwSelectedTextColor; } if( !IsEnabled() ) { iTextColor = pInfo->dwDisabledTextColor; } CDuiString sText = GetText(); RECT rcText = { 0, 0, MAX(szAvailable.cx, m_cxyFixed.cx), 9999 }; rcText.left += pInfo->rcTextPadding.left; rcText.right -= pInfo->rcTextPadding.right; if( pInfo->bShowHtml ) { int nLinks = 0; CRenderEngine::DrawHtmlText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, NULL, NULL, nLinks, DT_CALCRECT | pInfo->uTextStyle); } else { CRenderEngine::DrawText(m_pManager->GetPaintDC(), m_pManager, rcText, sText, iTextColor, pInfo->nFont, DT_CALCRECT | pInfo->uTextStyle); } cXY.cx = rcText.right - rcText.left + pInfo->rcTextPadding.left + pInfo->rcTextPadding.right + 20; cXY.cy = rcText.bottom - rcText.top + pInfo->rcTextPadding.top + pInfo->rcTextPadding.bottom; } if( m_cxyFixed.cy != 0 ) cXY.cy = m_cxyFixed.cy; if ( cXY.cx < m_cxyFixed.cx ) cXY.cx = m_cxyFixed.cx; m_cxyFixed.cy = cXY.cy; m_cxyFixed.cx = cXY.cx; return cXY; }
void CMenuWnd::ResizeMenu() { CControlUI* pRoot = m_pm.GetRoot(); #if defined(WIN32) && !defined(UNDER_CE) MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof(oMonitor); ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; #else CDuiRect rcWork; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork); #endif SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top }; szAvailable = pRoot->EstimateSize(szAvailable); m_pm.SetInitSize(szAvailable.cx, szAvailable.cy); //必须是Menu标签作为xml的根节点 CMenuUI *pMenuRoot = static_cast<CMenuUI*>(pRoot); ASSERT(pMenuRoot); SIZE szInit = m_pm.GetInitSize(); CDuiRect rc; CDuiPoint point = m_BasedPoint; rc.left = point.x; rc.top = point.y; rc.right = rc.left + szInit.cx; rc.bottom = rc.top + szInit.cy; int nWidth = rc.GetWidth(); int nHeight = rc.GetHeight(); if (m_dwAlignment & eMenuAlignment_Right) { rc.right = point.x; rc.left = rc.right - nWidth; } if (m_dwAlignment & eMenuAlignment_Bottom) { rc.bottom = point.y; rc.top = rc.bottom - nHeight; } SetForegroundWindow(m_hWnd); MoveWindow(m_hWnd, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), FALSE); SetWindowPos(m_hWnd, HWND_TOPMOST, rc.left, rc.top, rc.GetWidth(), rc.GetHeight() + pMenuRoot->GetInset().bottom + pMenuRoot->GetInset().top, SWP_SHOWWINDOW); }
void CHorizontalLayoutUI::SetPos(RECT rc, bool bNeedInvalidate) { CControlUI::SetPos(rc, bNeedInvalidate); rc = m_rcItem; // Adjust for inset rc.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 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 cyNeeded = 0; int nAdjustables = 0; int cxFixed = 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.cy -= rcPadding.top + rcPadding.bottom; 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.cx == 0 ) { nAdjustables++; } else { if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth(); if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth(); } cxFixed += sz.cx + pControl->GetPadding().left + pControl->GetPadding().right; sz.cy = MAX(sz.cy, 0); if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); if( sz.cy > pControl->GetMaxHeight() ) sz.cy = pControl->GetMaxHeight(); cyNeeded = MAX(cyNeeded, sz.cy + rcPadding.top + rcPadding.bottom); nEstimateNum++; } cxFixed += (nEstimateNum - 1) * m_iChildPadding; // Place elements int cxNeeded = 0; int cxExpand = 0; if( nAdjustables > 0 ) cxExpand = MAX(0, (szAvailable.cx - cxFixed) / nAdjustables); // Position the elements SIZE szRemaining = szAvailable; int iPosX = rc.left; if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) { iPosX -= m_pHorizontalScrollBar->GetScrollPos(); } int iAdjustable = 0; int cxFixedRemaining = cxFixed; 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.cx -= rcPadding.left; szControlAvailable = szRemaining; szControlAvailable.cy -= rcPadding.top + rcPadding.bottom; 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.cx == 0 ) { iAdjustable++; sz.cx = cxExpand; // Distribute remaining to last element (usually round-off left-overs) if( iAdjustable == nAdjustables ) { sz.cx = MAX(0, szRemaining.cx - rcPadding.right - cxFixedRemaining); } if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth(); if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth(); } else { if( sz.cx < pControl->GetMinWidth() ) sz.cx = pControl->GetMinWidth(); if( sz.cx > pControl->GetMaxWidth() ) sz.cx = pControl->GetMaxWidth(); cxFixedRemaining -= sz.cx; } sz.cy = pControl->GetMaxHeight(); if( sz.cy == 0 ) sz.cy = szAvailable.cy - rcPadding.top - rcPadding.bottom; if( sz.cy < 0 ) sz.cy = 0; if( sz.cy > szControlAvailable.cy ) sz.cy = szControlAvailable.cy; if( sz.cy < pControl->GetMinHeight() ) sz.cy = pControl->GetMinHeight(); UINT iChildAlign = GetChildVAlign(); if (iChildAlign == DT_VCENTER) { int iPosY = (rc.bottom + rc.top) / 2; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { iPosY += m_pVerticalScrollBar->GetScrollRange() / 2; iPosY -= m_pVerticalScrollBar->GetScrollPos(); } RECT rcCtrl = { iPosX + rcPadding.left, iPosY - sz.cy/2, iPosX + sz.cx + rcPadding.left, iPosY + sz.cy - sz.cy/2 }; pControl->SetPos(rcCtrl, false); } else if (iChildAlign == DT_BOTTOM) { int iPosY = rc.bottom; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { iPosY += m_pVerticalScrollBar->GetScrollRange(); iPosY -= m_pVerticalScrollBar->GetScrollPos(); } RECT rcCtrl = { iPosX + rcPadding.left, iPosY - rcPadding.bottom - sz.cy, iPosX + sz.cx + rcPadding.left, iPosY - rcPadding.bottom }; pControl->SetPos(rcCtrl, false); } else { int iPosY = rc.top; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { iPosY -= m_pVerticalScrollBar->GetScrollPos(); } RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + sz.cx + rcPadding.left, iPosY + sz.cy + rcPadding.top }; pControl->SetPos(rcCtrl, false); } iPosX += sz.cx + m_iChildPadding + rcPadding.left + rcPadding.right; cxNeeded += sz.cx + rcPadding.left + rcPadding.right; szRemaining.cx -= sz.cx + m_iChildPadding + rcPadding.right; } cxNeeded += (nEstimateNum - 1) * m_iChildPadding; // Process the scrollbar ProcessScrollBar(rc, cxNeeded, cyNeeded); }
void CTileLayoutUI::SetPos(RECT rc) { CControlUI::SetPos(rc); rc = m_rcItem; // Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; if( m_items.GetSize() == 0) { ProcessScrollBar(rc, 0, 0); return; } if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) rc.right -= m_pVerticalScrollBar->GetFixedWidth(); if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); // Position the elements if( m_szItem.cx > 0 ) m_nColumns = (rc.right - rc.left) / m_szItem.cx; if( m_nColumns == 0 ) m_nColumns = 1; int cyNeeded = 0; int cxWidth = (rc.right - rc.left) / m_nColumns; if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) cxWidth = (rc.right - rc.left + m_pHorizontalScrollBar->GetScrollRange() ) / m_nColumns; ; int cyHeight = 0; int iCount = 0; POINT ptTile = { rc.left, rc.top }; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) { ptTile.y -= m_pVerticalScrollBar->GetScrollPos(); } int iPosX = rc.left; if( m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible() ) { iPosX -= m_pHorizontalScrollBar->GetScrollPos(); ptTile.x = iPosX; } for( int it1 = 0; it1 < m_items.GetSize(); it1++ ) { CControlUI* pControl = static_cast<CControlUI*>(m_items[it1]); if( !pControl->IsVisible() ) continue; if( pControl->IsFloat() ) { SetFloatPos(it1); continue; } // Determine size RECT rcTile = { ptTile.x, ptTile.y, ptTile.x + cxWidth, ptTile.y }; if( (iCount % m_nColumns) == 0 ) { int iIndex = iCount; for( int it2 = it1; it2 < m_items.GetSize(); it2++ ) { CControlUI* pLineControl = static_cast<CControlUI*>(m_items[it2]); if( !pLineControl->IsVisible() ) continue; if( pLineControl->IsFloat() ) continue; RECT rcPadding = pLineControl->GetPadding(); SIZE szAvailable = { rcTile.right - rcTile.left - rcPadding.left - rcPadding.right, 9999 }; if( iIndex == iCount || (iIndex + 1) % m_nColumns == 0 ) { szAvailable.cx -= m_iChildPadding / 2; } else { szAvailable.cx -= m_iChildPadding; } if( szAvailable.cx < pControl->GetMinWidth() ) szAvailable.cx = pControl->GetMinWidth(); if( szAvailable.cx > pControl->GetMaxWidth() ) szAvailable.cx = pControl->GetMaxWidth(); SIZE szTile = pLineControl->EstimateSize(szAvailable); if( szTile.cx < pControl->GetMinWidth() ) szTile.cx = pControl->GetMinWidth(); if( szTile.cx > pControl->GetMaxWidth() ) szTile.cx = pControl->GetMaxWidth(); if( szTile.cy < pControl->GetMinHeight() ) szTile.cy = pControl->GetMinHeight(); if( szTile.cy > pControl->GetMaxHeight() ) szTile.cy = pControl->GetMaxHeight(); cyHeight = MAX(cyHeight, szTile.cy + rcPadding.top + rcPadding.bottom); if( (++iIndex % m_nColumns) == 0) break; } } RECT rcPadding = pControl->GetPadding(); rcTile.left += rcPadding.left + m_iChildPadding / 2; rcTile.right -= rcPadding.right + m_iChildPadding / 2; if( (iCount % m_nColumns) == 0 ) { rcTile.left -= m_iChildPadding / 2; } if( ( (iCount + 1) % m_nColumns) == 0 ) { rcTile.right += m_iChildPadding / 2; } // Set position rcTile.top = ptTile.y + rcPadding.top; rcTile.bottom = ptTile.y + cyHeight; SIZE szAvailable = { rcTile.right - rcTile.left, rcTile.bottom - rcTile.top }; SIZE szTile = pControl->EstimateSize(szAvailable); if( szTile.cx == 0 ) szTile.cx = szAvailable.cx; if( szTile.cy == 0 ) szTile.cy = szAvailable.cy; if( szTile.cx < pControl->GetMinWidth() ) szTile.cx = pControl->GetMinWidth(); if( szTile.cx > pControl->GetMaxWidth() ) szTile.cx = pControl->GetMaxWidth(); if( szTile.cy < pControl->GetMinHeight() ) szTile.cy = pControl->GetMinHeight(); if( szTile.cy > pControl->GetMaxHeight() ) szTile.cy = pControl->GetMaxHeight(); RECT rcPos = {(rcTile.left + rcTile.right - szTile.cx) / 2, (rcTile.top + rcTile.bottom - szTile.cy) / 2, (rcTile.left + rcTile.right - szTile.cx) / 2 + szTile.cx, (rcTile.top + rcTile.bottom - szTile.cy) / 2 + szTile.cy}; pControl->SetPos(rcPos); if( (++iCount % m_nColumns) == 0 ) { ptTile.x = iPosX; ptTile.y += cyHeight + m_iChildPadding; cyHeight = 0; } else { ptTile.x += cxWidth; } cyNeeded = rcTile.bottom - rc.top; if( m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible() ) cyNeeded += m_pVerticalScrollBar->GetScrollPos(); } // Process the scrollbar ProcessScrollBar(rc, 0, cyNeeded); }
void CHorizontalLayoutUI::SetPos(RECT rc) { CControlUI::SetPos(rc); rc = m_rcItem; // Adjust for inset rc.left += m_rcInset.left; rc.top += m_rcInset.top; rc.right -= m_rcInset.right; rc.bottom -= m_rcInset.bottom; if (m_items.GetSize() == 0) { ProcessScrollBar(rc, 0, 0); return; } if (m_pVerticalScrollBar && m_pVerticalScrollBar->IsVisible()) rc.right -= m_pVerticalScrollBar->GetFixedWidth(); if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) rc.bottom -= m_pHorizontalScrollBar->GetFixedHeight(); // Determine the width of elements that are sizeable SIZE szAvailable = { rc.right - rc.left, rc.bottom - rc.top }; if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) szAvailable.cx += m_pHorizontalScrollBar->GetScrollRange(); int nAdjustables = 0; int cxFixed = 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.cx == 0) { nAdjustables++; } else { if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); } cxFixed += sz.cx + pControl->GetPadding().left + pControl->GetPadding().right; nEstimateNum++; } cxFixed += (nEstimateNum - 1) * m_iChildPadding; int cxExpand = 0; int cxNeeded = 0; if (nAdjustables > 0) cxExpand = MAX(0, (szAvailable.cx - cxFixed) / nAdjustables); // Position the elements SIZE szRemaining = szAvailable; int iPosX = rc.left; if (m_pHorizontalScrollBar && m_pHorizontalScrollBar->IsVisible()) { iPosX -= m_pHorizontalScrollBar->GetScrollPos(); } int iAdjustable = 0; int cxFixedRemaining = cxFixed; 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.cx -= rcPadding.left; SIZE sz = pControl->EstimateSize(szRemaining); if (sz.cx == 0) { iAdjustable++; sz.cx = cxExpand; // Distribute remaining to last element (usually round-off left-overs) if (iAdjustable == nAdjustables) { sz.cx = MAX(0, szRemaining.cx - rcPadding.right - cxFixedRemaining); } if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); } else { if (sz.cx < pControl->GetMinWidth()) sz.cx = pControl->GetMinWidth(); if (sz.cx > pControl->GetMaxWidth()) sz.cx = pControl->GetMaxWidth(); cxFixedRemaining -= sz.cx; } sz.cy = pControl->GetFixedHeight(); if (sz.cy == 0) sz.cy = rc.bottom - rc.top - rcPadding.top - rcPadding.bottom; if (sz.cy < 0) sz.cy = 0; if (sz.cy < pControl->GetMinHeight()) sz.cy = pControl->GetMinHeight(); if (sz.cy > pControl->GetMaxHeight()) sz.cy = pControl->GetMaxHeight(); RECT rcCtrl = { iPosX + rcPadding.left, rc.top + rcPadding.top, iPosX + sz.cx + rcPadding.left + rcPadding.right, rc.top + rcPadding.top + sz.cy}; pControl->SetPos(rcCtrl); iPosX += sz.cx + m_iChildPadding + rcPadding.left + rcPadding.right; cxNeeded += sz.cx + rcPadding.left + rcPadding.right; szRemaining.cx -= sz.cx + m_iChildPadding + rcPadding.right; } cxNeeded += (nEstimateNum - 1) * m_iChildPadding; // Process the scrollbar ProcessScrollBar(rc, cxNeeded, 0); }
void CVerticalLayoutUI::SetPos(RECT rc) { CControlUI::SetPos(rc); rc = m_rcItem; // Adjust for inset rc.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 size SIZE 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 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(); } 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 ) { ////////////////////////////////////////////////////////////////////////// ///corrected by gechunping on 2014_3_27 ///deleted origin /// sz.cy = MAX(0, szRemaining.cy - rcPadding.bottom - cyFixedRemaining); ///corrected by gechunping on 2014_3_27 ////////////////////////////////////////////////////////////////////////// } 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 + rcPadding.top + rcPadding.bottom; } cyFixedRemaining -= m_iChildPadding; 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(); ////////////////////////////////////////////////////////////////////////// ///corrected by gechunping on 2014_3_27 ///origin/// RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top + rcPadding.bottom }; //err RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.bottom }; RECT rcCtrl = { iPosX + rcPadding.left, iPosY + rcPadding.top, iPosX + rcPadding.left + sz.cx, iPosY + sz.cy + rcPadding.top }; ///corrected by gechunping on 2014_3_27 ////////////////////////////////////////////////////////////////////////// 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 scrollbar ProcessScrollBar(rc, 0, cyNeeded); }
void CVerticalLayoutUI::SetPos(const CDuiRect& rc) { CControlUI::SetPos(rc); if( m_items.IsEmpty() ) return; CDuiRect rct = m_rcItem; rct.left += m_rcInset.left; rct.top += m_rcInset.top; rct.right -= m_rcInset.right; rct.bottom -= m_rcInset.bottom; // Determine the width of elements that are sizeable SIZE szAvailable = {rct.GetWidth(), rct.GetHeight()}; 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; 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; nEstimateNum++; } // 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 = rct.top; int iPosX = rct.left; 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; 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 - 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; 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, iPosY, iPosX + sz.cx, iPosY + sz.cy}; pControl->SetPos(rcCtrl); iPosY += sz.cy; cyNeeded += sz.cy ; szRemaining.cy -= sz.cy; } SIZE sztmp = {m_rcItem.GetWidth(), cyNeeded}; sztmp.cy += m_rcInset.top + m_rcInset.bottom; SetPostSize(sztmp); }
LRESULT CMenuWnd::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { if( uMsg == WM_CREATE ) { if( m_pOwner != NULL) { LONG styleValue = ::GetWindowLong(*this, GWL_STYLE); styleValue &= ~WS_CAPTION; ::SetWindowLong(*this, GWL_STYLE, styleValue | WS_CLIPSIBLINGS | WS_CLIPCHILDREN); RECT rcClient; ::GetClientRect(*this, &rcClient); ::SetWindowPos(*this, NULL, rcClient.left, rcClient.top, rcClient.right - rcClient.left, \ rcClient.bottom - rcClient.top, SWP_FRAMECHANGED); m_pm.Init(m_hWnd); // The trick is to add the items to the new container. Their owner gets // reassigned by this operation - which is why it is important to reassign // the items back to the righfull owner/manager when the window closes. m_pLayout = new CMenuUI(); m_pm.UseParentResource(m_pOwner->GetManager()); m_pLayout->SetManager(&m_pm, NULL, true); LPCTSTR pDefaultAttributes = m_pOwner->GetManager()->GetDefaultAttributeList(kMenuUIInterfaceName); if( pDefaultAttributes ) { m_pLayout->ApplyAttributeList(pDefaultAttributes); } m_pLayout->SetBkColor(0xFFFFFFFF); m_pLayout->SetBorderColor(0xFF85E4FF); m_pLayout->SetBorderSize(0); m_pLayout->SetAutoDestroy(false); m_pLayout->EnableScrollBar(); for( int i = 0; i < m_pOwner->GetCount(); i++ ) { if(m_pOwner->GetItemAt(i)->GetInterface(kMenuElementUIInterfaceName) != NULL ){ (static_cast<CMenuElementUI*>(m_pOwner->GetItemAt(i)))->SetOwner(m_pLayout); m_pLayout->Add(static_cast<CControlUI*>(m_pOwner->GetItemAt(i))); } } m_pm.AttachDialog(m_pLayout); // Position the popup window in absolute space RECT rcOwner = m_pOwner->GetPos(); RECT rc = rcOwner; int cxFixed = 0; int cyFixed = 0; #if defined(WIN32) && !defined(UNDER_CE) MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof(oMonitor); ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; #else CDuiRect rcWork; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork); #endif SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top }; for( int it = 0; it < m_pOwner->GetCount(); it++ ) { if(m_pOwner->GetItemAt(it)->GetInterface(kMenuElementUIInterfaceName) != NULL ){ CControlUI* pControl = static_cast<CControlUI*>(m_pOwner->GetItemAt(it)); SIZE sz = pControl->EstimateSize(szAvailable); cyFixed += sz.cy; if( cxFixed < sz.cx ) cxFixed = sz.cx; } } cyFixed += 4; cxFixed += 4; RECT rcWindow; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWindow); rc.top = rcOwner.top; rc.bottom = rc.top + cyFixed; ::MapWindowRect(m_pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc); rc.left = rcWindow.right; rc.right = rc.left + cxFixed; rc.right += 2; bool bReachBottom = false; bool bReachRight = false; LONG chRightAlgin = 0; LONG chBottomAlgin = 0; RECT rcPreWindow = {0}; ContextMenuObserver::Iterator<BOOL, ContextMenuParam> iterator(s_context_menu_observer); ReceiverImplBase<BOOL, ContextMenuParam>* pReceiver = iterator.next(); while( pReceiver != NULL ) { CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver); if( pContextMenu != NULL ) { GetWindowRect(pContextMenu->GetHWND(), &rcPreWindow); bReachRight = rcPreWindow.left >= rcWindow.right; bReachBottom = rcPreWindow.top >= rcWindow.bottom; if( pContextMenu->GetHWND() == m_pOwner->GetManager()->GetPaintWindow() || bReachBottom || bReachRight ) break; } pReceiver = iterator.next(); } if (bReachBottom) { rc.bottom = rcWindow.top; rc.top = rc.bottom - cyFixed; } if (bReachRight) { rc.right = rcWindow.left; rc.left = rc.right - cxFixed; } if( rc.bottom > rcWork.bottom ) { rc.bottom = rc.top; rc.top = rc.bottom - cyFixed; } if (rc.right > rcWork.right) { rc.right = rcWindow.left; rc.left = rc.right - cxFixed; rc.top = rcWindow.bottom; rc.bottom = rc.top + cyFixed; } if( rc.top < rcWork.top ) { rc.top = rcOwner.top; rc.bottom = rc.top + cyFixed; } if (rc.left < rcWork.left) { rc.left = rcWindow.right; rc.right = rc.left + cxFixed; } MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, FALSE); } else { m_pm.Init(m_hWnd); CDialogBuilder builder; CMenuBuilderCallback menuCallback; CControlUI* pRoot = builder.Create(m_xml, m_sType.GetData(), &menuCallback, &m_pm); m_pm.AttachDialog(pRoot); #if defined(WIN32) && !defined(UNDER_CE) MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof(oMonitor); ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; #else CDuiRect rcWork; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork); #endif SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top }; szAvailable = pRoot->EstimateSize(szAvailable); m_pm.SetInitSize(szAvailable.cx, szAvailable.cy); DWORD dwAlignment = eMenuAlignment_Left | eMenuAlignment_Top; SIZE szInit = m_pm.GetInitSize(); CDuiRect rc; CDuiPoint point = m_BasedPoint; rc.left = point.x; rc.top = point.y; rc.right = rc.left + szInit.cx; rc.bottom = rc.top + szInit.cy; int nWidth = rc.GetWidth(); int nHeight = rc.GetHeight(); if (dwAlignment & eMenuAlignment_Right) { rc.right = point.x; rc.left = rc.right - nWidth; } if (dwAlignment & eMenuAlignment_Bottom) { rc.bottom = point.y; rc.top = rc.bottom - nHeight; } SetForegroundWindow(m_hWnd); MoveWindow(m_hWnd, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), FALSE); SetWindowPos(m_hWnd, HWND_TOPMOST, rc.left, rc.top, rc.GetWidth(), rc.GetHeight(), SWP_SHOWWINDOW); } return 0; } else if( uMsg == WM_CLOSE ) { if( m_pOwner != NULL ) { m_pOwner->SetManager(m_pOwner->GetManager(), m_pOwner->GetParent(), false); m_pOwner->SetPos(m_pOwner->GetPos()); m_pOwner->SetFocus(); } } else if( uMsg == WM_RBUTTONDOWN || uMsg == WM_CONTEXTMENU || uMsg == WM_RBUTTONUP || uMsg == WM_RBUTTONDBLCLK ) { return 0L; } else if( uMsg == WM_KILLFOCUS ) { HWND hFocusWnd = (HWND)wParam; BOOL bInMenuWindowList = FALSE; ContextMenuParam param; param.hWnd = GetHWND(); ContextMenuObserver::Iterator<BOOL, ContextMenuParam> iterator(s_context_menu_observer); ReceiverImplBase<BOOL, ContextMenuParam>* pReceiver = iterator.next(); while( pReceiver != NULL ) { CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver); if( pContextMenu != NULL && pContextMenu->GetHWND() == hFocusWnd ) { bInMenuWindowList = TRUE; break; } pReceiver = iterator.next(); } if( !bInMenuWindowList ) { param.wParam = 1; param.lParam = NULL; s_context_menu_observer.RBroadcast(param); return 0; } } else if( uMsg == WM_KEYDOWN) { if( wParam == VK_ESCAPE) { Close(); } } LRESULT lRes = 0; if( m_pm.MessageHandler(uMsg, wParam, lParam, lRes) ) return lRes; return CWindowWnd::HandleMessage(uMsg, wParam, lParam); }
void CMenuWnd::ResizeSubMenu() { // Position the popup window in absolute space RECT rcOwner = m_pOwner->GetPos(); RECT rc = rcOwner; int cxFixed = 0; int cyFixed = 0; #if defined(WIN32) && !defined(UNDER_CE) MONITORINFO oMonitor = {}; oMonitor.cbSize = sizeof(oMonitor); ::GetMonitorInfo(::MonitorFromWindow(*this, MONITOR_DEFAULTTOPRIMARY), &oMonitor); CDuiRect rcWork = oMonitor.rcWork; #else CDuiRect rcWork; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWork); #endif SIZE szAvailable = { rcWork.right - rcWork.left, rcWork.bottom - rcWork.top }; for( int it = 0; it < m_pOwner->GetCount(); it++ ) { if(m_pOwner->GetItemAt(it)->GetInterface(_T("MenuElement")) != NULL ){ CControlUI* pControl = static_cast<CControlUI*>(m_pOwner->GetItemAt(it)); SIZE sz = pControl->EstimateSize(szAvailable); cyFixed += sz.cy; if( cxFixed < sz.cx ) cxFixed = sz.cx; } } RECT rcWindow; GetWindowRect(m_pOwner->GetManager()->GetPaintWindow(), &rcWindow); rc.top = rcOwner.top; rc.bottom = rc.top + cyFixed; ::MapWindowRect(m_pOwner->GetManager()->GetPaintWindow(), HWND_DESKTOP, &rc); rc.left = rcWindow.right; rc.right = rc.left + cxFixed; rc.right += 2; bool bReachBottom = false; bool bReachRight = false; LONG chRightAlgin = 0; LONG chBottomAlgin = 0; RECT rcPreWindow = {0}; MenuObserverImpl::Iterator iterator(CMenuWnd::GetGlobalContextMenuObserver()); MenuMenuReceiverImplBase* pReceiver = iterator.next(); while( pReceiver != NULL ) { CMenuWnd* pContextMenu = dynamic_cast<CMenuWnd*>(pReceiver); if( pContextMenu != NULL ) { GetWindowRect(pContextMenu->GetHWND(), &rcPreWindow); bReachRight = rcPreWindow.left >= rcWindow.right; bReachBottom = rcPreWindow.top >= rcWindow.bottom; if( pContextMenu->GetHWND() == m_pOwner->GetManager()->GetPaintWindow() || bReachBottom || bReachRight ) break; } pReceiver = iterator.next(); } if (bReachBottom) { rc.bottom = rcWindow.top; rc.top = rc.bottom - cyFixed; } if (bReachRight) { rc.right = rcWindow.left; rc.left = rc.right - cxFixed; } if( rc.bottom > rcWork.bottom ) { rc.bottom = rc.top; rc.top = rc.bottom - cyFixed; } if (rc.right > rcWork.right) { rc.right = rcWindow.left; rc.left = rc.right - cxFixed; } if( rc.top < rcWork.top ) { rc.top = rcOwner.top; rc.bottom = rc.top + cyFixed; } if (rc.left < rcWork.left) { rc.left = rcWindow.right; rc.right = rc.left + cxFixed; } MoveWindow(m_hWnd, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top + m_pLayout->GetInset().top + m_pLayout->GetInset().bottom, FALSE); }