diff options
author | Sebastian Geerken <devnull@localhost> | 2014-12-22 14:59:02 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2014-12-22 14:59:02 +0100 |
commit | 1162688e7720815b17cc6b85033ec5b63eb6440e (patch) | |
tree | d8ca3b1c43b7155c19f9e2470fae469fdf78824f /dw | |
parent | 424a01ce5c2dd3cadd3d7ca60c7b43283c183b02 (diff) |
(Absolute) positions: distinguish between container (= parent widget) and reference widget.
Diffstat (limited to 'dw')
-rw-r--r-- | dw/oofawarewidget.cc | 11 | ||||
-rw-r--r-- | dw/oofposabsmgr.cc | 14 | ||||
-rw-r--r-- | dw/oofposabsmgr.hh | 1 | ||||
-rw-r--r-- | dw/oofposfixedmgr.cc | 4 | ||||
-rw-r--r-- | dw/oofposfixedmgr.hh | 1 | ||||
-rw-r--r-- | dw/oofpositionedmgr.cc | 161 | ||||
-rw-r--r-- | dw/oofpositionedmgr.hh | 19 |
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, |