[Libreoffice-commits] .: Branch 'feature/layout' - README.layout vcl/inc vcl/source

Ricardo Cruz rpmcruz at kemper.freedesktop.org
Sat Dec 18 08:55:17 PST 2010


 README.layout                   |    7 -
 vcl/inc/vcl/align.hxx           |    4 
 vcl/inc/vcl/table.hxx           |   36 +++--
 vcl/source/control/tabctrl.cxx  |    2 
 vcl/source/layout/align.cxx     |   25 +++
 vcl/source/layout/box.cxx       |    6 
 vcl/source/layout/buttonbox.cxx |    1 
 vcl/source/layout/layout.cxx    |   12 +
 vcl/source/layout/ldialog.cxx   |    3 
 vcl/source/layout/notebook.cxx  |    9 -
 vcl/source/layout/table.cxx     |  251 +++++++++++++++-------------------------
 11 files changed, 168 insertions(+), 188 deletions(-)

New commits:
commit b5345f10e9c0f8d24f3fa42af5ad03ce450be3b4
Author: Ricardo Cruz <rpmcruz at alunos.dcc.fc.up.pt>
Date:   Sat Dec 18 16:54:22 2010 +0000

    Re-implemented Table in a different line. Tweaks here and there.

diff --git a/README.layout b/README.layout
index 9866fc8..ae85721 100644
--- a/README.layout
+++ b/README.layout
@@ -1,11 +1,16 @@
 ~ TODO ~
 
+* Make Window an implementation of a Layout (or Widget?)
+  interface. Notice that Window and Layout use different
+  hierarchies, so we have to keep the GetParent() and
+  GetChild() for the Window hierarchy, and add
+  GetLayoutParent() and GetLayoutChildren().
 * XML parser & factory
 * Property introspection
     * XML parser support for properties
 * UI editor
 * Polishing: more containers? write a strategy
-  plan for porting dialogs, etc
+  guide for porting dialogs, etc
 * Announcement: try to get people to
   do some dialog porting.
 
diff --git a/vcl/inc/vcl/align.hxx b/vcl/inc/vcl/align.hxx
index 6a3c226..b1b0676 100644
--- a/vcl/inc/vcl/align.hxx
+++ b/vcl/inc/vcl/align.hxx
@@ -31,6 +31,9 @@ class VCL_DLLPUBLIC Align : public Layout
 public:
     Align (float xalign, float yalign, float xscale, float yscale);
 
+    void SetMinSize (long minWidth, long minHeight);
+    void SetMaxSize (long maxWidth, long maxHeight);
+
     void AddChild (Window *child);
     void AddChild (Layout *child);
 
@@ -54,6 +57,7 @@ public:
 
 protected:
     float m_xalign, m_yalign, m_xscale, m_yscale;
+    long m_minWidth, m_minHeight, m_maxWidth, m_maxHeight;
     int m_borderWidth;
     Size m_requisition;
     Rectangle m_allocation;
diff --git a/vcl/inc/vcl/table.hxx b/vcl/inc/vcl/table.hxx
index 4281c02..f1522d9 100644
--- a/vcl/inc/vcl/table.hxx
+++ b/vcl/inc/vcl/table.hxx
@@ -31,11 +31,14 @@
 class VCL_DLLPUBLIC Table : public Layout
 {
 public:
-    Table (int cols);
+    Table (int cols, int rows);
 
-    void PackChild (Window *child, int rowSpan, int colSpan, bool rowExpand, bool colExpand);
-    void PackChild (Layout *child, int rowSpan, int colSpan, bool rowExpand, bool colExpand);
-    void SetSpacings (int rowSpacing, int colSpacing);
+    void Attach (Window *child, int left, int right, int top, int bottom,
+                 bool xexpand, bool yexpand);
+    void Attach (Layout *child, int left, int right, int top, int bottom,
+                 bool xexpand, bool yexpand);
+
+    void SetSpacings (int xspacing, int yspacing);
 
     virtual void AddChild (Widget &child);
     virtual void RemoveChild (Widget &child);
@@ -56,29 +59,34 @@ public:
     virtual const char *DebugName() const  { return "Table"; }
 
 protected:
-    void PackChild (Widget &widget, int rowSpan, int colSpan, bool rowExpand, bool colExpand);
+    void Attach (Widget &widget, int left, int right, int top, int bottom,
+                 bool xexpand, bool yexpand);
+    void GetReqSize (int left, int right, int top, int bottom, long extraWidth, long extraHeight,
+                     long *width, long *height);
 
     struct ChildData {
-        ChildData (Widget &child, int rowSpan, int colSpan, bool rowExpand, bool colExpand);
+        ChildData (Widget &child, int left, int right, int top, int bottom, bool xexpand, bool yexpand);
 
         Widget widget;
-        int rowSpan, colSpan;
-        int rowExpand : 2, colExpand : 2;
-        int leftCol, rightCol, topRow, bottomRow;  // internally calculated:
+        int left, right, top, bottom;
+        int xexpand : 2, yexpand : 2;
     };
     friend struct CmpChild;
 
     struct GroupData {
-        int expand : 2, reqSize;
+        int expand : 2;
+        long reqSize;
+
         GroupData() : expand (false), reqSize (0) {}
     };
 
     std::list <ChildData> m_children;
-    int m_colsLen, m_rowsSpacing, m_colsSpacing;
-    int m_borderWidth;
-
     std::vector <GroupData> m_cols, m_rows;
-    int m_colsExpandables, m_rowsExpandables;
+    int m_colsExpand, m_rowsExpand;
+    int m_colsNb, m_rowsNb;
+
+    int m_borderWidth, m_xspacing, m_yspacing;
+
     Size m_requisition;
     Rectangle m_allocation;
     Widget m_parent;
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 4832561..3bceeb8 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -2365,7 +2365,7 @@ void TabControl::SetMinimumSizePixel( const Size& i_rSize )
 
 Size TabControl::GetTabPageReqSize( USHORT nPageId )
 {
-    long nWidth = mnMaxPageWidth > 0 ? mnMaxPageWidth : 60000;
+    long nWidth = mnMaxPageWidth > 0 ? mnMaxPageWidth : LONG_MAX;
     return ImplGetItemSize( ImplGetItem (nPageId), nWidth );
 }
 
diff --git a/vcl/source/layout/align.cxx b/vcl/source/layout/align.cxx
index 7e14103..6ed54ae 100644
--- a/vcl/source/layout/align.cxx
+++ b/vcl/source/layout/align.cxx
@@ -24,9 +24,21 @@
 #include <vcl/align.hxx>
 
 Align::Align (float xalign, float yalign, float xscale, float yscale)
-: m_xalign (xalign), m_yalign (yalign), m_xscale (xscale), m_yscale (yscale), m_parent (Widget::NIL), m_child (Widget::NIL)
+: m_xalign (xalign), m_yalign (yalign), m_xscale (xscale), m_yscale (yscale), m_minWidth (0), m_minHeight(0), m_maxWidth (LONG_MAX), m_maxHeight (LONG_MAX), m_parent (Widget::NIL), m_child (Widget::NIL)
 {}
 
+void Align::SetMinSize (long minWidth, long minHeight)
+{
+    m_minWidth = minWidth; m_minHeight = minHeight;
+    QueueResize (this);
+}
+
+void Align::SetMaxSize (long maxWidth, long maxHeight)
+{
+    m_maxWidth = maxWidth; m_maxHeight = maxHeight;
+    QueueResize (this);
+}
+
 void Align::AddChild (Widget &child)
 {
     child.SetParent (this);
@@ -67,8 +79,13 @@ Size Align::SizeRequest()
         return m_requisition;
 
     Size req;
-    if (m_child != Widget::NIL)
-        req = m_child.SizeRequest();
+    if (m_child != Widget::NIL) {
+        req.Width() = SAL_MAX (req.Width(), m_minWidth);
+        req.Height() = SAL_MAX (req.Height(), m_minHeight);
+
+        req.Width() = SAL_MIN (req.Width(), m_maxWidth);
+        req.Height() = SAL_MIN (req.Height(), m_maxHeight);
+    }
 
     m_requisition = Size (req.Width() + m_borderWidth*2,
         req.Height() + m_borderWidth*2);
@@ -77,9 +94,9 @@ Size Align::SizeRequest()
 
 void Align::SizeAllocate (long x, long y, long width, long height)
 {
+    m_allocation = Rectangle (x, y, width, height);
     x += m_borderWidth; y += m_borderWidth;
     width -= m_borderWidth*2; height -= m_borderWidth*2;
-    m_allocation = Rectangle (x, y, width, height);
 
     if (!m_child.isNull()) {
         Size childReq (m_child.SizeRequest());
diff --git a/vcl/source/layout/box.cxx b/vcl/source/layout/box.cxx
index 143429e..d17024f 100644
--- a/vcl/source/layout/box.cxx
+++ b/vcl/source/layout/box.cxx
@@ -149,8 +149,8 @@ Size Box::SizeRequest()
 
     if (m_homogeneous)
         reqSize.prim *= visibleChildren;
-    if (visibleChildren > 0)
-        reqSize.prim += (visibleChildren-1) * m_spacing;
+    if (visibleChildren > 1)
+        reqSize.prim += m_spacing * (visibleChildren-1);
     reqSize.prim += m_borderWidth * 2;
     reqSize.secun += m_borderWidth * 2;
 
@@ -159,9 +159,9 @@ Size Box::SizeRequest()
 
 void Box::SizeAllocate (long x, long y, long width, long height)
 {
+    m_allocation = Rectangle (x, y, width, height);
     x += m_borderWidth, y += m_borderWidth;
     width -= m_borderWidth * 2; height -= m_borderWidth * 2;
-    m_allocation = Rectangle (x, y, width, height);
     SizeRequest();  // ensure was called beforehand
 
     int visibleChildren = 0, expandChildren = 0;
diff --git a/vcl/source/layout/buttonbox.cxx b/vcl/source/layout/buttonbox.cxx
index 9f0d6eb..48e1946 100644
--- a/vcl/source/layout/buttonbox.cxx
+++ b/vcl/source/layout/buttonbox.cxx
@@ -171,6 +171,7 @@ struct CmpButtons {
 
 void ButtonBox::SizeAllocate (long x, long y, long width, long height)
 {
+    m_allocation = Rectangle (x, y, width, height);
     x += m_borderWidth; y += m_borderWidth;
     width -= m_borderWidth * 2; height -= m_borderWidth * 2;
     SizeRequest();  // must be run before
diff --git a/vcl/source/layout/layout.cxx b/vcl/source/layout/layout.cxx
index 1b13931..983fca3 100644
--- a/vcl/source/layout/layout.cxx
+++ b/vcl/source/layout/layout.cxx
@@ -42,7 +42,7 @@ struct LayoutProscratinator : public Timer
 
     LayoutProscratinator() : Timer()
     {
-        SetTimeout (20);
+        SetTimeout (0);
     }
 
     void Add (Widget &widget)
@@ -76,10 +76,15 @@ fprintf (stderr, "QueueResize::Add (%s)\n", widget.DebugName());
 
     static Widget GetTopWidgetChanged (Widget &w)
     {
-        for (Widget p = w.GetParent(); !p.isNull(); w = p, p = p.GetParent())
+        Widget ret = w;
+fprintf (stderr, "GetTopWidgetChanged of %s\n", w.DebugName());
+        for (Widget p = w.GetParent(); !p.isNull(); ret = p, p = p.GetParent())
+{
+fprintf (stderr, "parent is %s - size changed? %d - has parent? %d\n", p.DebugName(), p.HasSizeChanged(), !p.GetParent().isNull());
             if (!p.HasSizeChanged())
                 break;
-        return w;
+}
+        return ret;
     }
 
 #ifdef DEBUG_PROSCRATINATOR
@@ -307,6 +312,7 @@ bool Widget::HasSizeChanged()
         Size oldSize (m_layout->SizeRequest());
         m_layout->InvalidateSize();
         Size newSize (m_layout->SizeRequest());
+fprintf (stderr, "%s::HasSizeChanged() - old size: %ld x %ld , new size: %ld x %ld\n", DebugName(), oldSize.Width(), oldSize.Height(), newSize.Width(), newSize.Height());
         return oldSize != newSize;
     }
     return true;
diff --git a/vcl/source/layout/ldialog.cxx b/vcl/source/layout/ldialog.cxx
index 6e87785..859778b 100644
--- a/vcl/source/layout/ldialog.cxx
+++ b/vcl/source/layout/ldialog.cxx
@@ -36,6 +36,9 @@ LDialog::LDialog()
 : Dialog (DIALOG_NO_PARENT, WB_LDIALOG), m_child (Widget::NIL), m_autoResize (1), m_borderWidth (0), m_defaultWidth (0), m_defaultHeight (0)
 {}
 
+void LDialog::SetDefaultSize (long width, long height)
+{ m_defaultWidth = width; m_defaultHeight = height; }
+
 void LDialog::AddChild (Widget &child)
 {
 fprintf (stderr, "LDialog::AddChild (%s)\n", child.DebugName());
diff --git a/vcl/source/layout/notebook.cxx b/vcl/source/layout/notebook.cxx
index 213500d..e94d021 100644
--- a/vcl/source/layout/notebook.cxx
+++ b/vcl/source/layout/notebook.cxx
@@ -108,7 +108,7 @@ Size Notebook::SizeRequest()
     for (unsigned int i = 0; i < m_children.size(); i++) {
         Widget &child = m_children[i];
         if (!child.isNull()) {
-            Size tabSize (GetTabPageReqSize (i+1)); //(GetTabBounds(i).GetSize());
+            Size tabSize (GetTabPageReqSize (i+1));
             tabWidth += tabSize.Width() + 4;
             tabHeight = SAL_MAX (tabHeight, tabSize.Height()+4);
 
@@ -144,7 +144,6 @@ void Notebook::SizeAllocate (long x, long y, long width, long height)
 
 void Notebook::ActivatePage()
 {
-fprintf (stderr, "Notebook::ActivatePage()\n");
     TabControl::ActivatePage();
     // we must delay 'activate' response because TabControl will still
     // be processing important stuff
@@ -159,14 +158,10 @@ IMPL_LINK (Notebook, ActivateTimerHdl, void *, EMPTYARG)
 
 void Notebook::StateChanged (StateChangedType type)
 {
-fprintf (stderr, "Notebook::StateChanged (%d)\n", type);
     TabControl::StateChanged (type);
-
+#if 1
     if (type == STATE_CHANGE_INITSHOW)
         SyncChildSize();
-#if 0
-    if (GetChildCount() > 0)
-        SetCurPageId (0);
 #endif
 }
 
diff --git a/vcl/source/layout/table.cxx b/vcl/source/layout/table.cxx
index f9c41cd..83d2a9f 100644
--- a/vcl/source/layout/table.cxx
+++ b/vcl/source/layout/table.cxx
@@ -31,39 +31,52 @@ struct CmpChild {
     { return childData.widget == m_child; }
 };
 
-Table::ChildData::ChildData (Widget &w, int rs, int cs, bool re, bool ce)
-: widget (w), rowSpan (rs), colSpan (cs), rowExpand (re), colExpand (ce)
+Table::ChildData::ChildData (Widget &w, int l, int r, int t, int b, bool x, bool y)
+: widget (w), left (l), right (r), top (t), bottom (b), xexpand (x), yexpand (y)
 {}
 
-Table::Table (int cols)
-: m_colsLen (cols), m_rowsSpacing (0), m_colsSpacing (0), m_borderWidth (0), m_colsExpandables (0), m_rowsExpandables (0), m_parent (Widget::NIL)
-{}
+Table::Table (int cols, int rows)
+: m_colsNb (cols), m_rowsNb (rows), m_borderWidth (0), m_xspacing (0), m_yspacing (0),
+m_parent (Widget::NIL)
+{
+    m_cols.resize (cols);
+    m_rows.resize (rows);
+}
 
-void Table::PackChild (Widget &child, int rowSpan, int colSpan, bool rowExpand, bool colExpand)
+void Table::Attach (Widget &child, int left, int right, int top, int bottom,
+                    bool xexpand, bool yexpand)
 {
-    if (rowSpan <= 0 || colSpan <= 0)
-        fprintf (stderr, "Table::PackChild Error: child must be given a "
-            "minimum of 1 of row-span and col-span\n");
+    if (left < 0 || right > m_colsNb || top < 0 || bottom > m_rowsNb || left >= right || top >= bottom) {
+        fprintf (stderr, "Table::Attach (%s, %d, %d, %d, %d, %s, %s): out of range arguments\n",
+            child.DebugName(), left, right, top, bottom, xexpand ? "true" : "false",
+            yexpand ? "true" : "false");
+        return;
+    }
 
-    m_children.push_back (ChildData (child, rowSpan, colSpan, rowExpand, colExpand));
+    m_children.push_back (ChildData (child, left, right, top, bottom, xexpand, yexpand));
     child.SetParent (this);
     QueueResize (this);
 }
 
-void Table::PackChild (Window *child, int rowSpan, int colSpan, bool rowExpand, bool colExpand)
-{ Widget w (child); PackChild (w, rowSpan, colSpan, rowExpand, colExpand); }
-void Table::PackChild (Layout *child, int rowSpan, int colSpan, bool rowExpand, bool colExpand)
-{ Widget w (child); PackChild (w, rowSpan, colSpan, rowExpand, colExpand); }
+void Table::Attach (Window *child, int left, int right, int top, int bottom,
+                    bool xexpand, bool yexpand)
+{ Widget w (child); Attach (w, left, right, top, bottom, xexpand, yexpand); }
+
+void Table::Attach (Layout *child, int left, int right, int top, int bottom,
+                    bool xexpand, bool yexpand)
+{ Widget w (child); Attach (w, left, right, top, bottom, xexpand, yexpand); }
 
-void Table::SetSpacings (int rowSpacing, int colSpacing)
+void Table::SetSpacings (int xspacing, int yspacing)
 {
-    m_rowsSpacing = rowSpacing; m_colsSpacing = colSpacing;
+    m_xspacing = xspacing; m_yspacing = yspacing;
     QueueResize (this);
 }
 
 void Table::AddChild (Widget &child)
 {
-    PackChild (child, 1, 1, true, true);
+    int left = m_children.size() % m_colsNb;
+    int top = m_children.size() / m_rowsNb;
+    Attach (child, left, left+1, top, top+1, false, false);
 }
 
 void Table::RemoveChild (Widget &child)
@@ -93,166 +106,94 @@ Size Table::SizeRequest()
     if (m_requisition.Width() != 0 && m_requisition.Height() != 0)
         return m_requisition;
 
-    Table *pThis = const_cast <Table *> (this);
-    int rowsLen = 0;
+    // 1. clear cols and rows data
+    for (std::vector <GroupData>::iterator it = m_cols.begin();
+         it != m_cols.end(); it++)
+    { it->expand = false; it->reqSize = 0; }
+    for (std::vector <GroupData>::iterator it = m_rows.begin();
+         it != m_rows.end(); it++)
+    { it->expand = false; it->reqSize = 0; }
 
-    // 1. layout the table -- adjust to cope with row-spans...
-    {
-        // temporary 1D representation of the table
-        std::vector <ChildData *> table;
-
-        int col = 0, row = 0;
-        for (std::list <ChildData>::iterator it = pThis->m_children.begin();
-             it != pThis->m_children.end(); it++) {
-            ChildData *child = &(*it);
-            if (!child->widget.IsVisible()) continue;
-
-            while (col + SAL_MIN (child->colSpan, m_colsLen) > m_colsLen) {
-                col = 0;
-                row++;
-
-                unsigned int i = col + (row * m_colsLen);
-                while (table.size() > i && !table[i]) i++;
-
-                col = i % m_colsLen; row = i / m_colsLen;
+    // 2. divide children req-size through the rows and cols they occupy
+    m_colsExpand = 0; m_rowsExpand = 0;
+    for (std::list <ChildData>::iterator it = m_children.begin();
+         it != m_children.end(); it++) {
+        Size childSize (it->widget.SizeRequest());
+
+        int xspan = it->right - it->left;
+        for (int i = it->left; i < it->right; i++) {
+            GroupData &c = m_cols[i];
+            c.reqSize = SAL_MAX (c.reqSize, childSize.Width() / xspan);
+            if (it->xexpand && !c.expand) {
+                c.expand = true;
+                m_colsExpand++;
             }
-
-            child->leftCol = col;
-            child->rightCol = SAL_MIN (col + child->colSpan, m_colsLen);
-            child->topRow = row;
-            child->bottomRow = row + child->rowSpan;
-
-            col += child->colSpan;
-
-            unsigned int start = child->leftCol + (child->topRow * m_colsLen);
-            unsigned int end = (child->rightCol-1) + ((child->bottomRow-1) * m_colsLen);
-            if (table.size() < end+1)
-                table.resize( end+1, NULL );
-            for (unsigned int i = start; i < end; i++)
-                table[ i ] = child;
-
-            rowsLen = SAL_MAX (rowsLen, child->bottomRow);
         }
-    }
-
-    // 2. calculate columns/rows sizes
-    for (int g = 0; g < 2; g++) {
-        std::vector <GroupData> &group = (g == 0) ? pThis->m_cols : pThis->m_rows;
-        group.clear();
-        group.resize (g == 0 ? m_colsLen : rowsLen);
-
-        // 2.1 base sizes on one-column/row children
-        for (std::list <ChildData>::iterator it = m_children.begin();
-             it != m_children.end(); it++) {
-            ChildData *child = &(*it);
-            if (!child->widget.IsVisible()) continue;
-            const int firstAttach = (g == 0) ? child->leftCol : child->topRow;
-            const int lastAttach  = (g == 0) ? child->rightCol : child->bottomRow;
-
-            if (firstAttach == lastAttach-1) {
-                Size reqSize (child->widget.SizeRequest());
-                int childSize = (g == 0) ? reqSize.Width() : reqSize.Height();
-                bool childExpand = (g == 0) ? child->colExpand : child->rowExpand;
-                int attach = firstAttach;
-                group[attach].reqSize = SAL_MAX (group[attach].reqSize, childSize);
-                group[attach].expand = childExpand || group[attach].expand;
+        int yspan = it->bottom - it->top;
+        for (int i = it->top; i < it->bottom; i++) {
+            GroupData &r = m_rows[i];
+            r.reqSize = SAL_MAX (r.reqSize, childSize.Height() / yspan);
+            if (it->yexpand && !r.expand) {
+                r.expand = true;
+                m_rowsExpand++;
             }
         }
+    }
 
-        // 2.2 make sure multiple-columns/rows children fit
-        for (std::list <ChildData>::iterator it = m_children.begin();
-             it != m_children.end(); it++ ) {
-            ChildData *child = &(*it);
-            if (!child->widget.IsVisible()) continue;
-            const int firstAttach = (g == 0) ? child->leftCol : child->topRow;
-            const int lastAttach  = (g == 0) ? child->rightCol : child->bottomRow;
-
-            if (firstAttach != lastAttach-1) {
-                Size reqSize (child->widget.SizeRequest());
-                int size = 0;
-                int expandables = 0;
-                for ( int i = firstAttach; i < lastAttach; i++ ) {
-                    size += group[i].reqSize;
-                    if (group[ i ].expand) expandables++;
-                }
-
-                long childSize = (g == 0) ? reqSize.Width() : reqSize.Height();
-                long extra = childSize - size;
-                if (extra > 0) {
-                    if (expandables) extra /= expandables;
-                    else extra /= lastAttach - firstAttach;
+    // 3. sum everything up
+    long width, height;
+    GetReqSize (0, m_colsNb, 0, m_rowsNb, 0, 0, &width, &height);
+    width += m_borderWidth * 2;
+    height += m_borderWidth * 2;
 
-                    for (int i = firstAttach; i < lastAttach; i++)
-                        if (expandables == 0 || group[i].expand)
-                            group[i].reqSize += extra;
-                }
-            }
-        }
-    }
+    return (m_requisition = Size (width, height));
+}
 
-    // 3. Sum everything up
-    pThis->m_colsExpandables = (pThis->m_rowsExpandables = 0);
-    long width = 0, height = 0;
-    for (std::vector <GroupData>::const_iterator it = m_cols.begin();
-         it != m_cols.end(); it++ ) {
-        width += it->reqSize;
-        if (it->expand)
-            pThis->m_colsExpandables++;
+void Table::GetReqSize (int left, int right, int top, int bottom, long extraWidth, long extraHeight, long *width, long *height)
+{
+    *width = 0; *height = 0;
+    for (int i = left; i < right; i++) {
+        GroupData &c = m_cols[i];
+        *width += c.reqSize;
+        if (c.expand) *width += extraWidth;
     }
-    for (std::vector <GroupData>::const_iterator it = m_rows.begin();
-          it != m_rows.end(); it++ ) {
-        height += it->reqSize;
-        if (it->expand)
-            pThis->m_rowsExpandables++;
+    for (int i = top; i < bottom; i++) {
+        GroupData &r = m_rows[i];
+        *height += r.reqSize;
+        if (r.expand) *height += extraHeight;
     }
-
-    pThis->m_requisition = Size (width, height);
-    return m_requisition;
+    int xspan = right - left, yspan = bottom - top;
+    if (xspan > 1)
+        *width += m_xspacing * (xspan-1);
+    if (yspan > 1)
+        *height += m_yspacing * (yspan-1);
 }
 
 void Table::SizeAllocate (long x, long y, long width, long height)
 {
+    long extraWidth = 0, extraHeight = 0;
+    if (m_colsExpand)
+        extraWidth = (width - m_requisition.Width()) / m_colsExpand;
+    if (m_rowsExpand)
+        extraHeight = (height - m_requisition.Height()) / m_rowsExpand;
+
+    m_allocation = Rectangle (x, y, width, height);
     x += m_borderWidth; y += m_borderWidth;
     width -= m_borderWidth * 2; height -= m_borderWidth * 2;
-    m_allocation = Rectangle (x, y, width, height);
     SizeRequest();  // ensure was called beforehand
 
-    if (m_cols.size() == 0 || m_rows.size() == 0) return;
-
-    long extraSize[2];
-    extraSize[0] = SAL_MAX (width - m_requisition.Width(), 0);
-    extraSize[1] = SAL_MAX (height - m_requisition.Height(), 0);
-    extraSize[0] /= m_colsExpandables ? m_colsExpandables : m_colsLen;
-    extraSize[1] /= m_rowsExpandables ? m_rowsExpandables : m_rows.size();
-
     for (std::list <ChildData>::iterator it = m_children.begin();
          it != m_children.end(); it++) {
-        ChildData *child = &(*it);
-        if (!child->widget.IsVisible()) continue;
+        ChildData &child = *it;
 
-        long childX = x, childY = y, childWidth = 0, childHeight = 0;
-        for (int g = 0; g < 2; g++) {
-            std::vector <GroupData> &group = (g == 0) ? m_cols : m_rows;
-            const int firstAttach = (g == 0) ? child->leftCol : child->topRow;
-            const int lastAttach  = (g == 0) ? child->rightCol : child->bottomRow;
-
-            for (int i = 0; i < firstAttach; i++) {
-                int size = group[i].reqSize;
-                if (group[i].expand)
-                    size += extraSize[g];
-                if (g == 0) childX += size;
-                else childY += size;
-            }
-            for (int i = firstAttach; i < lastAttach; i++) {
-                long size = group[i].reqSize;
-                if (group[i].expand)
-                    size += extraSize[g];
-                if (g == 0) childWidth += size;
-                else childHeight += size;
-            }
-        }
+        long childX, childY, childWidth, childHeight;
+        GetReqSize (0, child.left, 0, child.top, extraWidth, extraHeight, &childX, &childY);
+        GetReqSize (child.left, child.right, child.top, child.bottom, extraWidth, extraHeight,
+                    &childWidth, &childHeight);
+        if (child.left > 0) childX += m_xspacing;
+        if (child.top > 0) childY += m_yspacing;
 
-        child->widget.SizeAllocate (childX, childY, childWidth, childHeight);
+        child.widget.SizeAllocate (x + childX, y + childY, childWidth, childHeight);
     }
 }
 


More information about the Libreoffice-commits mailing list