aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2015-01-31 17:15:19 +0100
committerSebastian Geerken <devnull@localhost>2015-01-31 17:15:19 +0100
commit20be26d3698eeeeaf2c0a9e55a28831466fc0bd1 (patch)
treedd0388e3b11d9a409809609f1bf946964ebb58f4
parenteac1c960c8c875715fdb8d123e4c19302d93eb00 (diff)
Relative positions, part 6 (hopefully last): calculating the positions.
-rw-r--r--dw/ooffloatsmgr.cc2
-rw-r--r--dw/oofposabslikemgr.cc49
-rw-r--r--dw/oofpositionedmgr.cc21
-rw-r--r--dw/oofpositionedmgr.hh20
-rw-r--r--dw/oofposrelmgr.cc62
-rw-r--r--dw/oofposrelmgr.hh19
-rw-r--r--dw/textblock.cc23
-rw-r--r--dw/textblock.hh1
-rw-r--r--dw/textblock_linebreaking.cc9
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)