diff options
author | Sebastian Geerken <devnull@localhost> | 2015-01-31 17:15:19 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2015-01-31 17:15:19 +0100 |
commit | 20be26d3698eeeeaf2c0a9e55a28831466fc0bd1 (patch) | |
tree | dd0388e3b11d9a409809609f1bf946964ebb58f4 | |
parent | eac1c960c8c875715fdb8d123e4c19302d93eb00 (diff) |
Relative positions, part 6 (hopefully last): calculating the positions.
-rw-r--r-- | dw/ooffloatsmgr.cc | 2 | ||||
-rw-r--r-- | dw/oofposabslikemgr.cc | 49 | ||||
-rw-r--r-- | dw/oofpositionedmgr.cc | 21 | ||||
-rw-r--r-- | dw/oofpositionedmgr.hh | 20 | ||||
-rw-r--r-- | dw/oofposrelmgr.cc | 62 | ||||
-rw-r--r-- | dw/oofposrelmgr.hh | 19 | ||||
-rw-r--r-- | dw/textblock.cc | 23 | ||||
-rw-r--r-- | dw/textblock.hh | 1 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 9 |
9 files changed, 148 insertions, 58 deletions
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc index 4bf69450..c2ffc580 100644 --- a/dw/ooffloatsmgr.cc +++ b/dw/ooffloatsmgr.cc @@ -1525,7 +1525,7 @@ Widget *OOFFloatsMgr::getFloatWidgetAtPoint (SortedFloatsVector *list, int x, void OOFFloatsMgr::tellPosition1 (Widget *widget, int x, int y) { - DBG_OBJ_ENTER ("resize.oofm", 0, "tellPosition", "%p, %d, %d", + DBG_OBJ_ENTER ("resize.oofm", 0, "tellPosition1", "%p, %d, %d", widget, x, y); assert (y >= 0); diff --git a/dw/oofposabslikemgr.cc b/dw/oofposabslikemgr.cc index aed328ee..5afd6ec5 100644 --- a/dw/oofposabslikemgr.cc +++ b/dw/oofposabslikemgr.cc @@ -288,12 +288,13 @@ int OOFPosAbsLikeMgr::getAvailWidthOfChild (Widget *child, bool forceValue) // TODO Is "boxDiffWidth()" correct here? DBG_OBJ_MSG ("resize.oofm", 1, "no specification"); if (forceValue) { - int availWidth = container->getAvailWidth (true); - width = max (availWidth - containerBoxDiffWidth () - // Regard an undefined value as 0: - - max (getPosLeft (child, availWidth), 0), - - max (getPosRight (child, availWidth), 0), - 0); + int availWidth = container->getAvailWidth (true), left, right; + + // Regard undefined values as 0: + if (!getPosLeft (child, availWidth, &left)) left = 0; + if (!getPosRight (child, availWidth, &right)) right = 0; + + width = max (availWidth - containerBoxDiffWidth () - left - right, 0); } else width = -1; } else { @@ -330,12 +331,14 @@ int OOFPosAbsLikeMgr::getAvailHeightOfChild (Widget *child, bool forceValue) // TODO Is "boxDiffHeight()" correct here? DBG_OBJ_MSG ("resize.oofm", 1, "no specification"); if (forceValue) { - int availHeight = container->getAvailHeight (true); - height = max (availHeight - containerBoxDiffHeight () - // Regard an undefined value as 0: - - max (getPosTop (child, availHeight), 0), - - max (getPosBottom (child, availHeight), 0), - 0); + int availHeight = container->getAvailHeight (true), top, bottom; + + // Regard undefined values as 0: + if (!getPosTop (child, availHeight, &top)) top = 0; + if (!getPosBottom (child, availHeight, &bottom)) bottom = 0; + + height = + max (availHeight - containerBoxDiffHeight () - top - bottom, 0); } else height = -1; } else { @@ -464,14 +467,15 @@ void OOFPosAbsLikeMgr::calcHPosAndSizeChildOfChild (Child *child, int refWidth, widthDefined = false; } - int left = getPosLeft (child->widget, refWidth), - right = getPosRight (child->widget, refWidth); + int left, right; + bool leftDefined = getPosLeft (child->widget, refWidth, &left), + rightDefined = getPosRight (child->widget, refWidth, &right); DBG_OBJ_MSGF ("resize.oofm", 1, "=> left = %d, right = %d, width = %d (defined: %s)", left, right, width, widthDefined ? "true" : "false"); if (xPtr) { - if (left == -1 && right == -1) { + if (!leftDefined && !rightDefined) { assert (child->generator == container || (containerAllocationState != NOT_ALLOCATED && child->generator->wasAllocated ())); @@ -487,9 +491,9 @@ void OOFPosAbsLikeMgr::calcHPosAndSizeChildOfChild (Child *child, int refWidth, child->generator->getAllocation()->x - containerAllocation.x; DBG_OBJ_MSGF ("resize.oofm", 0, "=> xBase = %d", xBase); - if (left == -1 && right != -1) + if (!leftDefined && rightDefined) *xPtr = xBase + refWidth - width - right; - else if (left != -1 && right == -1) + else if (leftDefined && !rightDefined) *xPtr = xBase + left; else { *xPtr = xBase + left; @@ -542,15 +546,16 @@ void OOFPosAbsLikeMgr::calcVPosAndSizeChildOfChild (Child *child, int refHeight, heightDefined = false; } - int top = getPosTop (child->widget, refHeight), - bottom = getPosBottom (child->widget, refHeight); + int top, bottom; + bool topDefined = getPosTop (child->widget, refHeight, &top), + bottomDefined = getPosBottom (child->widget, refHeight, &bottom); DBG_OBJ_MSGF ("resize.oofm", 1, "=> top = %d, bottom = %d, height = %d + %d (defined: %s)", top, bottom, ascent, descent, heightDefined ? "true" : "false"); if (yPtr) { - if (top == -1 && bottom == -1) { + if (!topDefined && !bottomDefined) { assert (child->generator == container || (containerAllocationState != NOT_ALLOCATED && child->generator->wasAllocated ())); @@ -566,9 +571,9 @@ void OOFPosAbsLikeMgr::calcVPosAndSizeChildOfChild (Child *child, int refHeight, child->generator->getAllocation()->y - containerAllocation.y; DBG_OBJ_MSGF ("resize.oofm", 0, "=> yBase = %d", yBase); - if (top == -1 && bottom != -1) + if (!topDefined && bottomDefined) *yPtr = yBase + refHeight - (ascent + descent) - bottom; - else if (top != -1 && bottom == -1) + else if (topDefined && !bottomDefined) *yPtr = yBase + top; else { *yPtr = yBase + top; diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc index 5834a729..fc4ad938 100644 --- a/dw/oofpositionedmgr.cc +++ b/dw/oofpositionedmgr.cc @@ -169,7 +169,7 @@ void OOFPositionedMgr::tellPosition1 (Widget *widget, int x, int y) void OOFPositionedMgr::tellPosition2 (Widget *widget, int x, int y) { - DBG_OBJ_ENTER ("resize.oofm", 0, "tellPosition", "%p, %d, %d", + DBG_OBJ_ENTER ("resize.oofm", 0, "tellPosition2", "%p, %d, %d", widget, x, y); TypedPointer<Widget> key (widget); @@ -264,15 +264,18 @@ Widget *OOFPositionedMgr::getWidget (int i) return children->get(i)->widget; } -int OOFPositionedMgr::getPosBorder (style::Length cssValue, int refLength) +bool OOFPositionedMgr::getPosBorder (style::Length cssValue, int refLength, + int *result) { - if (style::isAbsLength (cssValue)) - return style::absLengthVal (cssValue); - else if (style::isPerLength (cssValue)) - return style::multiplyWithPerLength (refLength, cssValue); - else - // -1 means "undefined": - return -1; + if (style::isAbsLength (cssValue)) { + *result = style::absLengthVal (cssValue); + return true; + } else if (style::isPerLength (cssValue)) { + *result = style::multiplyWithPerLength (refLength, cssValue); + return true; + } else + // "false" means "undefined": + return false; } } // namespace oof diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh index 272cc62b..2962a9d1 100644 --- a/dw/oofpositionedmgr.hh +++ b/dw/oofpositionedmgr.hh @@ -34,16 +34,16 @@ protected: <dw::core::Widget>, Child> *childrenByWidget; - inline int getPosLeft (core::Widget *child, int availWidth) - { return getPosBorder (child->getStyle()->left, availWidth); } - inline int getPosRight (core::Widget *child, int availWidth) - { return getPosBorder (child->getStyle()->right, availWidth); } - inline int getPosTop (core::Widget *child, int availHeight) - { return getPosBorder (child->getStyle()->top, availHeight); } - inline int getPosBottom (core::Widget *child, int availHeight) - { return getPosBorder (child->getStyle()->bottom, availHeight); } - - int getPosBorder (core::style::Length cssValue, int refLength); + inline bool getPosLeft (core::Widget *child, int availWidth, int *result) + { return getPosBorder (child->getStyle()->left, availWidth, result); } + inline bool getPosRight (core::Widget *child, int availWidth, int *result) + { return getPosBorder (child->getStyle()->right, availWidth, result); } + inline bool getPosTop (core::Widget *child, int availHeight, int *result) + { return getPosBorder (child->getStyle()->top, availHeight, result); } + inline bool getPosBottom (core::Widget *child, int availHeight, int *result) + { return getPosBorder (child->getStyle()->bottom, availHeight, result); } + + bool getPosBorder (core::style::Length cssValue, int refLength, int *result); public: OOFPositionedMgr (OOFAwareWidget *container); diff --git a/dw/oofposrelmgr.cc b/dw/oofposrelmgr.cc index 8820f8b5..b4532c9d 100644 --- a/dw/oofposrelmgr.cc +++ b/dw/oofposrelmgr.cc @@ -18,7 +18,6 @@ */ #include "oofposrelmgr.hh" -#include "oofawarewidget.hh" using namespace dw::core; using namespace lout::object; @@ -66,12 +65,21 @@ void OOFPosRelMgr::calcWidgetRefSize (Widget *widget, Requisition *size) void OOFPosRelMgr::sizeAllocateStart (OOFAwareWidget *caller, Allocation *allocation) { + DBG_OBJ_ENTER ("resize.oofm", 0, "sizeAllocateStart", + "%p, (%d, %d, %d * (%d + %d))", + caller, allocation->x, allocation->y, allocation->width, + allocation->ascent, allocation->descent); + if (caller == container) containerAllocation = *allocation; + + DBG_OBJ_LEAVE (); } void OOFPosRelMgr::sizeAllocateEnd (OOFAwareWidget *caller) { + DBG_OBJ_ENTER ("resize.oofm", 0, "sizeAllocateEnd", "%p", caller); + if (caller == container) { for (int i = 0; i < children->size (); i++) { Child *child = children->get(i); @@ -82,14 +90,16 @@ void OOFPosRelMgr::sizeAllocateEnd (OOFAwareWidget *caller) Allocation *genAlloc = child->generator == container ? &containerAllocation : child->generator->getAllocation (), childAlloc; - childAlloc.x = genAlloc->x + child->x; - childAlloc.y = genAlloc->y + child->y; + childAlloc.x = genAlloc->x + getChildPosX (child); + childAlloc.y = genAlloc->y + getChildPosY (child); childAlloc.width = childReq.width; childAlloc.ascent = childReq.ascent; childAlloc.descent = childReq.descent; child->widget->sizeAllocate (&childAlloc); } } + + DBG_OBJ_LEAVE (); } void OOFPosRelMgr::getSize (Requisition *containerReq, int *oofWidth, @@ -99,11 +109,12 @@ void OOFPosRelMgr::getSize (Requisition *containerReq, int *oofWidth, for (int i = 0; i < children->size (); i++) { Child *child = children->get(i); - Requisition childReq; + Requisition childReq; child->widget->sizeRequest (&childReq); - *oofWidth = max (*oofWidth, child->x + childReq.width); + *oofWidth = max (*oofWidth, getChildPosX (child) + childReq.width); *oofHeight = max (*oofHeight, - child->y + childReq.ascent + childReq.descent); + getChildPosX (child) + childReq.ascent + + childReq.descent); } } @@ -116,9 +127,44 @@ void OOFPosRelMgr::getExtremes (Extremes *containerExtr, int *oofMinWidth, Child *child = children->get(i); Extremes childExtr; child->widget->getExtremes (&childExtr); - *oofMinWidth = max (*oofMinWidth, child->x + childExtr.minWidth); - *oofMaxWidth = max (*oofMaxWidth, child->x + childExtr.maxWidth); + + // Put the extremes of the container in relation to the extremes + // of the child, as in OOFPosAbsLikeMgr::getExtremes (see + // comment there). + *oofMinWidth = max (*oofMinWidth, + getChildPosX (child, containerExtr->minWidth) + + childExtr.minWidth); + *oofMaxWidth = max (*oofMaxWidth, + getChildPosX (child, containerExtr->maxWidth) + + childExtr.maxWidth); + } +} + +int OOFPosRelMgr::getChildPosDim (style::Length posCssValue, + style::Length negCssValue, int refPos, + int refLength) +{ + // posCssValue refers to "left" or "top", negCssValue refers to "right" or + // "bottom". The former values are preferred ("left" over "right" etc.), + // which should later depend on the CSS value "direction". + + DBG_OBJ_ENTER ("resize.oofm", 0, "getChildPosDim", + "<i>%d</i>, <i>%d</i>, %d, %d", + posCssValue, negCssValue, refPos, refLength); + + int diff; + if (getPosBorder (posCssValue, refLength, &diff)) + DBG_OBJ_MSGF ("resize.oofm", 1, "posCssValue: diff = %d", diff); + else { + if (getPosBorder (negCssValue, refLength, &diff)) { + DBG_OBJ_MSGF ("resize.oofm", 1, "negCssValue: diff = %d", diff); + diff *= -1; + } else + diff = 0; } + + DBG_OBJ_LEAVE_VAL ("%d + %d = %d", refPos, diff, refPos + diff); + return refPos + diff; } int OOFPosRelMgr::getAvailWidthOfChild (Widget *child, bool forceValue) diff --git a/dw/oofposrelmgr.hh b/dw/oofposrelmgr.hh index 90323094..fa58add3 100644 --- a/dw/oofposrelmgr.hh +++ b/dw/oofposrelmgr.hh @@ -2,6 +2,7 @@ #define __DW_OOFPOSRELMGR_HH__ #include "oofpositionedmgr.hh" +#include "oofawarewidget.hh" namespace dw { @@ -12,6 +13,24 @@ class OOFPosRelMgr: public OOFPositionedMgr protected: bool isReference (core::Widget *widget); + int getChildPosDim (core::style::Length posCssValue, + core::style::Length negCssValue, int refPos, + int refLength); + + inline int getChildPosX (Child *child, int refWidth) + { return getChildPosDim + (child->widget->getStyle()->left, child->widget->getStyle()->right, + child->x, refWidth - child->widget->getStyle()->boxDiffWidth ()); } + inline int getChildPosX (Child *child) + { return getChildPosX (child, container->getAvailWidth (true)); } + + inline int getChildPosY (Child *child, int refHeight) + { return getChildPosDim + (child->widget->getStyle()->top, child->widget->getStyle()->bottom, + child->y, refHeight - child->widget->getStyle()->boxDiffHeight ()); } + inline int getChildPosY (Child *child) + { return getChildPosY (child, container->getAvailHeight (true)); } + public: OOFPosRelMgr (OOFAwareWidget *container); ~OOFPosRelMgr (); diff --git a/dw/textblock.cc b/dw/textblock.cc index bdb8067d..d1d2fb26 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -3191,4 +3191,27 @@ int Textblock::yOffsetOfLineToBeCreated () return result; } +/** + * Includes margin, border, and padding. Can be used without allocation. + */ +int Textblock::yOffsetOfLineCreated (Line *line) +{ + // Similar applies (regarding exactness) as to yOffsetOfLineToBeCreated. + + DBG_OBJ_ENTER0 ("line.yoffset", 0, "yOffsetOfLineToBeCreated"); + + int result; + + Line *firstLine = lines->getRef (0); + result = calcVerticalBorder (getStyle()->padding.top, + getStyle()->borderWidth.top, + getStyle()->margin.top + extraSpace.top, + firstLine->borderAscent, + firstLine->marginAscent) + - firstLine->borderAscent + line->top; + + DBG_OBJ_LEAVE_VAL ("%d", result); + return result; +} + } // namespace dw diff --git a/dw/textblock.hh b/dw/textblock.hh index 80f29bd7..db5d845f 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -765,6 +765,7 @@ protected: void printBorderChangedErrorAndAbort (int y, Widget *vloat, int wrapLineIndex); int yOffsetOfLineToBeCreated (); + int yOffsetOfLineCreated (Line *line); bool sendSelectionEvent (core::SelectionState::EventType eventType, core::MousePositionEvent *event); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 6df26081..55577e87 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -495,15 +495,8 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, mustQueueResize = true; - //printWordShort (words->getRef (line->firstWord)); - //printf (" ... "); - //printWordShort (words->getRef (line->lastWord)); - //printf (": "); - //words->getRef(line->lastWord)->badnessAndPenalty.print (); - //printf ("\n"); - int xWidget = line->textOffset; - int yLine = lineYOffsetWidget (line); + int yLine = yOffsetOfLineCreated (line); for (int i = firstWord; i <= lastWord; i++) { Word *word = words->getRef (i); if (word->wordImgRenderer) |