summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2012-08-31 09:16:39 +0100
committerCaolán McNamara <caolanm@redhat.com>2012-09-28 08:48:43 +0100
commitfd7849d58de6c36eb7edd9d13b3f7c7da05fe235 (patch)
treef205d3562249a495fbc0f55365533c08098c82bb /vcl
parent41d2ae98758da4be882e009d3b5c3868e6f91ee0 (diff)
make spanning of empty row/cols work better
Change-Id: I4ef6cee2ffdfced8d98dc48cf21a142bb15fd4a3
Diffstat (limited to 'vcl')
-rw-r--r--vcl/inc/vcl/layout.hxx24
-rw-r--r--vcl/source/window/layout.cxx67
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);