[Libreoffice-commits] .: Branch 'feature/layout' - README.layout vcl/inc vcl/source
Ricardo Cruz
rpmcruz at kemper.freedesktop.org
Sun Dec 19 12:36:50 PST 2010
README.layout | 47 ++++++++++-
vcl/inc/vcl/ldialog.hxx | 10 +-
vcl/inc/vcl/notebook.hxx | 9 +-
vcl/inc/vcl/table.hxx | 17 +---
vcl/source/layout/align.cxx | 2
vcl/source/layout/box.cxx | 6 -
vcl/source/layout/buttonbox.cxx | 2
vcl/source/layout/layout.cxx | 43 ++++++----
vcl/source/layout/ldialog.cxx | 52 +++++++++----
vcl/source/layout/notebook.cxx | 7 +
vcl/source/layout/table.cxx | 158 +++++++++++++++++++++++++++-------------
11 files changed, 240 insertions(+), 113 deletions(-)
New commits:
commit fe5298f347de53f489a786a6f3dc078b4c5ff8fa
Author: Ricardo Cruz <rpmcruz at alunos.dcc.fc.up.pt>
Date: Sun Dec 19 20:35:21 2010 +0000
Fixed LDialog layout bugs | Improved Table: better space use by multi-span...
diff --git a/README.layout b/README.layout
index ae85721..6eaa501 100644
--- a/README.layout
+++ b/README.layout
@@ -1,4 +1,33 @@
-~ TODO ~
+OVERVIEW -=-=-=-=-=-=-=-=-=
+
+Welcome to the feature/layout branch!
+
+The idea here is to introduce logic layout containers
+(ie. Boxes, Tables) to VCL, so that we no longer need
+to manually place widgets using absolute coordinates.
+
+There are a few advantages to that approach. But mostly
+it makes it easier to re-design libreoffice dialogs.
+Especially once we introduce a XML parser and an UI editor.
+
+There was already a first attempt at this. That code is
+under toolkit/source/layout. What's new here is that we
+will be re-implementing this one at the VCL level, which
+should hopefully make it much easier to integrate with the
+existing dialogs.
+
+COMPILING -=-=-=-=-=-=-=-=-=
+
+Run the following, from a working build:
+
+./g checkout feature/layout
+./g pull -r
+make
+
+To get a working build, consult:
+http://www.documentfoundation.org/develop/
+
+TODO: Dynamic layout -=-=-=-=-=-=-=-=-=
* Make Window an implementation of a Layout (or Widget?)
interface. Notice that Window and Layout use different
@@ -14,8 +43,11 @@
* Announcement: try to get people to
do some dialog porting.
+TODO: Desktop integration -=-=-=-=-=-=-=-=-=
-~ TODO: side adventures ~
+These points aren't crucial for the main effort, but it would
+be nice to get these points addressed, and they should be fairly
+trivial nevertheless.
* Integration code should return a ButtonOrder with the
appropriate spec (see buttonbox.hxx)
@@ -28,9 +60,14 @@
bold font for the selected tab page: replace that by
gray-ing out the inactive tabs. Offset inactive tab label
content if we aren't doing that already.
-
-
-~ HACKING HOWTO ~
+* Buttons flicker quite a bit on focus-in and focus-out.
+* Button: shouldn't be possible to create an instance of
+ this base class: only of PushButton or whatever. The
+ names are too similar and you can easily use Button
+ by mistake, and only notice the mistake on run-time, not
+ while compiling.
+
+HACKING -=-=-=-=-=-=-=-=-=
Some information about the vcl layout code. Useful for both
people who want to hack on it, or with it.
diff --git a/vcl/inc/vcl/ldialog.hxx b/vcl/inc/vcl/ldialog.hxx
index bf8cd61..3f7de97 100644
--- a/vcl/inc/vcl/ldialog.hxx
+++ b/vcl/inc/vcl/ldialog.hxx
@@ -59,8 +59,7 @@ public:
virtual Size SizeRequest();
virtual void SizeAllocate (long x, long y, long width, long height);
- virtual Rectangle GetAllocation() const
- { return Rectangle (GetPosPixel(), GetSizePixel()); }
+ virtual Rectangle GetAllocation() const { return Rectangle (Point(0,0), m_allocation); }
virtual void InvalidateSize() { m_requisition = Size(0, 0); }
virtual bool SupportsInvalidateSize() { return true; }
@@ -77,12 +76,15 @@ protected:
DECL_LINK (RealizeTimerHdl, void *);
Timer *m_realizeTimer;
#endif
+ void Realize();
+ void _SizeAllocate (long width, long height);
Widget m_child;
- int m_autoResize : 2;
+ int m_myResize : 2;
int m_borderWidth;
long m_defaultWidth, m_defaultHeight;
- Size m_requisition;
+ Size m_requisition, m_allocation;
+ // let's keep allocation size, because GetSizePixel() seems to cut size by 1px
};
#endif /* VCL_LDIALOG_HXX */
diff --git a/vcl/inc/vcl/notebook.hxx b/vcl/inc/vcl/notebook.hxx
index 17d69b3..6d0baae 100644
--- a/vcl/inc/vcl/notebook.hxx
+++ b/vcl/inc/vcl/notebook.hxx
@@ -42,15 +42,14 @@ public:
virtual void RemoveChild (Widget &child);
virtual std::list <Widget> GetChildren() const;
- virtual void SetParent (Widget &) {}
- virtual Widget GetParent() const { return Widget (Window::GetParent()); }
+ 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 Rectangle (GetPosPixel(), GetSizePixel()); }
+ virtual Rectangle GetAllocation() const { return m_allocation; }
virtual void InvalidateSize() { m_requisition = Size (0, 0); }
virtual bool SupportsInvalidateSize() { return true; }
@@ -70,6 +69,8 @@ protected:
int m_borderWidth;
std::vector <Widget> m_children;
Size m_requisition;
+ Rectangle m_allocation;
+ Widget m_parent;
};
#endif /* VCL_NOTEBOOK_HXX */
diff --git a/vcl/inc/vcl/table.hxx b/vcl/inc/vcl/table.hxx
index f1522d9..8481f03 100644
--- a/vcl/inc/vcl/table.hxx
+++ b/vcl/inc/vcl/table.hxx
@@ -61,31 +61,28 @@ public:
protected:
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);
+ void SumReqSize (int first[], int last[], long extra[], long reqSize[]);
struct ChildData {
ChildData (Widget &child, int left, int right, int top, int bottom, bool xexpand, bool yexpand);
Widget widget;
- int left, right, top, bottom;
- int xexpand : 2, yexpand : 2;
+ int first[2], last[2];
+ bool expand[2];
};
friend struct CmpChild;
- struct GroupData {
+ struct DimData {
int expand : 2;
long reqSize;
-
- GroupData() : expand (false), reqSize (0) {}
};
std::list <ChildData> m_children;
- std::vector <GroupData> m_cols, m_rows;
- int m_colsExpand, m_rowsExpand;
+ std::vector <DimData> m_dim[2];
+ int m_expand[2];
int m_colsNb, m_rowsNb;
- int m_borderWidth, m_xspacing, m_yspacing;
+ int m_borderWidth, m_spacing[2];
Size m_requisition;
Rectangle m_allocation;
diff --git a/vcl/source/layout/align.cxx b/vcl/source/layout/align.cxx
index 6ed54ae..9226c16 100644
--- a/vcl/source/layout/align.cxx
+++ b/vcl/source/layout/align.cxx
@@ -24,7 +24,7 @@
#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_minWidth (0), m_minHeight(0), m_maxWidth (LONG_MAX), m_maxHeight (LONG_MAX), 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_allocation (Rectangle(0,0,0,0)), m_parent (Widget::NIL), m_child (Widget::NIL)
{}
void Align::SetMinSize (long minWidth, long minHeight)
diff --git a/vcl/source/layout/box.cxx b/vcl/source/layout/box.cxx
index d17024f..70be531 100644
--- a/vcl/source/layout/box.cxx
+++ b/vcl/source/layout/box.cxx
@@ -36,7 +36,7 @@ Box::ChildData::ChildData (Widget &w, bool e, bool f)
{}
Box::Box (Orientation orientation, bool homogeneous, int spacing)
-: m_orientation (orientation), m_homogeneous (homogeneous), m_spacing (spacing), m_borderWidth (0), m_parent (Widget::NIL)
+: m_orientation (orientation), m_homogeneous (homogeneous), m_spacing (spacing), m_borderWidth (0), m_allocation (Rectangle(0,0,0,0)), m_parent (Widget::NIL)
{}
void Box::Pack (Widget &child, bool expand, bool fill)
@@ -180,10 +180,8 @@ 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/buttonbox.cxx b/vcl/source/layout/buttonbox.cxx
index 48e1946..eadb3e4 100644
--- a/vcl/source/layout/buttonbox.cxx
+++ b/vcl/source/layout/buttonbox.cxx
@@ -76,7 +76,7 @@ ButtonBox::ChildData::ChildData (Widget &b, ButtonRole r)
{}
ButtonBox::ButtonBox()
-: m_borderWidth (0), m_parent (Widget::NIL)
+: m_borderWidth (0), m_allocation (Rectangle(0,0,0,0)), m_parent (Widget::NIL)
{
static DefaultButtonOrder order;
m_buttonOrder = ℴ
diff --git a/vcl/source/layout/layout.cxx b/vcl/source/layout/layout.cxx
index 983fca3..91a3c5e 100644
--- a/vcl/source/layout/layout.cxx
+++ b/vcl/source/layout/layout.cxx
@@ -42,13 +42,13 @@ struct LayoutProscratinator : public Timer
LayoutProscratinator() : Timer()
{
- SetTimeout (0);
+ SetTimeout (50);
}
void Add (Widget &widget)
{
if (!HasWidget (m_damaged, widget)) {
-fprintf (stderr, "QueueResize::Add (%s)\n", widget.DebugName());
+fprintf (stderr, "** QueueResize::Add (%s)\n", widget.DebugName());
m_damaged.push_front (widget);
Start();
}
@@ -78,12 +78,11 @@ fprintf (stderr, "QueueResize::Add (%s)\n", widget.DebugName());
{
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())
+ for (Widget p = w.GetParent(); !p.isNull(); ret = p, p = p.GetParent()) {
+ bool parentSizeChanged = p.HasSizeChanged();
+ if (!parentSizeChanged)
break;
-}
+ }
return ret;
}
@@ -216,15 +215,27 @@ Widget Widget::GetParent() const
{
if (m_layout)
return m_layout->GetParent();
- Window *parent = m_window->GetParent();
- if (parent)
- return Widget (parent);
+ if (m_window) {
+#if 1
+ // take only Layout types as parents.
+ // doesn't work perfectly though: should iterate down
+ // to make sure it didn't miss any Layout-pure parent.
+
+ Window *parent;
+ while ((parent = m_window->GetParent()))
+ if (dynamic_cast <Layout *> (parent))
+ return Widget (parent);
+ return Widget::NIL;
+#else
+ return Widget (m_window->GetParent());
+#endif
+ }
return Widget::NIL;
}
bool Widget::IsChild (Widget &parent) const
{
- for (Widget p = GetParent(); p != Widget::NIL; p = p.GetParent())
+ for (Widget p = GetParent(); !p.isNull(); p = p.GetParent())
if (p == parent)
return true;
return false;
@@ -234,7 +245,7 @@ bool Widget::IsRealized() const
{
if (m_layout) {
Rectangle r (m_layout->GetAllocation());
- return r.GetWidth() != 0 || r.GetHeight() != 0;
+ return r.getWidth() != 0 || r.getHeight() != 0;
}
if (m_window)
return m_window->IsReallyVisible();
@@ -320,10 +331,10 @@ fprintf (stderr, "%s::HasSizeChanged() - old size: %ld x %ld , new size: %ld x %
Rectangle Widget::GetAllocation() const
{
- if (m_window)
- return Rectangle (m_window->GetPosPixel(), m_window->GetSizePixel());
if (m_layout)
return m_layout->GetAllocation();
+ if (m_window)
+ return Rectangle (m_window->GetPosPixel(), m_window->GetSizePixel());
return Rectangle();
}
@@ -332,8 +343,8 @@ const char *Widget::DebugName() const
if (m_layout)
return m_layout->DebugName();
if (m_window)
- return "Window";
- return "NIL";
+ return "(Window)";
+ return "(NIL)";
}
bool Widget::operator == (const Widget &other) const
diff --git a/vcl/source/layout/ldialog.cxx b/vcl/source/layout/ldialog.cxx
index 859778b..c97fd7b 100644
--- a/vcl/source/layout/ldialog.cxx
+++ b/vcl/source/layout/ldialog.cxx
@@ -29,11 +29,11 @@
#define WB_LDIALOG (WB_STDDIALOG | WB_SIZEABLE)
LDialog::LDialog (Window *parent_dialog)
-: Dialog (parent_dialog, WB_LDIALOG), m_child (Widget::NIL), m_autoResize (1), m_borderWidth (0), m_defaultWidth (0), m_defaultHeight (0)
+: Dialog (parent_dialog, WB_LDIALOG), m_child (Widget::NIL), m_myResize (1), m_borderWidth (0), m_defaultWidth (0), m_defaultHeight (0)
{}
LDialog::LDialog()
-: Dialog (DIALOG_NO_PARENT, WB_LDIALOG), m_child (Widget::NIL), m_autoResize (1), m_borderWidth (0), m_defaultWidth (0), m_defaultHeight (0)
+: Dialog (DIALOG_NO_PARENT, WB_LDIALOG), m_child (Widget::NIL), m_myResize (1), m_borderWidth (0), m_defaultWidth (0), m_defaultHeight (0)
{}
void LDialog::SetDefaultSize (long width, long height)
@@ -41,7 +41,6 @@ void LDialog::SetDefaultSize (long width, long height)
void LDialog::AddChild (Widget &child)
{
-fprintf (stderr, "LDialog::AddChild (%s)\n", child.DebugName());
m_child = child;
child.SetParent (this);
QueueResize (this, this);
@@ -98,14 +97,41 @@ Size LDialog::SizePreferred()
return req;
}
-void LDialog::SizeAllocate (long, long, long width, long height)
+void LDialog::_SizeAllocate (long width, long height)
{
- m_autoResize = true;
- Window::SetPosSizePixel (0, 0, width, height, WINDOW_POSSIZE_SIZE);
+ Size curSize (GetSizePixel()); // GetOutputSizePixel() or GetResizeOutputSizePixel() ?
+
+ // ensure it shows new req-size
+ width = SAL_MAX (width, m_requisition.Width());
+ height = SAL_MAX (height, m_requisition.Height());
+
+ Size newSize (width, height);
+ if (curSize != newSize) {
+ m_myResize = true;
+ SetSizePixel (newSize);
+ }
+ m_allocation = newSize;
if (!m_child.isNull())
m_child.SizeAllocate (m_borderWidth, m_borderWidth,
width - m_borderWidth*2, height - m_borderWidth*2);
+
+}
+
+void LDialog::SizeAllocate (long, long, long, long)
+{
+ // This would look much better if we'd return GetSizePixel()
+ // on Layout::GetAllocation(), but that Window method seems
+ // to return a different value between calls.
+ Size curSize (GetSizePixel());
+ _SizeAllocate (curSize.Width(), curSize.Height());
+}
+
+void LDialog::Realize()
+{
+ // dialog starts with some given size: use _SizeAllocate()
+ Size size (SizePreferred());
+ _SizeAllocate (size.Width(), size.Height());
}
void LDialog::StateChanged (StateChangedType type)
@@ -113,15 +139,13 @@ 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));
m_realizeTimer->SetTimeout (20);
m_realizeTimer->Start();
#else
- Size size (SizePreferred());
- SizeAllocate (0, 0, size.Width(), size.Height());
+ Realize();
#endif
}
}
@@ -129,19 +153,15 @@ fprintf (stderr, "LDialog::StateChanged: INITSHOW\n");
void LDialog::Resize()
{
Dialog::Resize();
-if (!m_autoResize)
-fprintf (stderr, "LDialog::Resize - not auto\n");
-
- if (!m_autoResize)
+ if (!m_myResize)
QueueResize (this, this);
- m_autoResize = false;
+ m_myResize = false;
}
#ifdef USE_REALIZE_TIMER
IMPL_LINK (LDialog, RealizeTimerHdl, void *, EMPTYARG)
{
- Size size (SizePreferred());
- SizeAllocate (0, 0, size.Width(), size.Height());
+ Realize();
delete m_realizeTimer;
return 0;
}
diff --git a/vcl/source/layout/notebook.cxx b/vcl/source/layout/notebook.cxx
index e94d021..8932180 100644
--- a/vcl/source/layout/notebook.cxx
+++ b/vcl/source/layout/notebook.cxx
@@ -33,7 +33,7 @@ struct CmpChild {
};
Notebook::Notebook (Window *parent)
-: TabControl (parent), m_borderWidth (0)
+: TabControl (parent), m_borderWidth (0), m_allocation (Rectangle(0,0,0,0)), m_parent (Widget::NIL)
{
m_children.reserve (8);
@@ -136,9 +136,12 @@ void Notebook::SyncChildSize()
void Notebook::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;
- Window::SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
+
+ if (GetPosPixel() != Point (x, y) || GetSizePixel() != Size (width, height))
+ SetPosSizePixel (x, y, width, height, WINDOW_POSSIZE_ALL);
SyncChildSize();
}
diff --git a/vcl/source/layout/table.cxx b/vcl/source/layout/table.cxx
index 83d2a9f..1505626 100644
--- a/vcl/source/layout/table.cxx
+++ b/vcl/source/layout/table.cxx
@@ -22,6 +22,8 @@
#include "precompiled_vcl.hxx"
#include <vcl/table.hxx>
+#define COL 0
+#define ROW 1
struct CmpChild {
Widget m_child;
@@ -31,16 +33,23 @@ struct CmpChild {
{ return childData.widget == m_child; }
};
-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::ChildData::ChildData (Widget &w, int left, int right, int top, int bottom, bool xexpand, bool yexpand)
+: widget (w)
+{
+ first[COL] = left;
+ last[COL] = right;
+ first[ROW] = top;
+ last[ROW] = bottom;
+ expand[COL] = xexpand;
+ expand[ROW] = yexpand;
+}
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_colsNb (cols), m_rowsNb (rows), m_borderWidth (0), m_allocation (Rectangle(0,0,0,0)), m_parent (Widget::NIL)
{
- m_cols.resize (cols);
- m_rows.resize (rows);
+ m_spacing[COL] = 0; m_spacing[ROW] = 0;
+ m_dim[COL].resize (cols);
+ m_dim[ROW].resize (rows);
}
void Table::Attach (Widget &child, int left, int right, int top, int bottom,
@@ -68,12 +77,13 @@ void Table::Attach (Layout *child, int left, int right, int top, int bottom,
void Table::SetSpacings (int xspacing, int yspacing)
{
- m_xspacing = xspacing; m_yspacing = yspacing;
+ m_spacing[COL] = xspacing; m_spacing[ROW] = yspacing;
QueueResize (this);
}
void Table::AddChild (Widget &child)
{
+ // this won't work if the table hasn't been built linearly
int left = m_children.size() % m_colsNb;
int top = m_children.size() / m_rowsNb;
Attach (child, left, left+1, top, top+1, false, false);
@@ -107,14 +117,64 @@ Size Table::SizeRequest()
return m_requisition;
// 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; }
-
- // 2. divide children req-size through the rows and cols they occupy
+ for (int dim = 0; dim < 2; dim++)
+ for (std::vector <DimData>::iterator it = m_dim[dim].begin();
+ it != m_dim[dim].end(); it++)
+ { it->expand = false; it->reqSize = 0; }
+
+ // 2. calculate cols and rows req-sizes to support one-span children
+ m_expand[COL] = 0; m_expand[ROW] = 0;
+ for (std::list <ChildData>::iterator it = m_children.begin();
+ it != m_children.end(); it++) {
+ Size childSize (it->widget.SizeRequest());
+ for (int dim = 0; dim < 2; dim++) {
+ if (it->last[dim] - it->first[dim] == 1) {
+ DimData &d = m_dim[dim][it->first[dim]];
+ long childDim = (dim == 0) ? childSize.Width() : childSize.Height();
+ d.reqSize = SAL_MAX (d.reqSize, childDim);
+ if (it->expand[dim] && !d.expand) {
+ d.expand = true;
+ m_expand[dim]++;
+ }
+ }
+ }
+ }
+
+ // 3. now, do the same for multi-span columns
+ // note: we could have done this in the previous step, but we want
+ // to minimize the req-size of the cols and rows
+ for (std::list <ChildData>::iterator it = m_children.begin();
+ it != m_children.end(); it++) {
+ Size childSize (it->widget.SizeRequest());
+ for (int dim = 0; dim < 2; dim++) {
+ int span = it->last[dim] - it->first[dim];
+ if (span > 1) {
+ int n_expand = 0;
+ for (int i = it->first[dim]; i < it->last[dim]; i++)
+ if (m_dim[dim][i].expand)
+ n_expand++;
+
+ int len = (n_expand == 0) ? span : n_expand;
+ long childDim = (dim == 0) ? childSize.Width() : childSize.Height();
+ // if no col/row is set to expand, and child is, rectify
+ bool rectifyExpand = (n_expand == 0 && it->expand[dim]);
+
+ for (int i = it->first[dim]; i < it->last[dim]; i++) {
+ DimData &d = m_dim[dim][i];
+ if (n_expand == 0 || d.expand)
+ d.reqSize = SAL_MAX (d.reqSize, childDim / len);
+ if (rectifyExpand)
+ d.expand = true;
+ }
+ if (rectifyExpand)
+ m_expand[dim] += span;
+ }
+ }
+ }
+
+
+
+#if 0
m_colsExpand = 0; m_rowsExpand = 0;
for (std::list <ChildData>::iterator it = m_children.begin();
it != m_children.end(); it++) {
@@ -139,43 +199,41 @@ Size Table::SizeRequest()
}
}
}
+#endif
- // 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;
+ // 4. sum everything up
+ int table[4] = { 0, 0, m_colsNb, m_rowsNb };
+ long extra[2] = { 0 }, size[2];
+ SumReqSize (table, table+2, extra, size);
+ size[COL] += m_borderWidth * 2;
+ size[ROW] += m_borderWidth * 2;
- return (m_requisition = Size (width, height));
+ return (m_requisition = Size (size[COL], size[ROW]));
}
-void Table::GetReqSize (int left, int right, int top, int bottom, long extraWidth, long extraHeight, long *width, long *height)
+void Table::SumReqSize (int first[], int last[], long extra[], long reqSize[])
{
- *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 (int i = top; i < bottom; i++) {
- GroupData &r = m_rows[i];
- *height += r.reqSize;
- if (r.expand) *height += extraHeight;
+ reqSize[COL] = 0; reqSize[ROW] = 0;
+ for (int dim = 0; dim < 2; dim++) {
+ for (int i = first[dim]; i < last[dim]; i++) {
+ DimData &d = m_dim[dim][i];
+ reqSize[dim] += d.reqSize;
+ if (d.expand)
+ reqSize[dim] += extra[dim];
+ }
+ int span = last[dim] - first[dim];
+ if (span > 1)
+ reqSize[dim] += m_spacing[dim] * (span-1);
}
- 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;
+ long extraSize[2] = { 0 };
+ if (m_expand[COL] > 0)
+ extraSize[COL] = (width - m_requisition.Width()) / m_expand[COL];
+ if (m_expand[ROW] > 0)
+ extraSize[ROW] = (height - m_requisition.Height()) / m_expand[ROW];
m_allocation = Rectangle (x, y, width, height);
x += m_borderWidth; y += m_borderWidth;
@@ -186,14 +244,14 @@ void Table::SizeAllocate (long x, long y, long width, long height)
it != m_children.end(); it++) {
ChildData &child = *it;
- 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;
+ long childPos[2], childSize[2];
+ int bounds[4] = { 0, 0, child.first[COL], child.first[ROW] };
+ SumReqSize (bounds, bounds+2, extraSize, childPos);
+ SumReqSize (child.first, child.last, extraSize, childSize);
+ if (child.first[COL] > 0) childPos[COL] += m_spacing[COL];
+ if (child.first[ROW] > 0) childPos[ROW] += m_spacing[ROW];
- child.widget.SizeAllocate (x + childX, y + childY, childWidth, childHeight);
+ child.widget.SizeAllocate (x + childPos[0], y + childPos[1], childSize[0], childSize[1]);
}
}
More information about the Libreoffice-commits
mailing list