diff options
-rw-r--r-- | dw/ruler.cc | 2 | ||||
-rw-r--r-- | dw/table.cc | 4 | ||||
-rw-r--r-- | dw/textblock.cc | 112 | ||||
-rw-r--r-- | dw/textblock.hh | 8 | ||||
-rw-r--r-- | dw/widget.cc | 135 | ||||
-rw-r--r-- | dw/widget.hh | 20 |
6 files changed, 254 insertions, 27 deletions
diff --git a/dw/ruler.cc b/dw/ruler.cc index 3599c32a..c19b30c0 100644 --- a/dw/ruler.cc +++ b/dw/ruler.cc @@ -34,7 +34,7 @@ Ruler::Ruler () void Ruler::sizeRequestImpl (core::Requisition *requisition) { - requisition->width = lout::misc::max (getAvailWidth (), + requisition->width = lout::misc::max (getAvailWidth (true), getStyle()->boxDiffWidth ()); requisition->ascent = getStyle()->boxOffsetY (); requisition->descent = getStyle()->boxRestHeight (); diff --git a/dw/table.cc b/dw/table.cc index d15100b7..e40d43ca 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -477,13 +477,13 @@ void Table::forceCalcCellSizes () * rendering is implemented, to handle fixed positions etc., * as defined by CSS2.) */ - int availWidth = getAvailWidth (); + int availWidth = getAvailWidth (true); totalWidth = misc::min (core::style::multiplyWithPerLength (availWidth, getStyle()->width), availWidth); } else if (getStyle()->width == core::style::LENGTH_AUTO) { - totalWidth = getAvailWidth (); + totalWidth = getAvailWidth (true); forceTotalWidth = 0; } diff --git a/dw/textblock.cc b/dw/textblock.cc index 7da706f7..e5f16186 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -333,7 +333,7 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition) DBG_OBJ_MSG ("resize", 0, "<b>sizeRequestImpl</b> ()"); DBG_OBJ_MSG_START (); - lineBreakWidth = getAvailWidth (); + lineBreakWidth = getAvailWidth (true); rewrap (); showMissingLines (); @@ -401,6 +401,8 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition) requisition->width); } + correctRequisition (requisition, core::splitHeightPreserveAscent); + DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)", requisition->width, requisition->ascent, requisition->descent); @@ -776,12 +778,13 @@ bool Textblock::isBlockLevel () return true; } -int Textblock::getAvailWidthOfChild (Widget *child) +int Textblock::getAvailWidthOfChild (Widget *child, bool forceValue) { // TODO Implement also for ListItem (subtract space for bullet). // TODO Correct by extremes? - DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidthOfChild</b> (%p)", child); + DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidthOfChild</b> (%p, %s)", + child, forceValue ? "true" : "false"); DBG_OBJ_MSG_START (); int width; @@ -790,12 +793,21 @@ int Textblock::getAvailWidthOfChild (Widget *child) // TODO What does "width" exactly stand for? (Content or all?) width = core::style::absLengthVal (child->getStyle()->width); else { - int containerWidth = getAvailWidth () - boxDiffWidth (); - if (core::style::isPerLength (child->getStyle()->width)) - width = core::style::multiplyWithPerLength (containerWidth, - child->getStyle()->width); - else - width = containerWidth; + int availWidth = getAvailWidth (forceValue); + if (availWidth == -1) { + assert (!forceValue); + width = -1; + } else { + int containerWidth = availWidth - boxDiffWidth (); + if (core::style::isPerLength (child->getStyle()->width)) + width = + core::style::multiplyWithPerLength (containerWidth, + child->getStyle()->width); + else + // A textblock will use the whole width (but not the whole + // height, see getAvailHeightOfChild()). + width = forceValue ? containerWidth : 1; + } } DBG_OBJ_MSGF ("resize", 1, "=> %d", width); @@ -804,6 +816,88 @@ int Textblock::getAvailWidthOfChild (Widget *child) return width; } +int Textblock::getAvailHeightOfChild (Widget *child) +{ + // TODO Implement also for ListItem (subtract space for bullet). + // TODO Correct by extremes? + + DBG_OBJ_MSGF ("resize", 0, "<b>getAvailHeightOfChild</b> (%p)", child); + DBG_OBJ_MSG_START (); + + int height; + + if (core::style::isAbsLength (child->getStyle()->height)) + // TODO What does "height" exactly stand for? (Content or all?) + height = core::style::absLengthVal (child->getStyle()->height); + else { + int availHeight = getAvailHeight (); + if (availHeight == -1) + height = -1; + else { + int containerHeight = availHeight - boxDiffHeight (); + if (core::style::isPerLength (child->getStyle()->height)) + height = + core::style::multiplyWithPerLength (containerHeight, + child->getStyle()->height); + else + height = -1; + } + } + + DBG_OBJ_MSGF ("resize", 1, "=> %d", height); + DBG_OBJ_MSG_END (); + + return height; +} + +void Textblock::correctRequisitionOfChild (Widget *child, + core::Requisition *requisition, + void (*splitHeightFun)(int height, + int *ascent, + int *descent)) +{ + // TODO Implement also for ListItem (subtract space for bullet). + // TODO Correct by extremes? + + DBG_OBJ_MSGF ("resize", 0, + "<b>correctRequisitionOfChild</b> (%p, %d * (%d + %d), ...)", + child, requisition->width, requisition->ascent, + requisition->descent); + DBG_OBJ_MSG_START (); + + if (core::style::isAbsLength (child->getStyle()->width)) + // TODO What does "width" exactly stand for? (Content or all?) + requisition->width = core::style::absLengthVal (child->getStyle()->width); + else if (core::style::isPerLength (child->getStyle()->width)) { + int availWidth = getAvailWidth (false); + if (availWidth != -1) { + int containerWidth = availWidth - boxDiffWidth (); + requisition->width = + core::style::multiplyWithPerLength (containerWidth, + child->getStyle()->width); + } + } + + if (core::style::isAbsLength (child->getStyle()->height)) + // TODO What does "height" exactly stand for? (Content or all?) + splitHeightFun (core::style::absLengthVal (child->getStyle()->height), + &requisition->ascent, &requisition->descent); + else if (core::style::isPerLength (child->getStyle()->height)) { + int availHeight = getAvailHeight (); + if (availHeight != -1) { + int containerHeight = availHeight - boxDiffHeight (); + splitHeightFun (core::style::multiplyWithPerLength + (containerHeight, child->getStyle()->height), + &requisition->ascent, &requisition->descent); + } + } + + DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)", + requisition->width, requisition->ascent, + requisition->descent); + DBG_OBJ_MSG_END (); +} + bool Textblock::buttonPressImpl (core::EventButton *event) { return sendSelectionEvent (core::SelectionState::BUTTON_PRESS, event); diff --git a/dw/textblock.hh b/dw/textblock.hh index 2f35acb5..dfedeeef 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -749,7 +749,13 @@ protected: void markSizeChange (int ref); void markExtremesChange (int ref); - int getAvailWidthOfChild (Widget *child); + int getAvailWidthOfChild (Widget *child, bool forceValue); + int getAvailHeightOfChild (Widget *child); + void correctRequisitionOfChild (Widget *child, + core::Requisition *requisition, + void (*splitHeightFun)(int height, + int *ascent, + int *descent)); void notifySetAsTopLevel(); void notifySetParent(); diff --git a/dw/widget.cc b/dw/widget.cc index 792647e9..79689e48 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -340,29 +340,32 @@ void Widget::sizeRequest (Requisition *requisition) DBG_OBJ_MSG_END (); } -int Widget::getAvailWidth () +int Widget::getAvailWidth (bool forceValue) { // TODO Correct by extremes? - DBG_OBJ_MSG ("resize", 0, "<b>getAvailWidth</b> ()"); + DBG_OBJ_MSGF ("resize", 0, "<b>getAvailWidth</b> (%s)", + forceValue ? "true" : "false"); DBG_OBJ_MSG_START (); int width; if (container == NULL) { // TODO Consider nested layouts (e. g. <button>). - int viewportWidth = - layout->viewportWidth - (layout->canvasHeightGreater ? - layout->vScrollbarThickness : 0); if (style::isAbsLength (getStyle()->width)) width = style::absLengthVal (getStyle()->width); - else if (style::isPerLength (getStyle()->width)) - width = style::multiplyWithPerLength (viewportWidth, - getStyle()->width); - else - width = viewportWidth; + else { + int viewportWidth = + layout->viewportWidth - (layout->canvasHeightGreater ? + layout->vScrollbarThickness : 0); + if (style::isPerLength (getStyle()->width)) { + width = style::multiplyWithPerLength (viewportWidth, + getStyle()->width); + } else + width = forceValue ? viewportWidth : -1; + } } else - width = container->getAvailWidthOfChild (this); + width = container->getAvailWidthOfChild (this, forceValue); DBG_OBJ_MSGF ("resize", 1, "=> %d", width); DBG_OBJ_MSG_END (); @@ -370,6 +373,80 @@ int Widget::getAvailWidth () return width; } +int Widget::getAvailHeight () +{ + // TODO Correct by ... not extremes, but ...? (Height extremes?) + + DBG_OBJ_MSG ("resize", 0, "<b>getAvailHeight</b> ()"); + DBG_OBJ_MSG_START (); + + int height; + + if (container == NULL) { + // TODO Consider nested layouts (e. g. <button>). + if (style::isAbsLength (getStyle()->height)) + height = style::absLengthVal (getStyle()->height); + else if (style::isPerLength (getStyle()->height)) + // Notice that here -- unlike getAvailWidth() -- + // layout->hScrollbarThickness is not considered here; + // something like canvasWidthGreater (analogue to + // canvasHeightGreater) would be complicated and lead to + // possibly contradictory self-references. + height = style::multiplyWithPerLength (layout->viewportHeight, + getStyle()->height); + else + height = -1; + } else + height = container->getAvailHeightOfChild (this); + + DBG_OBJ_MSGF ("resize", 1, "=> %d", height); + DBG_OBJ_MSG_END (); + + return height; +} + +void Widget::correctRequisition (Requisition *requisition, + void (*splitHeightFun)(int height, int *ascent, + int *descent)) +{ + // TODO Correct by extremes? + + DBG_OBJ_MSGF ("resize", 0, "<b>correctRequisition</b> (%d * (%d + %d), ...)", + requisition->width, requisition->ascent, requisition->descent); + DBG_OBJ_MSG_START (); + + if (container == NULL) { + if (core::style::isAbsLength (getStyle()->width)) + // TODO What does "width" exactly stand for? (Content or all?) + requisition->width = core::style::absLengthVal (getStyle()->width); + else if (core::style::isPerLength (getStyle()->width)) { + int viewportWidth = + layout->viewportWidth - (layout->canvasHeightGreater ? + layout->vScrollbarThickness : 0); + requisition->width = style::multiplyWithPerLength (viewportWidth, + getStyle()->width); + } + + if (core::style::isAbsLength (getStyle()->height)) + // TODO What does "height" exactly stand for? (Content or all?) + splitHeightFun (core::style::absLengthVal (getStyle()->height), + &requisition->ascent, &requisition->descent); + else if (core::style::isPerLength (getStyle()->height)) { + // For layout->viewportHeight, see comment in getAvailHeight(). + splitHeightFun (core::style::multiplyWithPerLength + (layout->viewportHeight, getStyle()->height), + &requisition->ascent, &requisition->descent); + } + } else + container->correctRequisitionOfChild (this, requisition, splitHeightFun); + + DBG_OBJ_MSGF ("resize", 1, "=> %d * (%d + %d)", + requisition->width, requisition->ascent, + requisition->descent); + DBG_OBJ_MSG_END (); + +} + /** * \brief Wrapper for Widget::getExtremesImpl(). */ @@ -847,13 +924,29 @@ void Widget::markExtremesChange (int ref) { } -int Widget::getAvailWidthOfChild (Widget *child) +int Widget::getAvailWidthOfChild (Widget *child, bool forceValue) +{ + // Must be implemented for possible containers. + misc::assertNotReached (); + return 0; +} + +int Widget::getAvailHeightOfChild (Widget *child) { // Must be implemented for possible containers. misc::assertNotReached (); return 0; } +void Widget::correctRequisitionOfChild (Widget *child, Requisition *requisition, + void (*splitHeightFun)(int height, + int *ascent, + int *descent)) +{ + // Must be implemented for possible containers. + misc::assertNotReached (); +} + /** * \brief This method is called after a widget has been set as the top of a * widget tree. @@ -922,5 +1015,23 @@ void Widget::removeChild (Widget *child) misc::assertNotReached (); } +void splitHeightPreserveAscent (int height, int *ascent, int *descent) +{ + *descent = height - *ascent; + if (*descent < 0) { + *descent = 0; + *ascent = height; + } +} + +void splitHeightPreserveDescent (int height, int *ascent, int *descent) +{ + *ascent = height - *descent; + if (*ascent < 0) { + *ascent = 0; + *descent = height; + } +} + } // namespace core } // namespace dw diff --git a/dw/widget.hh b/dw/widget.hh index 3d8cdbd6..09749012 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -312,7 +312,14 @@ protected: */ virtual void markExtremesChange (int ref); - virtual int getAvailWidthOfChild (Widget *child); + virtual int getAvailWidthOfChild (Widget *child, bool forceValue); + virtual int getAvailHeightOfChild (Widget *child); + virtual void correctRequisitionOfChild (Widget *child, + Requisition *requisition, + void (*splitHeightFun)(int height, + int *ascent, + int + *descent)); virtual void notifySetAsTopLevel(); virtual void notifySetParent(); @@ -424,8 +431,13 @@ public: void sizeRequest (Requisition *requisition); void getExtremes (Extremes *extremes); void sizeAllocate (Allocation *allocation); - int getAvailWidth (); + int getAvailWidth (bool forceValue); + int getAvailHeight (); + void correctRequisition (Requisition *requisition, + void (*splitHeightFun)(int height, int *ascent, + int *descent)); + virtual bool isBlockLevel (); virtual bool isPossibleContainer (); @@ -486,6 +498,10 @@ public: virtual void removeChild (Widget *child); }; +void splitHeightPreserveAscent (int height, int *ascent, int *descent); +void splitHeightPreserveDescent (int height, int *ascent, int *descent); + + } // namespace core } // namespace dw |