diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-08-31 09:16:39 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-09-28 08:48:43 +0100 |
commit | fd7849d58de6c36eb7edd9d13b3f7c7da05fe235 (patch) | |
tree | f205d3562249a495fbc0f55365533c08098c82bb /vcl | |
parent | 41d2ae98758da4be882e009d3b5c3868e6f91ee0 (diff) |
make spanning of empty row/cols work better
Change-Id: I4ef6cee2ffdfced8d98dc48cf21a142bb15fd4a3
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/vcl/layout.hxx | 24 | ||||
-rw-r--r-- | vcl/source/window/layout.cxx | 67 |
2 files changed, 68 insertions, 23 deletions
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx index db35196c661f..3da9edd96832 100644 --- a/vcl/inc/vcl/layout.hxx +++ b/vcl/inc/vcl/layout.hxx @@ -313,7 +313,29 @@ private: bool m_bColumnHomogeneous; int m_nRowSpacing; int m_nColumnSpacing; - typedef boost::multi_array<Window*, 2> array_type; + + struct GridEntry + { + Window *pChild; + sal_Int32 nSpanWidth; + sal_Int32 nSpanHeight; + GridEntry() + : pChild(0) + , nSpanWidth(0) + , nSpanHeight(0) + { + } + }; + + typedef boost::multi_array<GridEntry, 2> array_type; + + struct ExtendedGridEntry : GridEntry + { + int x; + int y; + }; + + typedef boost::multi_array<ExtendedGridEntry, 2> ext_array_type; array_type assembleGrid() const; bool isNullGrid(const array_type& A) const; diff --git a/vcl/source/window/layout.cxx b/vcl/source/window/layout.cxx index bd278196aac4..db512436d0dd 100644 --- a/vcl/source/window/layout.cxx +++ b/vcl/source/window/layout.cxx @@ -385,7 +385,7 @@ void VclButtonBox::setAllocation(const Size &rAllocation) VclGrid::array_type VclGrid::assembleGrid() const { - array_type A; + ext_array_type A; for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT)) @@ -410,9 +410,23 @@ VclGrid::array_type VclGrid::assembleGrid() const A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]); } - A[nLeftAttach][nTopAttach] = pChild; - } + ExtendedGridEntry &rEntry = A[nLeftAttach][nTopAttach]; + rEntry.pChild = pChild; + rEntry.nSpanWidth = nWidth; + rEntry.nSpanHeight = nHeight; + rEntry.x = nLeftAttach; + rEntry.y = nTopAttach; + for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX) + { + for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY) + { + ExtendedGridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY]; + rSpan.x = nLeftAttach; + rSpan.y = nTopAttach; + } + } + } //see if we have any empty rows/cols sal_Int32 nMaxX = A.shape()[0]; @@ -425,16 +439,12 @@ VclGrid::array_type VclGrid::assembleGrid() const { for (sal_Int32 y = 0; y < nMaxY; ++y) { - const Window *pChild = A[x][y]; - if (pChild) + const GridEntry &rEntry = A[x][y]; + const Window *pChild = rEntry.pChild; + if (pChild && pChild->IsVisible()) { - sal_Int32 nWidth = pChild->get_grid_width(); - for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX) - aNonEmptyCols[x+nSpanX] = true; - - sal_Int32 nHeight = pChild->get_grid_height(); - for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY) - aNonEmptyRows[y+nSpanY] = true; + aNonEmptyCols[x] = true; + aNonEmptyRows[y] = true; } } } @@ -442,9 +452,19 @@ VclGrid::array_type VclGrid::assembleGrid() const sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true); sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true); - //no empty rows or cols - if (nNonEmptyCols == nMaxX && nNonEmptyRows == nMaxY) - return A; + //reduce the spans of elements that span empty rows or columns + for (sal_Int32 x = 0; x < nMaxX; ++x) + { + for (sal_Int32 y = 0; y < nMaxY; ++y) + { + ExtendedGridEntry &rSpan = A[x][y]; + ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y]; + if (!aNonEmptyCols[x]) + --rEntry.nSpanWidth; + if (!aNonEmptyRows[y]) + --rEntry.nSpanHeight; + } + } //make new grid without empty rows and columns array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]); @@ -456,7 +476,8 @@ VclGrid::array_type VclGrid::assembleGrid() const { if (aNonEmptyRows[y] == false) continue; - B[x2][y2++] = A[x][y]; + GridEntry &rEntry = A[x][y]; + B[x2][y2++] = rEntry; } ++x2; } @@ -486,19 +507,20 @@ void VclGrid::calcMaxs(const array_type &A, std::vector<Value> &rWidths, std::ve { for (sal_Int32 y = 0; y < nMaxY; ++y) { - const Window *pChild = A[x][y]; + const GridEntry &rEntry = A[x][y]; + const Window *pChild = rEntry.pChild; if (!pChild) continue; Size aChildSize = getLayoutRequisition(*pChild); - sal_Int32 nWidth = pChild->get_grid_width(); + sal_Int32 nWidth = rEntry.nSpanWidth; for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX) { rWidths[x+nSpanX].m_nValue = std::max(rWidths[x+nSpanX].m_nValue, aChildSize.Width()/nWidth); rWidths[x+nSpanX].m_bExpand = rWidths[x+nSpanX].m_bExpand | pChild->get_hexpand(); } - sal_Int32 nHeight = pChild->get_grid_height(); + sal_Int32 nHeight = rEntry.nSpanHeight; for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY) { rHeights[y+nSpanY].m_nValue = std::max(rHeights[y+nSpanY].m_nValue, aChildSize.Height()/nHeight); @@ -641,17 +663,18 @@ void VclGrid::setAllocation(const Size& rAllocation) { for (sal_Int32 y = 0; y < nMaxY; ++y) { - Window *pChild = A[x][y]; + GridEntry &rEntry = A[x][y]; + Window *pChild = rEntry.pChild; if (pChild) { Size aChildAlloc(0, 0); - sal_Int32 nWidth = pChild->get_grid_width(); + sal_Int32 nWidth = rEntry.nSpanWidth; for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX) aChildAlloc.Width() += aWidths[x+nSpanX].m_nValue; aChildAlloc.Width() += get_column_spacing()*(nWidth-1); - sal_Int32 nHeight = pChild->get_grid_height(); + sal_Int32 nHeight = rEntry.nSpanHeight; for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY) aChildAlloc.Height() += aHeights[y+nSpanY].m_nValue; aChildAlloc.Height() += get_row_spacing()*(nHeight-1); |