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

Ricardo Cruz rpmcruz at kemper.freedesktop.org
Fri Dec 17 19:24:24 PST 2010


 vcl/inc/vcl/align.hxx           |    6 
 vcl/inc/vcl/box.hxx             |    7 -
 vcl/inc/vcl/buttonbox.hxx       |   63 ++++++++--
 vcl/inc/vcl/layout.hxx          |   29 ++--
 vcl/inc/vcl/ldialog.hxx         |   24 +++
 vcl/inc/vcl/notebook.hxx        |   12 +
 vcl/inc/vcl/tabctrl.hxx         |    3 
 vcl/inc/vcl/table.hxx           |    6 
 vcl/source/control/tabctrl.cxx  |    8 +
 vcl/source/layout/box.cxx       |    9 -
 vcl/source/layout/buttonbox.cxx |  210 +++++++++++++++++++++++++++-------
 vcl/source/layout/layout.cxx    |  241 ++++++++++------------------------------
 vcl/source/layout/ldialog.cxx   |   58 +++++----
 vcl/source/layout/notebook.cxx  |   93 +++++++--------
 vcl/source/layout/table.cxx     |   20 +--
 15 files changed, 456 insertions(+), 333 deletions(-)

New commits:
commit 1ca9321f7365c45726d4e6ff8b24ee28b0b8ebbb
Author: Ricardo Cruz <rpmcruz at alunos.dcc.fc.up.pt>
Date:   Sat Dec 18 03:23:40 2010 +0000

    Implemented ButtonBox: needs to be read plataform defaults next

diff --git a/vcl/inc/vcl/buttonbox.hxx b/vcl/inc/vcl/buttonbox.hxx
index 05e91fd..84efbc1 100644
--- a/vcl/inc/vcl/buttonbox.hxx
+++ b/vcl/inc/vcl/buttonbox.hxx
@@ -18,41 +18,76 @@
  *
  ************************************************************************/
 
-#ifndef VCL_BOX_HXX
+#ifndef VCL_BUTTON_BOX_HXX
 #define VCL_BUTTON_BOX_HXX
 
 #include <vcl/dllapi.h>
-#include <vcl/box.hxx>
-#include <map>
+#include <vcl/layout.hxx>
+#include <list>
 
 /* Places buttons according to their "roles" as specified by
    the user's desktop.
 */
 
-class Button;
+class PushButton;
 
-class VCL_DLLPUBLIC ButtonBox : public HBox
+// To implement by the plataform
+enum ButtonRole {
+    OK_BUTTON, CANCEL_BUTTON, APPLY_BUTTON, REVERT_BUTTON, HELP_BUTTON,
+    CUSTOM_BUTTON
+};
+
+struct ButtonOrder {
+    virtual int RoleAlign (ButtonRole role) = 0;  // (-1,0,+1) for (left,center,right)
+    virtual int RoleOrder (ButtonRole role) = 0;      // any natural number
+    virtual bool UseSameSize() = 0;
+};
+
+class VCL_DLLPUBLIC ButtonBox : public Layout
 {
 public:
     ButtonBox();
 
-    enum Role {
-        OK_BUTTON, CANCEL_BUTTON, APPLY_BUTTON, HELP_BUTTON, CUSTOM_BUTTON
-    };
-
-    void Pack (Button *button, Role role);
+    void Pack (PushButton *button, ButtonRole role);
 
+    virtual void AddChild (Widget &child);
     virtual void RemoveChild (Widget &child);
+    virtual std::list <Widget> GetChildren() const;
 
+    virtual void SetParent (Widget &parent)  { m_parent = parent; }
+    virtual Widget GetParent() const  { return m_parent; }
+
+    virtual void SetBorderWidth (int borderWidth);
+
+    virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
+    virtual Rectangle GetAllocation() const { return m_allocation; }
+
+    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
+    virtual bool SupportsInvalidateSize() { return true; }
 
     virtual const char *DebugName() const  { return "ButtonBox"; }
 
 protected:
-    friend struct ChildOrder;
+    void Pack (Widget &child, ButtonRole role);
+
+    struct ChildData {
+        ChildData (Widget &child, ButtonRole role);
+
+        Widget button;
+        ButtonRole role;
+        Size requisition;  // cache
+    };
+    friend struct CmpChild;
+    friend struct CmpButtons;
 
-// FIXME: change to list
-//    std::map <Widget, Role> m_roles;
+    ButtonOrder *m_buttonOrder;
+    int m_borderWidth;
+    long m_maxButtonWidth;
+    std::list <ChildData> m_children;
+    Size m_requisition;
+    Rectangle m_allocation;
+    Widget m_parent;
 };
 
 #endif /* VCL_BUTTON_BOX_HXX */
diff --git a/vcl/source/layout/buttonbox.cxx b/vcl/source/layout/buttonbox.cxx
index e3d0f3b..48b8e6d 100644
--- a/vcl/source/layout/buttonbox.cxx
+++ b/vcl/source/layout/buttonbox.cxx
@@ -24,70 +24,194 @@
 #include <vcl/button.hxx>
 #include <vcl/buttonbox.hxx>
 
-ButtonBox::ButtonBox ()
-: HBox (true, 12)
+#define SPACING 6
+
+// TODO: export order to plugins
+
+struct DefaultButtonOrder : public ButtonOrder {
+    virtual int RoleAlign (ButtonRole role) {
+        switch (role) {
+            case OK_BUTTON:     return +1;
+            case CANCEL_BUTTON: return +1;
+            case APPLY_BUTTON:  return +1;
+            case REVERT_BUTTON: return -1;
+            case HELP_BUTTON:   return -1;
+            case CUSTOM_BUTTON: return +1;
+        }
+        return 1;
+    }
+    virtual int RoleOrder (ButtonRole role) {
+        switch (role) {
+            // right align
+            case OK_BUTTON:     return 3;
+            case CANCEL_BUTTON: return 2;
+            case APPLY_BUTTON:  return 1;
+            case CUSTOM_BUTTON: return 0;
+            // left align
+            case HELP_BUTTON:   return 0;
+            case REVERT_BUTTON: return 1;
+        }
+        return 5;
+    }
+    virtual bool UseSameSize() { return true; }
+};
+
+struct CmpChild {
+    Widget m_child;
+    CmpChild (Widget &child) : m_child (child) {}
+
+    bool operator() (const ButtonBox::ChildData &childData)
+    { return Widget (childData.button) == m_child; }
+};
+
+ButtonBox::ChildData::ChildData (Widget &b, ButtonRole r)
+: button (b), role (r)
 {}
 
-void ButtonBox::Pack (Button *button, Role role)
+ButtonBox::ButtonBox()
+: m_borderWidth (0), m_parent (Widget::NIL)
 {
-    Widget widget (button);
-#if 0
-    m_roles[widget] = role;
-#endif
-    Box::Pack (widget, false, true);
+    static DefaultButtonOrder order;
+    m_buttonOrder = &order;
+}
+
+void ButtonBox::Pack (Widget &child, ButtonRole role)
+{
+    m_children.push_back (ChildData (child, role));
+    child.SetParent (this);
+    QueueResize (this);
+}
+
+void ButtonBox::Pack (PushButton *button, ButtonRole role)
+{
+    Widget w (button);
+    Pack (w, role);
+}
+
+void ButtonBox::AddChild (Widget &child)
+{
+    Pack (child, CUSTOM_BUTTON);
 }
 
 void ButtonBox::RemoveChild (Widget &child)
 {
-#if 0
-    m_roles.erase (child);
-#endif
-    Box::RemoveChild (child);
+    CmpChild isChild (child);
+    m_children.remove_if (isChild);
+    QueueResize (this);
 }
 
-// TODO: order ought dependend on system settings
-// The higher the placement role, the more to the right they are placed.
-// Positive values are aligned to the right, negatives values to the left.
-// TODO: create special flag for the center
+std::list <Widget> ButtonBox::GetChildren() const
+{
+    std::list <Widget> children;
+    for (std::list <ChildData>::const_iterator it = m_children.begin();
+         it != m_children.end(); it++)
+        children.push_back (it->button);
+    return children;
+}
 
-static int GetRolePlacement (ButtonBox::Role role)
+void ButtonBox::SetBorderWidth (int borderWidth)
 {
-    switch (role) {
-        case ButtonBox::OK_BUTTON:     return  4;
-        case ButtonBox::CANCEL_BUTTON: return  2;
-        case ButtonBox::APPLY_BUTTON:  return  3;
-        case ButtonBox::HELP_BUTTON:   return -1;
-        case ButtonBox::CUSTOM_BUTTON: return  0;
-    }
-    return 0;
+    m_borderWidth = borderWidth = borderWidth;
+    QueueResize (this);
 }
 
-#if 0
-struct ChildOrder {
-    ButtonBox *box;
-    ChildOrder (ButtonBox *b) : box (b) {}
+Size ButtonBox::SizeRequest()
+{
+    if (m_requisition.Width() != 0 || m_requisition.Height() != 0)
+        return m_requisition;
+
+    m_maxButtonWidth = 0;
+    int childrenNb = 0;
+    long width = 0, height = 0;
+    for (std::list <ChildData>::iterator it = m_children.begin();
+         it != m_children.end(); it++) {
+        Widget &button = it->button;
+        if (button.IsVisible()) {
+            Size childReq (button.SizeRequest());
+            it->requisition = childReq;
+
+            if (m_buttonOrder->UseSameSize())
+                m_maxButtonWidth = SAL_MAX (m_maxButtonWidth, childReq.Width());
+            else
+                width += childReq.Width();
+            height = SAL_MAX (height, childReq.Height());
+            childrenNb++;
+        }
+    }
+
+    if (m_buttonOrder->UseSameSize())
+        width = m_maxButtonWidth * childrenNb;
+    if (childrenNb > 0)  // spacing
+        width += (SPACING * (childrenNb-1));
+    width += m_borderWidth * 2;
+    height += m_borderWidth * 2;
+
+    m_requisition = Size (width, height);
+    return m_requisition;
+}
 
-    bool operator() (Box::ChildData &child1, Box::ChildData &child2) {
-        std::map <Widget, ButtonBox::Role> &m = box->m_roles;
-        std::map <Widget, ButtonBox::Role>::iterator it, jt;
-        it = m.find (child1.widget);
-        jt = m.find (child2.widget);
+struct CmpButtons {
+    ButtonOrder *order;
+    CmpButtons (ButtonOrder *o) : order (o) {}
 
-        int weight1 = it == m.end() ? 0 : GetRolePlacement (it->second);
-        int weight2 = jt == m.end() ? 0 : GetRolePlacement (jt->second);
-        return weight1 < weight2;
+    bool operator() (const ButtonBox::ChildData *child1, const ButtonBox::ChildData *child2)
+    {
+        return order->RoleOrder (child1->role) > order->RoleOrder (child2->role);
     }
 };
-#endif
 
 void ButtonBox::SizeAllocate (long x, long y, long width, long height)
 {
-#if 0   // FIXME
-    ChildOrder order (this);
-    std::sort (Box::m_children.begin(), Box::m_children.end(), order);
-#endif
+    x += m_borderWidth; y += m_borderWidth;
+    width -= m_borderWidth * 2; height -= m_borderWidth * 2;
+    SizeRequest();  // must be run before
+
+    CmpButtons cmp (m_buttonOrder);
+    for (int align = -1; align <= +1; align++) {
+        std::vector <ChildData *> buttons;
+        buttons.reserve (m_children.size());
+        long childrenWidth = 0;  // required for align=0
 
-    Box::SizeAllocate (x, y, width, height);
+        // 1. filter buttons belonging to this alignment
+        for (std::list <ChildData>::iterator it = m_children.begin();
+             it != m_children.end(); it++) {
+            Widget &button = it->button;
+            if (button.IsVisible())
+                if (m_buttonOrder->RoleAlign (it->role) == align) {
+                    buttons.push_back (&(*it));
+                    if (align == 0)
+                        childrenWidth += it->requisition.Width();
+                }
+        }
+        if (align == 0)
+            childrenWidth += SPACING * (buttons.size()-1);
+
+        // 2. sort buttons by order
+        std::sort (buttons.begin(), buttons.end(), cmp);
+
+        // 3. allocate buttons
+        long childX;
+        switch (align) {
+            case -1: childX = 0; break;
+            case  0: childX = (width - childrenWidth) / 2; break;
+            case +1: childX = width; break;
+        }
+        for (std::vector <ChildData *>::iterator it = buttons.begin();
+             it != buttons.end(); it++) {
+            long childWidth;
+            if (m_buttonOrder->UseSameSize())
+                childWidth = m_maxButtonWidth;
+            else
+                childWidth = (*it)->requisition.Width();
+            if (align == +1)
+                childX -= childWidth;
+
+            (*it)->button.SizeAllocate (x + childX, y, childWidth, height);
+            if (align <= 0)
+                childX += childWidth;
+            childX += SPACING * (align <= 0 ? +1 : -1);
+        }
+    }
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/layout/layout.cxx b/vcl/source/layout/layout.cxx
index 7f930c3..61e25e6 100644
--- a/vcl/source/layout/layout.cxx
+++ b/vcl/source/layout/layout.cxx
@@ -254,10 +254,8 @@ void Widget::ShowAll()
 
 void Widget::Foreach (Widget::ForeachCallback callback)
 {
-fprintf (stderr, "%s::Foreach()\n", DebugName());
     if (m_layout) {
         std::list <Widget> children (m_layout->GetChildren());
-fprintf (stderr, "\tchildren nb: %d\n", children.size());
         for (std::list <Widget>::iterator it = children.begin();
              it != children.end(); it++)
             it->Foreach (callback);
@@ -270,24 +268,28 @@ fprintf (stderr, "\tchildren nb: %d\n", children.size());
         }
     }
 
-//fprintf (stderr, "%s::Foreach()\n", DebugName());
     callback (*this);
 }
 
 Size Widget::SizeRequest()
 {
-//fprintf (stderr, "%s::SizeRequest()\n", DebugName(), x, y, width, height);
+fprintf (stderr, "%s::SizeRequest()\n", DebugName());
+    Size ret;
     if (m_layout)
-        return m_layout->SizeRequest();
-    return m_window->GetOptimalSize (WINDOWSIZE_PREFERRED);
+        ret = m_layout->SizeRequest();
+    else if (m_window)
+        ret = m_window->GetOptimalSize (WINDOWSIZE_PREFERRED);
+fprintf (stderr, "\t%s::SizeRequest() -> %ld x %ld\n", DebugName(), ret.Width(), ret.Height());
+    return ret;
 }
 
 void Widget::SizeAllocate (long x, long y, long width, long height)
 {
 fprintf (stderr, "%s::SizeAllocate: %ld,%ld x %ld,%ld \n", DebugName(), x, y, width, height);
     if (m_layout)
-        return m_layout->SizeAllocate (x, y, width, height);
-    return m_window->SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
+        m_layout->SizeAllocate (x, y, width, height);
+    else if (m_window)
+        m_window->SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
 }
 
 void Widget::SizeAllocate (const Rectangle &rect)
diff --git a/vcl/source/layout/table.cxx b/vcl/source/layout/table.cxx
index 8bd34b3..f9c41cd 100644
--- a/vcl/source/layout/table.cxx
+++ b/vcl/source/layout/table.cxx
@@ -107,7 +107,7 @@ Size Table::SizeRequest()
             ChildData *child = &(*it);
             if (!child->widget.IsVisible()) continue;
 
-            while (col + SAL_MIN (child->colSpan, m_colsLen ) > m_colsLen) {
+            while (col + SAL_MIN (child->colSpan, m_colsLen) > m_colsLen) {
                 col = 0;
                 row++;
 
@@ -118,14 +118,14 @@ Size Table::SizeRequest()
             }
 
             child->leftCol = col;
-            child->rightCol = SAL_MIN( col + child->colSpan, m_colsLen );
+            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);
+            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++)
@@ -176,8 +176,8 @@ Size Table::SizeRequest()
                     if (group[ i ].expand) expandables++;
                 }
 
-                int childSize = (g == 0) ? reqSize.Width() : reqSize.Height();
-                int extra = childSize - size;
+                long childSize = (g == 0) ? reqSize.Width() : reqSize.Height();
+                long extra = childSize - size;
                 if (extra > 0) {
                     if (expandables) extra /= expandables;
                     else extra /= lastAttach - firstAttach;
@@ -192,7 +192,7 @@ Size Table::SizeRequest()
 
     // 3. Sum everything up
     pThis->m_colsExpandables = (pThis->m_rowsExpandables = 0);
-    int width = 0, height = 0;
+    long width = 0, height = 0;
     for (std::vector <GroupData>::const_iterator it = m_cols.begin();
          it != m_cols.end(); it++ ) {
         width += it->reqSize;
@@ -219,7 +219,7 @@ void Table::SizeAllocate (long x, long y, long width, long height)
 
     if (m_cols.size() == 0 || m_rows.size() == 0) return;
 
-    int extraSize[2];
+    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;
@@ -230,7 +230,7 @@ void Table::SizeAllocate (long x, long y, long width, long height)
         ChildData *child = &(*it);
         if (!child->widget.IsVisible()) continue;
 
-        int childX = x, childY = y, childWidth = 0, childHeight = 0;
+        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;
@@ -244,7 +244,7 @@ void Table::SizeAllocate (long x, long y, long width, long height)
                 else childY += size;
             }
             for (int i = firstAttach; i < lastAttach; i++) {
-                int size = group[i].reqSize;
+                long size = group[i].reqSize;
                 if (group[i].expand)
                     size += extraSize[g];
                 if (g == 0) childWidth += size;
commit 5065d184209833c0a4d4a21ab14d67b21700310f
Author: Ricardo Cruz <rpmcruz at alunos.dcc.fc.up.pt>
Date:   Fri Dec 17 23:55:40 2010 +0000

    Fixed Notebook

diff --git a/vcl/inc/vcl/notebook.hxx b/vcl/inc/vcl/notebook.hxx
index bef8f56..17d69b3 100644
--- a/vcl/inc/vcl/notebook.hxx
+++ b/vcl/inc/vcl/notebook.hxx
@@ -24,6 +24,7 @@
 #include <vcl/dllapi.h>
 #include <vcl/tabctrl.hxx>
 #include <vcl/layout.hxx>
+#include <vcl/timer.hxx>
 #include <vector>
 
 /* Adds dynamic layouting to TabControl.
@@ -56,10 +57,15 @@ public:
 
     virtual const char *DebugName() const  { return "Notebook"; }
 
+    virtual void ActivatePage();
     virtual void StateChanged (StateChangedType type);
 
 protected:
     void AddPage (const String &label, Widget &child);
+    void SyncChildSize();
+
+    DECL_LINK (ActivateTimerHdl, void *);
+    Timer m_activateTimer;
 
     int m_borderWidth;
     std::vector <Widget> m_children;
diff --git a/vcl/inc/vcl/tabctrl.hxx b/vcl/inc/vcl/tabctrl.hxx
index f6ac7e6..b4202b2 100644
--- a/vcl/inc/vcl/tabctrl.hxx
+++ b/vcl/inc/vcl/tabctrl.hxx
@@ -216,6 +216,9 @@ public:
 
     // returns the rectangle of the tab for page nPageId
     Rectangle GetTabBounds( USHORT nPageId ) const;
+
+    // The size necessary to show the tab label item.
+    Size GetTabPageReqSize (USHORT nPageId);
 };
 
 #endif  // _SV_TABCTRL_HXX
diff --git a/vcl/source/control/tabctrl.cxx b/vcl/source/control/tabctrl.cxx
index 986901a..4832561 100644
--- a/vcl/source/control/tabctrl.cxx
+++ b/vcl/source/control/tabctrl.cxx
@@ -2363,5 +2363,13 @@ void TabControl::SetMinimumSizePixel( const Size& i_rSize )
 
 // -----------------------------------------------------------------------
 
+Size TabControl::GetTabPageReqSize( USHORT nPageId )
+{
+    long nWidth = mnMaxPageWidth > 0 ? mnMaxPageWidth : 60000;
+    return ImplGetItemSize( ImplGetItem (nPageId), nWidth );
+}
+
+// -----------------------------------------------------------------------
+
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/layout/box.cxx b/vcl/source/layout/box.cxx
index 99d1989..143429e 100644
--- a/vcl/source/layout/box.cxx
+++ b/vcl/source/layout/box.cxx
@@ -180,8 +180,10 @@ void Box::SizeAllocate (long x, long y, long width, long height)
             visibleChildren++;
         }
     }
+fprintf (stderr, "nb children: %d - visible children: %d - homogeneous: %d\n", m_children.size(), visibleChildren, m_homogeneous);
     if (!visibleChildren) return;
-
+if (m_homogeneous)
+fprintf (stderr, "max child prim size: %ld\n", sameChildSize);
     long extraSpace = 0;
     GVector allocSize (this, width, height);
     if (expandChildren) {
diff --git a/vcl/source/layout/layout.cxx b/vcl/source/layout/layout.cxx
index d96fb82..7f930c3 100644
--- a/vcl/source/layout/layout.cxx
+++ b/vcl/source/layout/layout.cxx
@@ -121,7 +121,6 @@ fprintf (stderr, "QueueResize::Add (%s)\n", widget.DebugName());
 void Layout::QueueResize (Widget &widget)
 {
     if (widget.IsRealized() && widget.IsVisible()) {
-fprintf (stderr, "** adding child to queue resize\n");
         static LayoutProscratinator timer;
         timer.Add (widget);
     }
@@ -255,19 +254,23 @@ void Widget::ShowAll()
 
 void Widget::Foreach (Widget::ForeachCallback callback)
 {
+fprintf (stderr, "%s::Foreach()\n", DebugName());
     if (m_layout) {
         std::list <Widget> children (m_layout->GetChildren());
+fprintf (stderr, "\tchildren nb: %d\n", children.size());
         for (std::list <Widget>::iterator it = children.begin();
              it != children.end(); it++)
             it->Foreach (callback);
     }
-    else if (m_window) {  // also apply to internal windows
+    else if (m_window) {
+        // also apply to internal windows
         for (USHORT i = 0; i < m_window->GetChildCount(); i++) {
             Widget child (m_window->GetChild (i));
-            callback (child);
+            child.Foreach (callback);
         }
     }
 
+//fprintf (stderr, "%s::Foreach()\n", DebugName());
     callback (*this);
 }
 
diff --git a/vcl/source/layout/ldialog.cxx b/vcl/source/layout/ldialog.cxx
index 68753a2..6e87785 100644
--- a/vcl/source/layout/ldialog.cxx
+++ b/vcl/source/layout/ldialog.cxx
@@ -38,6 +38,7 @@ LDialog::LDialog()
 
 void LDialog::AddChild (Widget &child)
 {
+fprintf (stderr, "LDialog::AddChild (%s)\n", child.DebugName());
     m_child = child;
     child.SetParent (this);
     QueueResize (this, this);
@@ -58,8 +59,8 @@ void LDialog::RemoveChild (Widget &)
 std::list <Widget> LDialog::GetChildren() const
 {
     std::list <Widget> children;
-    if (GetChildCount())
-        children.push_back (Widget (GetChild (0)));
+    if (!m_child.isNull())
+        children.push_back (m_child);
     return children;
 }
 
@@ -109,6 +110,7 @@ void LDialog::StateChanged (StateChangedType type)
     Dialog::StateChanged (type);
 
     if (type == STATE_CHANGE_INITSHOW) {
+fprintf (stderr, "LDialog::StateChanged: INITSHOW\n");
 #ifdef USE_REALIZE_TIMER
         m_realizeTimer = new Timer();
         m_realizeTimer->SetTimeoutHdl (LINK (this, LDialog, RealizeTimerHdl));
@@ -124,6 +126,8 @@ void LDialog::StateChanged (StateChangedType type)
 void LDialog::Resize()
 {
     Dialog::Resize();
+if (!m_autoResize)
+fprintf (stderr, "LDialog::Resize - not auto\n");
 
     if (!m_autoResize)
         QueueResize (this, this);
diff --git a/vcl/source/layout/notebook.cxx b/vcl/source/layout/notebook.cxx
index 621742d..213500d 100644
--- a/vcl/source/layout/notebook.cxx
+++ b/vcl/source/layout/notebook.cxx
@@ -36,6 +36,9 @@ Notebook::Notebook (Window *parent)
 : TabControl (parent), m_borderWidth (0)
 {
     m_children.reserve (8);
+
+    m_activateTimer.SetTimeoutHdl (LINK (this, Notebook, ActivateTimerHdl));
+    m_activateTimer.SetTimeout (5);
 }
 
 void Notebook::AddPage (const String &label, Widget &child)
@@ -49,13 +52,12 @@ void Notebook::AddPage (const String &label, Widget &child)
         m_children[i] = child;
 
     // 'i' is just an identifier: it has no bearing on its position
-    InsertPage (i, label, TAB_APPEND);
+    InsertPage (i+1, label, TAB_APPEND);
     TabPage *tab_page = new TabPage (this);
-    SetTabPage (i, tab_page);
-    Widget _this (this, this);
-    child.SetParent (_this, tab_page);
-    if (m_children.size() == 0)
-        SelectTabPage (i);
+    tab_page->Show();
+    SetTabPage (i+1, tab_page);
+    Widget rthis (this, this);
+    child.SetParent (rthis, tab_page);
     QueueResize (this, this);
 }
 
@@ -97,77 +99,75 @@ void Notebook::SetBorderWidth (int borderWidth)
     QueueResize (this, this);
 }
 
-static long GetHeaderHeight() { return 25; }
-
 Size Notebook::SizeRequest()
 {
     if (m_requisition.Width() != 0 && m_requisition.Height() != 0)
         return m_requisition;
 
-    long width = 0, height = 0, tab_width = 0, tab_height = 0;
+    long childWidth = 0, childHeight = 0, tabWidth = 0, tabHeight = 0;
     for (unsigned int i = 0; i < m_children.size(); i++) {
         Widget &child = m_children[i];
         if (!child.isNull()) {
-            Size tab_size (GetTabBounds(i).GetSize());
-            tab_width += tab_size.Width();
-            tab_height = SAL_MAX (tab_height, tab_size.Height());
+            Size tabSize (GetTabPageReqSize (i+1)); //(GetTabBounds(i).GetSize());
+            tabWidth += tabSize.Width() + 4;
+            tabHeight = SAL_MAX (tabHeight, tabSize.Height()+4);
 
             Size childSize (child.SizeRequest());
-            width = SAL_MAX (width, childSize.Width());
-            height = SAL_MAX (height, childSize.Height());
+            childWidth = SAL_MAX (childWidth, childSize.Width());
+            childHeight = SAL_MAX (childHeight, childSize.Height());
         }
     }
-    width = SAL_MAX (width, tab_width);
-
-    width += m_borderWidth * 2;
-    height += (m_borderWidth * 2) + tab_height + 4;
 
+    long width = SAL_MAX (childWidth, tabWidth) + (m_borderWidth * 2) + 2;
+    long height = childHeight + tabHeight + (m_borderWidth * 2) + 4;
     return (m_requisition = Size (width, height));
 }
 
+void Notebook::SyncChildSize()
+{
+    USHORT id = GetCurPageId()-1;
+    Widget &child = m_children[id];
+    if (!child.isNull()) {
+        Window *tab_page = GetTabPage (id+1);
+        Size size (tab_page->GetSizePixel());
+        child.SizeAllocate (0, 0, size.Width(), size.Height());
+    }
+}
+
 void Notebook::SizeAllocate (long x, long y, long width, long height)
 {
     x += m_borderWidth; y += m_borderWidth;
     width -= m_borderWidth*2; height -= m_borderWidth*2;
     Window::SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
+    SyncChildSize();
+}
 
-#if 1
-    long headerHeight = GetHeaderHeight();
-
-    for (unsigned int i = 0; i < m_children.size(); i++) {
-        Widget &child = m_children[i];
-        if (!child.isNull()) {
-            Rectangle tabpage_rect (GetTabPageBounds(i));
-/*            TabPage *tab_page = GetTabPage (i);
-            if (tab_page)
-                tab_page->SetPosSizePixel (0, 0, width, height, flags);*/
-
-            Rectangle tab_rect = GetTabBounds (i);
-//            headerHeight = tab_rect.GetSize().Height();
-
-//fprintf (stderr, "\theaderHeight: %ld\n", headerHeight);
-            child.SizeAllocate (0, headerHeight, width, height - headerHeight);
-        }
-    }
-
+void Notebook::ActivatePage()
+{
+fprintf (stderr, "Notebook::ActivatePage()\n");
+    TabControl::ActivatePage();
+    // we must delay 'activate' response because TabControl will still
+    // be processing important stuff
+    m_activateTimer.Start();
+}
 
-/*
-USHORT id = GetCurPageId();
-Rectangle r;
-r = GetTabPageBounds(id);
-fprintf (stderr, "\tGetTabPageBounds (%d): %ldx%ld , %ldx%ld\n", id, r.TopLeft().X(), r.TopLeft().Y(), r.GetSize().Width(), r.GetSize().Height());
-r = GetTabBounds(id);
-fprintf (stderr, "\tGetTabBounds (%d): %ldx%ld , %ldx%ld\n", id, r.TopLeft().X(), r.TopLeft().Y(), r.GetSize().Width(), r.GetSize().Height());
-*/
-#endif
+IMPL_LINK (Notebook, ActivateTimerHdl, void *, EMPTYARG)
+{
+    SyncChildSize();
+    return 0;
 }
 
 void Notebook::StateChanged (StateChangedType type)
 {
+fprintf (stderr, "Notebook::StateChanged (%d)\n", type);
     TabControl::StateChanged (type);
 
+    if (type == STATE_CHANGE_INITSHOW)
+        SyncChildSize();
+#if 0
     if (GetChildCount() > 0)
         SetCurPageId (0);
+#endif
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 63694c6f0e6740c3c0841607664cf2e6e9bd78ec
Author: Ricardo Cruz <rpmcruz at alunos.dcc.fc.up.pt>
Date:   Fri Dec 17 18:58:28 2010 +0000

    Fixed glitches/crash from the Layout introduction.

diff --git a/vcl/inc/vcl/align.hxx b/vcl/inc/vcl/align.hxx
index 90a7df9..6a3c226 100644
--- a/vcl/inc/vcl/align.hxx
+++ b/vcl/inc/vcl/align.hxx
@@ -43,11 +43,15 @@ public:
 
     virtual void SetBorderWidth (int borderWidth);
 
-    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
     virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
     virtual Rectangle GetAllocation() const { return m_allocation; }
 
+    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
+    virtual bool SupportsInvalidateSize() { return true; }
+
+    virtual const char *DebugName() const  { return "Align"; }
+
 protected:
     float m_xalign, m_yalign, m_xscale, m_yscale;
     int m_borderWidth;
diff --git a/vcl/inc/vcl/box.hxx b/vcl/inc/vcl/box.hxx
index 92bc1b1..c58c936 100644
--- a/vcl/inc/vcl/box.hxx
+++ b/vcl/inc/vcl/box.hxx
@@ -46,11 +46,16 @@ public:
 
     virtual void SetBorderWidth (int borderWidth);
 
-    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
     virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
     virtual Rectangle GetAllocation() const { return m_allocation; }
 
+    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
+    virtual bool SupportsInvalidateSize() { return true; }
+
+    virtual const char *DebugName() const
+    { return m_orientation ? "VBox" : "HBox"; }
+
 protected:
     Box (Orientation orientation, bool homogeneous, int spacing);
 
diff --git a/vcl/inc/vcl/buttonbox.hxx b/vcl/inc/vcl/buttonbox.hxx
index 0d14cad..05e91fd 100644
--- a/vcl/inc/vcl/buttonbox.hxx
+++ b/vcl/inc/vcl/buttonbox.hxx
@@ -46,6 +46,8 @@ public:
 
     virtual void SizeAllocate (long x, long y, long width, long height);
 
+    virtual const char *DebugName() const  { return "ButtonBox"; }
+
 protected:
     friend struct ChildOrder;
 
diff --git a/vcl/inc/vcl/layout.hxx b/vcl/inc/vcl/layout.hxx
index 694a823..3fe1c90 100644
--- a/vcl/inc/vcl/layout.hxx
+++ b/vcl/inc/vcl/layout.hxx
@@ -44,12 +44,12 @@ public:
     std::list <Widget> GetChildren() const;
     void SetParent (Widget &parent);
     void SetParent (Layout *layout);  // convenience
-    // use when Layout and Window parents must differ:
-    // FIXME: this will break down when introducing a new Window to a Layout direct child
+    // use when parenting a child under an internal Window:
     void SetParent (Widget &parent, Window *parent_window);
     Widget GetParent() const;
     bool IsChild (Widget &parent) const;
 
+    bool IsRealized() const;
     bool IsVisible() const;
     void ShowAll();
 
@@ -61,9 +61,10 @@ public:
     bool HasSizeChanged();
     Rectangle GetAllocation() const;
 
-//    bool operator == (Widget &other) const;
-    bool operator == (Widget other) const;
-    bool operator != (Widget &other) const;
+    const char *DebugName() const;
+
+    bool operator == (const Widget &other) const;
+    bool operator != (const Widget &other) const;
 
     static Widget NIL;
 
@@ -101,17 +102,23 @@ public:
 
     virtual void SetBorderWidth (int borderWidth) = 0;
 
-    // Optional optimization method: to speed up the layouting, you can
-    // return a cache for GetOptimalSize(), which you should clear when
-    // this method is called.
-
-    virtual void InvalidateSize() = 0;
+    // Size request calculation, and allocation.
+    // NOTE: if you implement Window, call SetPosSizePixel() on SizeAllocate()
 
     virtual Size SizeRequest() = 0;
     virtual void SizeAllocate (long x, long y, long width, long height) = 0;
-
     virtual Rectangle GetAllocation() const = 0;
 
+    // You should cache SizeRequest(), and clear the cache on InvalidateSize().
+    // If you don't want to do that, return false for the Supports method.
+
+    virtual void InvalidateSize() = 0;
+    virtual bool SupportsInvalidateSize() = 0;
+
+    // Debug:
+
+    virtual const char *DebugName() const = 0;
+
     // Internal method:
     // Call this method when the size of your widget or container may have
     // changed, to issue a layout recalculation order.
diff --git a/vcl/inc/vcl/ldialog.hxx b/vcl/inc/vcl/ldialog.hxx
index 4448e56..bf8cd61 100644
--- a/vcl/inc/vcl/ldialog.hxx
+++ b/vcl/inc/vcl/ldialog.hxx
@@ -28,7 +28,15 @@
 /* Use this top window when using the dynamic containers.
 */
 
-class VCL_DLLPUBLIC LDialog : public Dialog, Layout
+/* Whether to do a SizeAllocate() on the moment of Show(), or defer
+   it for when it gets to the event loop. */
+//#define USE_REALIZE_TIMER
+
+#ifdef USE_REALIZE_TIMER
+class Timer;
+#endif
+
+class VCL_DLLPUBLIC LDialog : public Dialog, public Layout
 {
 public:
     LDialog (Window *parent_dialog);
@@ -45,26 +53,36 @@ public:
     virtual std::list <Widget> GetChildren() const;
 
     virtual void SetParent (Widget &)  {}
-    virtual Widget GetParent() const  { return Widget (Window::GetParent()); }
+    virtual Widget GetParent() const  { return Widget::NIL; }
 
     virtual void SetBorderWidth (int borderWidth);  // refers to the inner border
 
-    virtual void InvalidateSize() {}
     virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
     virtual Rectangle GetAllocation() const
     { return Rectangle (GetPosPixel(), GetSizePixel()); }
 
+    virtual void InvalidateSize()  { m_requisition = Size(0, 0); }
+    virtual bool SupportsInvalidateSize()  { return true; }
+
+    virtual const char *DebugName() const  { return "LDialog"; }
+
     Size SizePreferred();
 
     virtual void StateChanged (StateChangedType type);
     virtual void Resize();
 
 protected:
+#ifdef USE_REALIZE_TIMER
+    DECL_LINK (RealizeTimerHdl, void *);
+    Timer *m_realizeTimer;
+#endif
+
     Widget m_child;
     int m_autoResize : 2;
     int m_borderWidth;
     long m_defaultWidth, m_defaultHeight;
+    Size m_requisition;
 };
 
 #endif /* VCL_LDIALOG_HXX */
diff --git a/vcl/inc/vcl/notebook.hxx b/vcl/inc/vcl/notebook.hxx
index 3fd2a1c..bef8f56 100644
--- a/vcl/inc/vcl/notebook.hxx
+++ b/vcl/inc/vcl/notebook.hxx
@@ -46,12 +46,16 @@ public:
 
     virtual void SetBorderWidth (int borderWidth);
 
-    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
     virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
     virtual Rectangle GetAllocation() const
     { return Rectangle (GetPosPixel(), GetSizePixel()); }
 
+    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
+    virtual bool SupportsInvalidateSize()  { return true; }
+
+    virtual const char *DebugName() const  { return "Notebook"; }
+
     virtual void StateChanged (StateChangedType type);
 
 protected:
diff --git a/vcl/inc/vcl/table.hxx b/vcl/inc/vcl/table.hxx
index 4bcfe28..4281c02 100644
--- a/vcl/inc/vcl/table.hxx
+++ b/vcl/inc/vcl/table.hxx
@@ -46,11 +46,15 @@ public:
 
     virtual void SetBorderWidth (int borderWidth);
 
-    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
     virtual Size SizeRequest();
     virtual void SizeAllocate (long x, long y, long width, long height);
     virtual Rectangle GetAllocation() const { return m_allocation; }
 
+    virtual void InvalidateSize()  { m_requisition = Size (0, 0); }
+    virtual bool SupportsInvalidateSize() { return true; }
+
+    virtual const char *DebugName() const  { return "Table"; }
+
 protected:
     void PackChild (Widget &widget, int rowSpan, int colSpan, bool rowExpand, bool colExpand);
 
diff --git a/vcl/source/layout/box.cxx b/vcl/source/layout/box.cxx
index d8cec23..99d1989 100644
--- a/vcl/source/layout/box.cxx
+++ b/vcl/source/layout/box.cxx
@@ -142,7 +142,6 @@ Size Box::SizeRequest()
                 reqSize.prim = SAL_MAX (reqSize.prim, reqChildSize.prim);
             else
                 reqSize.prim += reqChildSize.prim;
-fprintf (stderr, "\tprim size: %ld\n", reqSize.prim);
             reqSize.secun = SAL_MAX (reqSize.secun, reqChildSize.secun);
             visibleChildren++;
         }
@@ -150,7 +149,8 @@ fprintf (stderr, "\tprim size: %ld\n", reqSize.prim);
 
     if (m_homogeneous)
         reqSize.prim *= visibleChildren;
-    reqSize.prim += (visibleChildren-1) * m_spacing;
+    if (visibleChildren > 0)
+        reqSize.prim += (visibleChildren-1) * m_spacing;
     reqSize.prim += m_borderWidth * 2;
     reqSize.secun += m_borderWidth * 2;
 
@@ -159,7 +159,6 @@ fprintf (stderr, "\tprim size: %ld\n", reqSize.prim);
 
 void Box::SizeAllocate (long x, long y, long width, long height)
 {
-fprintf (stderr, "%cBox::SetPosSizePixel: %ldx%ld , %ldx%ld\n", m_orientation == HORIZONTAL ? 'H' : 'V', 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);
diff --git a/vcl/source/layout/layout.cxx b/vcl/source/layout/layout.cxx
index d8df330..d96fb82 100644
--- a/vcl/source/layout/layout.cxx
+++ b/vcl/source/layout/layout.cxx
@@ -25,149 +25,7 @@
 #include <vcl/window.hxx>
 #include <vcl/timer.hxx>
 
-#if 0
-
-// FIXME: we may want, in the future, to integrate this volatile
-// widget tree with the actual one
-
-struct DirtyWidget
-{
-    Window *window;
-    DirtyWidget *next, *child;
-
-    DirtyWidget (Window *window)
-    : window (window), next (NULL), child (NULL) {}
-
-    ~DirtyWidget()
-    { delete child; delete next; }
-
-    // FIXME: check if this function doesn't check only for parents,
-    // but also for grand-parents and so ...
-    bool IsParent (DirtyWidget *child)
-    { return child->IsChild (parent); }
-};
-
-struct DirtyTree
-{
-    DirtyWidget *root;
-
-    DirtyTree() : root (NULL) {}
-    ~DirtyTree() { delete root; }
-
-    void Add (Window *window)
-    { return Add (NULL, root, new DirtyWidget (window)); }
-
-    void Clear()
-    { delete root; root = NULL; }
-
-    // We pass parent as an argument, since we do not store it in
-    // the DirtyWidget structure
-
-    void Add (DirtyWidget *parent, DirtyWidget *node, DirtyWidget *widget)
-    {
-        if (!root)  // first entry
-        { root = widget; return; }
-        if (node->window == widget->window)  // already added
-        { delete widget; return; }
-
-        // For each nodes within this breath:
-        // 1. check if child
-        for (DirtyWidget *i = node; i; i = i->next)
-            if (i->IsParent (widget)) {
-                fprintf (stderr, "\tis child\n");
-                if (i->child)
-                    Add (i, i->child, widget);
-                else
-                    i->child = widget;
-                return;  // done: a widget can only be a child within a breath
-            }
-
-        // 2. not child: check if parent
-        for (DirtyWidget *i = node, *prev = 0; i; prev = i, i = i->next)
-            if (widget->IsParent (i)) {
-                fprintf (stderr, "\tis parent\n");
-                if (prev)
-                    prev->next = i->next;
-                else
-                    parent->child = i->next;
-
-                if (widget->child) {
-                    DirtyWidget *n = widget->child->next;
-                    i->next = n;
-                    widget->child = i;
-                }
-                else
-                    widget->child = i;
-                // loop must continue: a wigdet may have multiple children within a breath
-            }
-        if (widget->child) {
-            DirtyWidget *n = parent->child;
-            parent->child = widget;
-            widget->next = n;
-        }
-
-        // 3. not child or parent: must be sibling then
-        if (!widget->child) {
-            fprintf (stderr, "\tadded as sibling\n");
-            widget->next = node->next;
-            node->next = widget;  // widget order is irrelevant
-        }
-    }
-};
-
-struct LayoutProscratinator : public Timer
-{
-    DirtyTree *tree;
-
-    LayoutProscratinator() : tree (NULL)
-    {
-        SetTimeout (500);
-    }
-
-    void Add (Window *widget)
-    {
-        if (widget->IsVisible())
-            tree->Add (widget);
-    }
-
-    virtual void Timeout()
-    {
-        // 1. Check damage extent (whether parent size changed as well)
-        for (DirtyWidget *i = tree->root; i; i = i->next)
-            for (Window *p = i->window->GetParent(); p; p = p->GetParent()) {
-                bool sizeChanged = true;
-                Layout *layout = dynamic_cast <Layout *> (parent);
-                if (layout)
-                    sizeChanged = layout->HasSizeChanged();
-
-                if (sizeChanged)
-                    tree->Add (p);
-                else
-                    break;
-            }
-
-        // 2. Force re-allocate
-        for (DirtyWidget *i = tree->root; i; i = i->next) {
-            Point p = i->window->GetPosPixel();
-            Size s = i->window->GetSizePixel();
-            i->window->SetPosSizePixel (p, s);
-        }
-
-        tree->Clear();
-    }
-};
-
-#endif
-
-/*
-struct IsChildOf {
-    Window *m_parent;
-    IsChildOf (Window *parent) : m_parent (parent) {}
-
-    bool operator() (Window *child)
-    { return child->IsChild (m_parent); }
-};
-*/
+#define DEBUG_PROSCRATINATOR
 
 struct IsChildCmp {
     Widget m_child;
@@ -182,7 +40,7 @@ struct LayoutProscratinator : public Timer
     typedef std::list <Widget> WidgetList;
     WidgetList m_damaged;
 
-    LayoutProscratinator()
+    LayoutProscratinator() : Timer()
     {
         SetTimeout (500);
     }
@@ -190,6 +48,7 @@ struct LayoutProscratinator : public Timer
     void Add (Widget &widget)
     {
         if (!HasWidget (m_damaged, widget)) {
+fprintf (stderr, "QueueResize::Add (%s)\n", widget.DebugName());
             m_damaged.push_front (widget);
             Start();
         }
@@ -215,37 +74,39 @@ struct LayoutProscratinator : public Timer
         return dst;
     }
 
-    static Widget &GetTopWidgetChanged (Widget &w)
+    static Widget GetTopWidgetChanged (Widget &w)
     {
-        for (Widget p = w.GetParent();; w = p, p = p.GetParent())
+        for (Widget p = w.GetParent(); !p.isNull(); w = p, p = p.GetParent())
             if (!p.HasSizeChanged())
                 break;
         return w;
     }
 
-#if 0
-static void PrintList (const char *label, WidgetList &list)
-{
-    fprintf (stderr, "\tPrint %s list:\n", label);
-    for (WidgetList::iterator it = list.begin(); it != list.end(); it++)
-        fprintf (stderr, "\t\t%p\n", *it);
-}
+#ifdef DEBUG_PROSCRATINATOR
+    static void PrintList (const char *label, WidgetList &list)
+    {
+        fprintf (stderr, "%s printout\n", label);
+        for (WidgetList::iterator it = list.begin(); it != list.end(); it++)
+            fprintf (stderr, "\t%s\n", it->DebugName());
+    }
+#else
+    static inline void PrintList (const char *, WidgetList &) {}
 #endif
 
     virtual void Timeout()
     {
-//fprintf (stderr, "** Layout Timer Timeout **\n");
+        PrintList ("\nTimeout() - damaged", m_damaged);
         WidgetList affected, affected2;
 
-//PrintList ("m_damaged", m_damaged);
         // cut list to the top damaged widgets
         affected = GetParentWidgets (m_damaged);
-//PrintList ("affected", affected);
+        PrintList ("Timeout() - cut list", affected);
         for (WidgetList::iterator it = affected.begin(); it != affected.end(); it++)
             affected2.push_front (GetTopWidgetChanged (*it));
-//PrintList ("affected2", affected2);
+        PrintList ("Timeout() - affected extent", affected2);
+
         affected = GetParentWidgets (affected2);
-//PrintList ("affected", affected);
+        PrintList ("Timeout() - cut list", affected);
 
         // issue size re-allocations
         for (WidgetList::iterator it = affected.begin(); it != affected.end(); it++) {
@@ -259,7 +120,8 @@ static void PrintList (const char *label, WidgetList &list)
 
 void Layout::QueueResize (Widget &widget)
 {
-    if (widget.IsVisible()) {
+    if (widget.IsRealized() && widget.IsVisible()) {
+fprintf (stderr, "** adding child to queue resize\n");
         static LayoutProscratinator timer;
         timer.Add (widget);
     }
@@ -316,8 +178,6 @@ void Widget::SetParent (Layout *layout)
 
 void Widget::SetParent (Widget &parent, Window *parent_window)
 {
-    // FIXME: see message in layout.hxx
-
     if (parent_window)
         SetParentWindow (parent_window);
     if (m_layout)
@@ -352,7 +212,10 @@ Widget Widget::GetParent() const
 {
     if (m_layout)
         return m_layout->GetParent();
-    return Widget (m_window->GetParent());
+    Window *parent = m_window->GetParent();
+    if (parent)
+        return Widget (parent);
+    return Widget::NIL;
 }
 
 bool Widget::IsChild (Widget &parent) const
@@ -363,6 +226,17 @@ bool Widget::IsChild (Widget &parent) const
     return false;
 }
 
+bool Widget::IsRealized() const
+{
+    if (m_layout) {
+        Rectangle r (m_layout->GetAllocation());
+        return r.GetWidth() != 0 || r.GetHeight() != 0;
+    }
+    if (m_window)
+        return m_window->IsReallyVisible();
+    return true;
+}
+
 bool Widget::IsVisible() const
 {
     if (m_window)
@@ -381,8 +255,6 @@ void Widget::ShowAll()
 
 void Widget::Foreach (Widget::ForeachCallback callback)
 {
-    callback (*this);
-
     if (m_layout) {
         std::list <Widget> children (m_layout->GetChildren());
         for (std::list <Widget>::iterator it = children.begin();
@@ -395,10 +267,13 @@ void Widget::Foreach (Widget::ForeachCallback callback)
             callback (child);
         }
     }
+
+    callback (*this);
 }
 
 Size Widget::SizeRequest()
 {
+//fprintf (stderr, "%s::SizeRequest()\n", DebugName(), x, y, width, height);
     if (m_layout)
         return m_layout->SizeRequest();
     return m_window->GetOptimalSize (WINDOWSIZE_PREFERRED);
@@ -406,6 +281,7 @@ Size Widget::SizeRequest()
 
 void Widget::SizeAllocate (long x, long y, long width, long height)
 {
+fprintf (stderr, "%s::SizeAllocate: %ld,%ld x %ld,%ld \n", DebugName(), x, y, width, height);
     if (m_layout)
         return m_layout->SizeAllocate (x, y, width, height);
     return m_window->SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
@@ -422,13 +298,13 @@ void Widget::InvalidateSize()
 
 bool Widget::HasSizeChanged()
 {
-    if (m_layout) {
+    if (m_layout && m_layout->SupportsInvalidateSize()) {
         Size oldSize (m_layout->SizeRequest());
         m_layout->InvalidateSize();
         Size newSize (m_layout->SizeRequest());
         return oldSize != newSize;
     }
-    return false;
+    return true;
 }
 
 Rectangle Widget::GetAllocation() const
@@ -440,13 +316,19 @@ Rectangle Widget::GetAllocation() const
     return Rectangle();
 }
 
-/*bool Widget::operator == (Widget &other) const
-{ return this->m_window == other.m_window && this->m_layout == other.m_layout; }
-*/
-bool Widget::operator == (Widget other) const
+const char *Widget::DebugName() const
+{
+    if (m_layout)
+        return m_layout->DebugName();
+    if (m_window)
+        return "Window";
+    return "NIL";
+}
+
+bool Widget::operator == (const Widget &other) const
 { return this->m_window == other.m_window && this->m_layout == other.m_layout; }
 
-bool Widget::operator != (Widget &other) const
+bool Widget::operator != (const Widget &other) const
 { return this->m_window != other.m_window || this->m_layout != other.m_layout; }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/layout/ldialog.cxx b/vcl/source/layout/ldialog.cxx
index 164276b..68753a2 100644
--- a/vcl/source/layout/ldialog.cxx
+++ b/vcl/source/layout/ldialog.cxx
@@ -22,6 +22,9 @@
 #include "precompiled_vcl.hxx"
 
 #include <vcl/ldialog.hxx>
+#ifdef USE_REALIZE_TIMER
+#include <vcl/timer.hxx>
+#endif
 
 #define WB_LDIALOG (WB_STDDIALOG | WB_SIZEABLE)
 
@@ -68,6 +71,9 @@ void LDialog::SetBorderWidth (int borderWidth)
 
 Size LDialog::SizeRequest()
 {
+    if (m_requisition.Width() != 0 && m_requisition.Height() != 0)
+        return m_requisition;
+
     Size childReq;
     if (!m_child.isNull())
         childReq = m_child.SizeRequest();
@@ -77,7 +83,7 @@ Size LDialog::SizeRequest()
 
     SetMinOutputSizePixel (req);
     SetMaxOutputSizePixel (Size (LONG_MAX, LONG_MAX));
-    return req;
+    return (m_requisition = req);
 }
 
 Size LDialog::SizePreferred()
@@ -90,6 +96,9 @@ Size LDialog::SizePreferred()
 
 void LDialog::SizeAllocate (long, long, long width, long height)
 {
+    m_autoResize = true;
+    Window::SetPosSizePixel (0, 0, width, height, WINDOW_POSSIZE_SIZE);
+
     if (!m_child.isNull())
         m_child.SizeAllocate (m_borderWidth, m_borderWidth,
             width - m_borderWidth*2, height - m_borderWidth*2);
@@ -100,34 +109,35 @@ void LDialog::StateChanged (StateChangedType type)
     Dialog::StateChanged (type);
 
     if (type == STATE_CHANGE_INITSHOW) {
-fprintf (stderr, "** INITSHOW\n");
-        m_autoResize = true;
-        SetSizePixel (SizePreferred());
-    }
-
-#if 0
-fprintf (stderr, "LDialog::StateChanged: %d\n", type);
-    if (type == STATE_CHANGE_INITSHOW) {
-        // on realize, show window with the desired size
-        m_resizeSafeguard = true;
-        SetSizePixel (GetOptimalSize (WINDOWSIZE_PREFERRED));
-        m_resizeSafeguard = false;
-    }
+#ifdef USE_REALIZE_TIMER
+        m_realizeTimer = new Timer();
+        m_realizeTimer->SetTimeoutHdl (LINK (this, LDialog, RealizeTimerHdl));
+        m_realizeTimer->SetTimeout (20);
+        m_realizeTimer->Start();
+#else
+        Size size (SizePreferred());
+        SizeAllocate (0, 0, size.Width(), size.Height());
 #endif
+    }
 }
 
 void LDialog::Resize()
 {
-fprintf (stderr, "LDialog::Resize\n");
     Dialog::Resize();
 
-    if (!m_autoResize) {
-fprintf (stderr, "\tqueue resize\n");
+    if (!m_autoResize)
         QueueResize (this, this);
-    }
-    else
-        fprintf (stderr, "\tignore\n");
     m_autoResize = false;
 }
 
+#ifdef USE_REALIZE_TIMER
+IMPL_LINK (LDialog, RealizeTimerHdl, void *, EMPTYARG)
+{
+    Size size (SizePreferred());
+    SizeAllocate (0, 0, size.Width(), size.Height());
+    delete m_realizeTimer;
+    return 0;
+}
+#endif
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/layout/notebook.cxx b/vcl/source/layout/notebook.cxx
index 6d982d3..621742d 100644
--- a/vcl/source/layout/notebook.cxx
+++ b/vcl/source/layout/notebook.cxx
@@ -129,7 +129,7 @@ void Notebook::SizeAllocate (long x, long y, long width, long height)
 {
     x += m_borderWidth; y += m_borderWidth;
     width -= m_borderWidth*2; height -= m_borderWidth*2;
-    SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
+    Window::SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
 
 #if 1
     long headerHeight = GetHeaderHeight();
@@ -145,19 +145,20 @@ void Notebook::SizeAllocate (long x, long y, long width, long height)
             Rectangle tab_rect = GetTabBounds (i);
 //            headerHeight = tab_rect.GetSize().Height();
 
-fprintf (stderr, "\theaderHeight: %ld\n", headerHeight);
+//fprintf (stderr, "\theaderHeight: %ld\n", headerHeight);
             child.SizeAllocate (0, headerHeight, width, height - headerHeight);
         }
     }
 
 
-
+/*
 USHORT id = GetCurPageId();
 Rectangle r;
 r = GetTabPageBounds(id);
 fprintf (stderr, "\tGetTabPageBounds (%d): %ldx%ld , %ldx%ld\n", id, r.TopLeft().X(), r.TopLeft().Y(), r.GetSize().Width(), r.GetSize().Height());
 r = GetTabBounds(id);
 fprintf (stderr, "\tGetTabBounds (%d): %ldx%ld , %ldx%ld\n", id, r.TopLeft().X(), r.TopLeft().Y(), r.GetSize().Width(), r.GetSize().Height());
+*/
 #endif
 }
 


More information about the Libreoffice-commits mailing list