aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-12-22 14:59:02 +0100
committerSebastian Geerken <devnull@localhost>2014-12-22 14:59:02 +0100
commit1162688e7720815b17cc6b85033ec5b63eb6440e (patch)
treed8ca3b1c43b7155c19f9e2470fae469fdf78824f /dw
parent424a01ce5c2dd3cadd3d7ca60c7b43283c183b02 (diff)
(Absolute) positions: distinguish between container (= parent widget) and reference widget.
Diffstat (limited to 'dw')
-rw-r--r--dw/oofawarewidget.cc11
-rw-r--r--dw/oofposabsmgr.cc14
-rw-r--r--dw/oofposabsmgr.hh1
-rw-r--r--dw/oofposfixedmgr.cc4
-rw-r--r--dw/oofposfixedmgr.hh1
-rw-r--r--dw/oofpositionedmgr.cc161
-rw-r--r--dw/oofpositionedmgr.hh19
7 files changed, 135 insertions, 76 deletions
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index ff04a642..a1901210 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -195,13 +195,10 @@ bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex)
testWidgetOutOfFlow (widget)));
case OOFM_ABSOLUTE:
- // Only the toplevel widget (as for all) as well as absolutely,
- // relatively, and fixedly positioned elements constitute the
- // containing block for absolutely positioned elements, but
- // neither floats nor other elements like table cells, or
- // elements with 'overview' set to another value than 'visible'.
- return widget->instanceOf (OOFAwareWidget::CLASS_ID) &&
- (widget->getParent() == NULL || testWidgetPositioned (widget));
+ // We use the toplevel widget as container, i. e. parent widget.
+ // See also OOFPosAbsMgr::isReference for the definition of the
+ // "reference widget".
+ return widget->getParent() == NULL;
case OOFM_FIXED:
// The single container for fixedly positioned elements is the
diff --git a/dw/oofposabsmgr.cc b/dw/oofposabsmgr.cc
index 07daca86..a0b8b721 100644
--- a/dw/oofposabsmgr.cc
+++ b/dw/oofposabsmgr.cc
@@ -35,6 +35,20 @@ OOFPosAbsMgr::~OOFPosAbsMgr ()
DBG_OBJ_DELETE ();
}
+bool OOFPosAbsMgr::isReference (core::Widget *widget)
+{
+ // Only the toplevel widget (as for all) as well as absolutely,
+ // relatively, and fixedly positioned elements constitute the
+ // containing block (i. e. the reference widget) for absolutely
+ // positioned elements (But neither floats nor other elements like
+ // table cells, or elements with 'overview' set to another value
+ // than 'visible').
+
+ return widget->instanceOf (OOFAwareWidget::CLASS_ID) &&
+ (widget->getParent() == NULL ||
+ OOFAwareWidget::testWidgetPositioned (widget));
+}
+
// Comment for all containerBox* implementations: for the toplevel
// widget, assume margin = border = 0 (should perhaps set so when
// widgets are constructed), so that the padding area is actually the
diff --git a/dw/oofposabsmgr.hh b/dw/oofposabsmgr.hh
index 20c09535..f6cc969e 100644
--- a/dw/oofposabsmgr.hh
+++ b/dw/oofposabsmgr.hh
@@ -10,6 +10,7 @@ namespace oof {
class OOFPosAbsMgr: public OOFPositionedMgr
{
protected:
+ bool isReference (core::Widget *widget);
int containerBoxOffsetX ();
int containerBoxOffsetY ();
int containerBoxRestWidth ();
diff --git a/dw/oofposfixedmgr.cc b/dw/oofposfixedmgr.cc
index 22cca983..ea5f9b5c 100644
--- a/dw/oofposfixedmgr.cc
+++ b/dw/oofposfixedmgr.cc
@@ -34,6 +34,10 @@ OOFPosFixedMgr::~OOFPosFixedMgr ()
DBG_OBJ_DELETE ();
}
+bool OOFPosFixedMgr::isReference (core::Widget *widget)
+{
+ return widget->getParent () == NULL;
+}
int OOFPosFixedMgr::containerBoxOffsetX ()
{
diff --git a/dw/oofposfixedmgr.hh b/dw/oofposfixedmgr.hh
index 38937878..1e099d39 100644
--- a/dw/oofposfixedmgr.hh
+++ b/dw/oofposfixedmgr.hh
@@ -10,6 +10,7 @@ namespace oof {
class OOFPosFixedMgr: public OOFPositionedMgr
{
protected:
+ bool isReference (core::Widget *widget);
int containerBoxOffsetX ();
int containerBoxOffsetY ();
int containerBoxRestWidth ();
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 2466086b..334aed30 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -82,23 +82,18 @@ void OOFPositionedMgr::sizeAllocateEnd (OOFAwareWidget *caller)
bool extremesChanged = haveExtremesChanged ();
// Consider children which were ignored in getSize (see comment
- // there). These are children, for which the generator is
- // different from the container, whose position is not fully
- // defined, and for which the generator and container were not
- // allocated. For the container, the latter is the case when
- // containerAllocationState == IN_ALLOCATION; for the generator,
- // this is valid in an analogue way, as long as sizeRequest is
- // immediately followed by sizeAllocate (as in resizeIdle).
+ // there). The respective widgets were not allocated before if
+ // and only if containerAllocationState == IN_ALLOCATION. For
+ // the generator (and reference widget), this is the case as
+ // long as sizeRequest is immediately followed by sizeAllocate
+ // (as in resizeIdle).
bool notAllChildrenConsideredBefore = false;
- if (containerAllocationState == IN_ALLOCATION) {
- for (int i = 0;
- !notAllChildrenConsideredBefore && i < children->size(); i++) {
- Child *child = children->get(i);
- if (child->generator != container && !isPosComplete (child->widget))
- notAllChildrenConsideredBefore = true;
- }
- }
+ for (int i = 0;
+ !notAllChildrenConsideredBefore && i < children->size(); i++)
+ if (!isPosCalculable (children->get(i),
+ containerAllocationState != IN_ALLOCATION))
+ notAllChildrenConsideredBefore = true;
if (sizeChanged || notAllChildrenConsideredBefore || extremesChanged)
container->oofSizeChanged (extremesChanged);
@@ -203,14 +198,13 @@ bool OOFPositionedMgr::haveExtremesChanged ()
DBG_OBJ_MSG_START ();
- // Search for children which have not yet been considered by getExtremes().
+ // Search for children which have not yet been considered by
+ // getExtremes(). Cf. sizeAllocateEnd().
- for (int i = 0; i < children->size () && !changed; i++) {
- Child *child = children->get (i);
- if (child->generator != container && !isHPosComplete (child->widget) &&
- containerAllocationState == IN_ALLOCATION)
+ for (int i = 0; i < children->size () && !changed; i++)
+ if (!isHPosCalculable (children->get (i),
+ containerAllocationState == IN_ALLOCATION))
changed = true;
- }
DBG_OBJ_MSG_END ();
@@ -261,7 +255,17 @@ int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator,
DBG_OBJ_ENTER ("construct.oofm", 0, "addWidgetOOF", "%p, %p, %d",
widget, generator, externalIndex);
- Child *child = new Child (widget, generator);
+ Widget *reference = NULL;
+
+ for (Widget *widget2 = generator; reference == NULL && widget2 != container;
+ widget2 = widget2->getParent ())
+ if (isReference (widget2))
+ reference = widget2;
+
+ if (reference == NULL)
+ reference = container;
+
+ Child *child = new Child (widget, generator, reference);
children->put (child);
childrenByWidget->put (new TypedPointer<Widget> (widget), child);
@@ -270,6 +274,7 @@ int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator,
DBG_OBJ_ARRSET_PTR ("children", children->size() - 1, widget);
DBG_OBJ_SET_PTR_O (widget, "<Positioned>.generator", generator);
+ DBG_OBJ_SET_PTR_O (widget, "<Positioned>.reference", reference);
DBG_OBJ_MSGF ("construct.oofm", 1, "=> %d", subRef);
DBG_OBJ_LEAVE ();
@@ -355,10 +360,9 @@ void OOFPositionedMgr::getSize (Requisition *containerReq, int *oofWidth,
// this method) can only be determined when the following
// condition (if clause) is is fulfilled. Other children will be
// considered later in sizeAllocateEnd.
- if (child->generator == container ||
- isPosComplete (child->widget) ||
- (containerAllocationState != NOT_ALLOCATED
- && child->generator->wasAllocated ())) {
+ if (isPosCalculable (child,
+ containerAllocationState != NOT_ALLOCATED &&
+ child->generator->wasAllocated ())) {
int x, y, width, ascent, descent;
calcPosAndSizeChildOfChild (child, refWidth, refHeight, &x, &y, &width,
&ascent, &descent);
@@ -389,10 +393,9 @@ void OOFPositionedMgr::getExtremes (Extremes *containerExtr, int *oofMinWidth,
Child *child = children->get(i);
// If clause: see getSize().
- if (child->generator == container ||
- isHPosComplete (child->widget) ||
- (containerAllocationState != NOT_ALLOCATED
- && child->generator->wasAllocated ())) {
+ if (isHPosCalculable (child,
+ containerAllocationState != NOT_ALLOCATED
+ && child->generator->wasAllocated ())) {
int x, width;
Extremes childExtr;
child->widget->getExtremes (&childExtr);
@@ -584,25 +587,38 @@ int OOFPositionedMgr::getPosBorder (style::Length cssValue, int refLength)
return -1;
}
-bool OOFPositionedMgr::isHPosComplete (Widget *child)
+bool OOFPositionedMgr::isHPosComplete (Child *child)
{
- return (style::isAbsLength (child->getStyle()->left) ||
- style::isPerLength (child->getStyle()->left)) &&
- (style::isAbsLength (child->getStyle()->right) ||
- style::isPerLength (child->getStyle()->right));
+ return (style::isAbsLength (child->widget->getStyle()->left) ||
+ style::isPerLength (child->widget->getStyle()->left)) &&
+ (style::isAbsLength (child->widget->getStyle()->right) ||
+ style::isPerLength (child->widget->getStyle()->right));
}
-bool OOFPositionedMgr::isVPosComplete (Widget *child)
+bool OOFPositionedMgr::isVPosComplete (Child *child)
{
- return (style::isAbsLength (child->getStyle()->top) ||
- style::isPerLength (child->getStyle()->top)) &&
- (style::isAbsLength (child->getStyle()->bottom) ||
- style::isPerLength (child->getStyle()->bottom));
+ return (style::isAbsLength (child->widget->getStyle()->top) ||
+ style::isPerLength (child->widget->getStyle()->top)) &&
+ (style::isAbsLength (child->widget->getStyle()->bottom) ||
+ style::isPerLength (child->widget->getStyle()->bottom));
}
-bool OOFPositionedMgr::isPosComplete (Widget *child)
+bool OOFPositionedMgr::isHPosCalculable (Child *child, bool allocated)
{
- return isHPosComplete (child) && isVPosComplete (child);
+ return
+ allocated || (isVPosComplete (child) && child->reference == container);
+}
+
+bool OOFPositionedMgr::isVPosCalculable (Child *child, bool allocated)
+{
+ return
+ allocated || (isVPosComplete (child) && child->reference == container);
+}
+
+bool OOFPositionedMgr::isPosCalculable (Child *child, bool allocated)
+{
+ return isHPosCalculable (child, allocated) &&
+ isVPosCalculable (child, allocated);
}
void OOFPositionedMgr::calcPosAndSizeChildOfChild (Child *child, int refWidth,
@@ -676,15 +692,25 @@ void OOFPositionedMgr::calcHPosAndSizeChildOfChild (Child *child, int refWidth,
child->x + (child->generator == container ? 0 :
child->generator->getAllocation()->x
- (containerAllocation.x + containerBoxOffsetX ()));
- } else if (left == -1 && right != -1)
- *xPtr = refWidth - width - right;
- else if (left != -1 && right == -1)
- *xPtr = left;
- else {
- *xPtr = left;
- if (!widthDefined) {
- width = refWidth - (left + right);
- DBG_OBJ_MSGF ("resize.oofm", 0, "=> width (corrected) = %d", width);
+ } else {
+ assert (child->reference == container ||
+ (containerAllocationState != NOT_ALLOCATED
+ && child->reference->wasAllocated ()));
+ int xBase = child->reference == container ? 0 :
+ child->generator->getAllocation()->x - containerAllocation.x;
+ DBG_OBJ_MSGF ("resize.oofm", 0, "=> xBase = %d", xBase);
+
+ if (left == -1 && right != -1)
+ *xPtr = xBase + refWidth - width - right;
+ else if (left != -1 && right == -1)
+ *xPtr = xBase + left;
+ else {
+ *xPtr = xBase + left;
+ if (!widthDefined) {
+ width = refWidth - (left + right);
+ DBG_OBJ_MSGF ("resize.oofm", 0, "=> width (corrected) = %d",
+ width);
+ }
}
}
@@ -745,18 +771,27 @@ void OOFPositionedMgr::calcVPosAndSizeChildOfChild (Child *child, int refHeight,
child->y + (child->generator == container ? 0 :
child->generator->getAllocation()->y
- (containerAllocation.y + containerBoxOffsetY ()));
- } else if (top == -1 && bottom != -1)
- *yPtr = refHeight - (ascent + descent) - bottom;
- else if (top != -1 && bottom == -1)
- *yPtr = top;
- else {
- *yPtr = top;
- if (!heightDefined) {
- int height = refHeight - (top + bottom);
- splitHeightPreserveAscent (height, &ascent, &descent);
- DBG_OBJ_MSGF ("resize.oofm", 0,
- "=> ascent + descent (corrected) = %d + %d",
- ascent, descent);
+ } else {
+ assert (child->reference == container ||
+ (containerAllocationState != NOT_ALLOCATED
+ && child->reference->wasAllocated ()));
+ int yBase = child->reference == container ? 0 :
+ child->generator->getAllocation()->y - containerAllocation.y;
+ DBG_OBJ_MSGF ("resize.oofm", 0, "=> yBase = %d", yBase);
+
+ if (top == -1 && bottom != -1)
+ *yPtr = yBase + refHeight - (ascent + descent) - bottom;
+ else if (top != -1 && bottom == -1)
+ *yPtr = yBase + top;
+ else {
+ *yPtr = yBase + top;
+ if (!heightDefined) {
+ int height = refHeight - (top + bottom);
+ splitHeightPreserveAscent (height, &ascent, &descent);
+ DBG_OBJ_MSGF ("resize.oofm", 0,
+ "=> ascent + descent (corrected) = %d + %d",
+ ascent, descent);
+ }
}
}
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index 04fa1629..713c2739 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -13,14 +13,17 @@ protected:
class Child: public lout::object::Object
{
public:
- core::Widget *widget;
+ core::Widget *widget, *reference;
OOFAwareWidget *generator;
int x, y;
- inline Child (core::Widget *widget, OOFAwareWidget *generator)
- { this->widget = widget; this->generator = generator; x = y = 0; }
+ inline Child (core::Widget *widget, OOFAwareWidget *generator,
+ core::Widget *reference)
+ { this->widget = widget; this->generator = generator;
+ this->reference = reference; x = y = 0; }
};
+ virtual bool isReference (core::Widget *widget) = 0;
virtual int containerBoxOffsetX () = 0;
virtual int containerBoxOffsetY () = 0;
virtual int containerBoxRestWidth () = 0;
@@ -56,9 +59,13 @@ protected:
int getPosBorder (core::style::Length cssValue, int refLength);
- bool isHPosComplete (core::Widget *child);
- bool isVPosComplete (core::Widget *child);
- bool isPosComplete (core::Widget *child);
+ bool isHPosComplete (Child *child);
+ bool isVPosComplete (Child *child);
+
+ bool isHPosCalculable (Child *child, bool allocated);
+ bool isVPosCalculable (Child *child, bool allocated);
+
+ bool isPosCalculable (Child *child, bool allocated);
void calcPosAndSizeChildOfChild (Child *child, int refWidth, int refHeight,
int *xPtr, int *yPtr, int *widthPtr,