diff options
author | Sebastian Geerken <devnull@localhost> | 2015-01-08 14:51:23 +0100 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2015-01-08 14:51:23 +0100 |
commit | 3fa61740d50d8a8fd6c61eb86e1f7a45a3762570 (patch) | |
tree | b6d857642d861fc594292ec69260bfc3cc617be0 | |
parent | e05ebd46d570cd64c116ed4bdde669ea0962e99b (diff) | |
parent | 428094b178eb03d8e500c81837caac402e4b138c (diff) |
Merge with main repo.
-rw-r--r-- | doc/dw-grows.doc | 18 | ||||
-rw-r--r-- | dw/Makefile.am | 2 | ||||
-rw-r--r-- | dw/alignedtablecell.cc | 16 | ||||
-rw-r--r-- | dw/alignedtablecell.hh | 5 | ||||
-rw-r--r-- | dw/bullet.cc | 5 | ||||
-rw-r--r-- | dw/image.cc | 5 | ||||
-rw-r--r-- | dw/listitem.cc | 5 | ||||
-rw-r--r-- | dw/listitem.hh | 2 | ||||
-rw-r--r-- | dw/oofawarewidget.cc | 9 | ||||
-rw-r--r-- | dw/oofawarewidget.hh | 1 | ||||
-rw-r--r-- | dw/ooffloatsmgr.cc | 98 | ||||
-rw-r--r-- | dw/ooffloatsmgr.hh | 4 | ||||
-rw-r--r-- | dw/oofpositionedmgr.cc | 2 | ||||
-rw-r--r-- | dw/regardingborder.cc | 39 | ||||
-rw-r--r-- | dw/regardingborder.hh | 24 | ||||
-rw-r--r-- | dw/ruler.cc | 13 | ||||
-rw-r--r-- | dw/ruler.hh | 15 | ||||
-rw-r--r-- | dw/simpletablecell.cc | 13 | ||||
-rw-r--r-- | dw/simpletablecell.hh | 5 | ||||
-rw-r--r-- | dw/table.cc | 230 | ||||
-rw-r--r-- | dw/table.hh | 5 | ||||
-rw-r--r-- | dw/tablecell.cc | 3 | ||||
-rw-r--r-- | dw/tablecell.hh | 5 | ||||
-rw-r--r-- | dw/textblock.cc | 56 | ||||
-rw-r--r-- | dw/textblock.hh | 41 | ||||
-rw-r--r-- | dw/textblock_linebreaking.cc | 36 | ||||
-rw-r--r-- | dw/types.hh | 1 | ||||
-rw-r--r-- | dw/ui.cc | 18 | ||||
-rw-r--r-- | dw/ui.hh | 14 | ||||
-rw-r--r-- | dw/widget.cc | 57 | ||||
-rw-r--r-- | dw/widget.hh | 7 | ||||
-rw-r--r-- | lout/misc.hh | 16 | ||||
-rw-r--r-- | src/dillo.cc | 4 | ||||
-rw-r--r-- | src/html.cc | 21 | ||||
-rw-r--r-- | test/dw_simple_container.cc | 287 |
35 files changed, 724 insertions, 358 deletions
diff --git a/doc/dw-grows.doc b/doc/dw-grows.doc index 15150338..0d123d61 100644 --- a/doc/dw-grows.doc +++ b/doc/dw-grows.doc @@ -89,6 +89,24 @@ The rules for the calculation: <b>Notice:</b> Currently, dw::core::Widget::getExtremesImpl must set all four members in dw::core::Extremes; this may change.</div> +Another **extension of extremes: *adjustmentWidth*.** This is used as +minimum for the width, when "adjust_min_width" (or, +"adjust_table_min_width", respectively) is set. + +The rules for the calculation: + +1. If a widget has no children, it can choose a suitable value, + typically based on dw::core::Extremes::minWidth and + dw::core::Extremes::minWidthIntrinsic. +2. A widget must calculate *adjustmentWidth* from *adjustmentWidth* of + its children. + +*Note:* An implementation of dw::core::Widget::getExtremesImpl may set +this value *after* calling dw::core::Widget::correctExtremesOfChild, +so that it cannot be used for the correction of extremes. In this case +*useAdjustmentWidth = false* should be passed to +dw::core::Widget::correctExtremesOfChild. On the other hand, if known +before, *useAdjustmentWidth* should be set to *true*. Rules for *new* methods related to resizing =========================================== diff --git a/dw/Makefile.am b/dw/Makefile.am index 15055ad8..ba0c7539 100644 --- a/dw/Makefile.am +++ b/dw/Makefile.am @@ -84,6 +84,8 @@ libDw_widgets_a_SOURCES = \ oofpositionedmgr.hh \ outofflowmgr.cc \ outofflowmgr.hh \ + regardingborder.cc \ + regardingborder.hh \ ruler.cc \ ruler.hh \ simpletablecell.cc \ diff --git a/dw/alignedtablecell.cc b/dw/alignedtablecell.cc index e7ab2741..dc7d88c9 100644 --- a/dw/alignedtablecell.cc +++ b/dw/alignedtablecell.cc @@ -17,8 +17,6 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - - #include "alignedtablecell.hh" #include "table.hh" #include "tablecell.hh" @@ -58,6 +56,11 @@ bool AlignedTableCell::isBlockLevel () return tablecell::isBlockLevel (); } +bool AlignedTableCell::mustBeWidenedToAvailWidth () +{ + return tablecell::mustBeWidenedToAvailWidth (); +} + int AlignedTableCell::getAvailWidthOfChild (Widget *child, bool forceValue) { DBG_OBJ_ENTER ("resize", 0, "AlignedTableCell/getAvailWidthOfChild", @@ -104,15 +107,18 @@ void AlignedTableCell::correctRequisitionOfChild (Widget *child, } void AlignedTableCell::correctExtremesOfChild (Widget *child, - core::Extremes *extremes) + core::Extremes *extremes, + bool useAdjustmentWidth) { DBG_OBJ_ENTER ("resize", 0, "AlignedTableCell/correctExtremesOfChild", "%p, %d (%d) / %d (%d)", child, extremes->minWidth, extremes->minWidthIntrinsic, extremes->maxWidth, extremes->maxWidthIntrinsic); - AlignedTextblock::correctExtremesOfChild (child, extremes); - tablecell::correctCorrectedExtremesOfChild (this, child, extremes); + AlignedTextblock::correctExtremesOfChild (child, extremes, + useAdjustmentWidth); + tablecell::correctCorrectedExtremesOfChild (this, child, extremes, + useAdjustmentWidth); DBG_OBJ_LEAVE (); } diff --git a/dw/alignedtablecell.hh b/dw/alignedtablecell.hh index 5325ba63..56196e6d 100644 --- a/dw/alignedtablecell.hh +++ b/dw/alignedtablecell.hh @@ -18,7 +18,8 @@ protected: void correctRequisitionOfChild (Widget *child, core::Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - void correctExtremesOfChild (Widget *child, core::Extremes *extremes); + void correctExtremesOfChild (Widget *child, core::Extremes *extremes, + bool useAdjustmentWidth); bool getAdjustMinWidth (); @@ -39,6 +40,8 @@ public: int applyPerHeight (int containerHeight, core::style::Length perHeight); bool isBlockLevel (); + + bool mustBeWidenedToAvailWidth (); }; } // namespace dw diff --git a/dw/bullet.cc b/dw/bullet.cc index 0b4b5983..e01191c3 100644 --- a/dw/bullet.cc +++ b/dw/bullet.cc @@ -44,10 +44,9 @@ void Bullet::sizeRequestImpl (core::Requisition *requisition) void Bullet::getExtremesImpl (core::Extremes *extremes) { - extremes->minWidth = extremes->maxWidth = + extremes->minWidth = extremes->maxWidth = extremes->adjustmentWidth = + extremes->minWidthIntrinsic = extremes->maxWidthIntrinsic = lout::misc::max (getStyle()->font->xHeight * 4 / 5, 1); - extremes->minWidthIntrinsic = extremes->minWidth; - extremes->maxWidthIntrinsic = extremes->maxWidth; } void Bullet::containerSizeChangedForChildren () diff --git a/dw/image.cc b/dw/image.cc index a1052726..7fb6c5eb 100644 --- a/dw/image.cc +++ b/dw/image.cc @@ -264,7 +264,10 @@ void Image::getExtremesImpl (core::Extremes *extremes) extremes->minWidthIntrinsic = extremes->minWidth; extremes->maxWidthIntrinsic = extremes->maxWidth; - correctExtremes (extremes); + correctExtremes (extremes, false); + + extremes->adjustmentWidth = + misc::min (extremes->minWidthIntrinsic, extremes->minWidth); } void Image::sizeAllocateImpl (core::Allocation *allocation) diff --git a/dw/listitem.cc b/dw/listitem.cc index 65293d8d..8bd2a93a 100644 --- a/dw/listitem.cc +++ b/dw/listitem.cc @@ -40,6 +40,11 @@ ListItem::~ListItem() DBG_OBJ_DELETE (); } +bool ListItem::mustBeWidenedToAvailWidth () +{ + return true; +} + void ListItem::initWithWidget (core::Widget *widget, core::style::Style *style) { diff --git a/dw/listitem.hh b/dw/listitem.hh index 2e303d5d..20fa6e9d 100644 --- a/dw/listitem.hh +++ b/dw/listitem.hh @@ -18,6 +18,8 @@ public: ListItem(ListItem *ref, bool limitTextWidth); ~ListItem(); + bool mustBeWidenedToAvailWidth (); + void initWithWidget (core::Widget *widget, core::style::Style *style); void initWithText (const char *text, core::style::Style *style); }; diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc index 6e34b32f..c6b75306 100644 --- a/dw/oofawarewidget.cc +++ b/dw/oofawarewidget.cc @@ -339,6 +339,8 @@ void OOFAwareWidget::correctExtremesByOOF (Extremes *extremes) extremes->maxWidth = max (extremes->maxWidth, oofMaxWidth); extremes->maxWidthIntrinsic = max (extremes->maxWidthIntrinsic, oofMinWidth); + extremes->adjustmentWidth = max (extremes->adjustmentWidth, + oofMinWidth); DBG_OBJ_MSGF ("resize", 1, "after correction: %d (%d) / %d (%d)", extremes->minWidth, extremes->minWidthIntrinsic, @@ -809,6 +811,13 @@ Object *OOFAwareWidget::stackingIterator (bool atEnd) return new OOFStackingIterator (this, atEnd); } +bool OOFAwareWidget::mustBeWidenedToAvailWidth () +{ + // Only used for floats. + assertNotReached (); + return false; +} + void OOFAwareWidget::borderChanged (int y, Widget *vloat) { assertNotReached (); diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh index 17123910..5c87b423 100644 --- a/dw/oofawarewidget.hh +++ b/dw/oofawarewidget.hh @@ -260,6 +260,7 @@ public: Widget **interruptedWidget); lout::object::Object *stackingIterator (bool atEnd); + virtual bool mustBeWidenedToAvailWidth (); virtual void borderChanged (int y, core::Widget *vloat); virtual void clearPositionChanged (); virtual void oofSizeChanged (bool extremesChanged); diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc index f3844577..8758c1a3 100644 --- a/dw/ooffloatsmgr.cc +++ b/dw/ooffloatsmgr.cc @@ -750,10 +750,9 @@ bool OOFFloatsMgr::hasRelationChanged (TBInfo *tbInfo, Side side, else { Allocation *gba = getAllocation (vloat->generatingBlock); - int newFlx = - calcFloatX (vloat, side, - gba->x - containerAllocation.x, gba->width, - vloat->generatingBlock->getLineBreakWidth ()); + int newFlx = calcFloatX (vloat, side, + gba->x - containerAllocation.x, + getGBWidthForAllocation (vloat)); int newFly = vloat->generatingBlock->getAllocation()->y - containerAllocation.y + vloat->yReal; @@ -1206,11 +1205,10 @@ void OOFFloatsMgr::sizeAllocateFloats (Side side, int newLastAllocatedFloat) ensureFloatSize (vloat); Allocation *gba = getAllocation (vloat->generatingBlock); - int lineBreakWidth = vloat->generatingBlock->getLineBreakWidth(); Allocation childAllocation; - childAllocation.x = cba->x + - calcFloatX (vloat, side, gba->x - cba->x, gba->width, lineBreakWidth); + childAllocation.x = cba->x + calcFloatX (vloat, side, gba->x - cba->x, + getGBWidthForAllocation (vloat)); childAllocation.y = gba->y + vloat->yReal; childAllocation.width = vloat->size.width; childAllocation.ascent = vloat->size.ascent; @@ -1224,27 +1222,39 @@ void OOFFloatsMgr::sizeAllocateFloats (Side side, int newLastAllocatedFloat) DBG_OBJ_LEAVE (); } +// Used as argument "gbWidth" for calcFloatX(), in the context of allocation. +int OOFFloatsMgr::getGBWidthForAllocation (Float *vloat) +{ + // See comments in getFloatsSize() for a detailed rationale ... + if (container->mustBeWidenedToAvailWidth ()) + return vloat->generatingBlock->getLineBreakWidth (); + else + // ... but notice this difference: not GB width + float width is + // used, but only GB width, since the float width has already + // been included in getFloatsSize(). + return min (getAllocation(vloat->generatingBlock)->width, + vloat->generatingBlock->getLineBreakWidth ()); +} /** * \brief ... * * gbX is given relative to the CB, as is the return value. */ -int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth, - int gbLineBreakWidth) +int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth) { - DBG_OBJ_ENTER ("resize.common", 0, "calcFloatX", "%p, %s, %d, %d, %d", + DBG_OBJ_ENTER ("resize.common", 0, "calcFloatX", "%p, %s, %d, %d", vloat->getWidget (), side == LEFT ? "LEFT" : "RIGHT", gbX, - gbWidth, gbLineBreakWidth); + gbWidth); int x; switch (side) { case LEFT: // Left floats are always aligned on the left side of the // generator (content, not allocation) ... - x = gbX + vloat->generatingBlock->boxOffsetX(); - DBG_OBJ_MSGF ("resize.oofm", 1, "left: x = %d + %d = %d", - gbX, vloat->generatingBlock->boxOffsetX(), x); + x = gbX + vloat->generatingBlock->getStyle()->boxOffsetX(); + DBG_OBJ_MSGF ("resize.common", 1, "left: x = %d + %d = %d", + gbX, vloat->generatingBlock->getStyle()->boxOffsetX(), x); // ... but when the float exceeds the line break width of the // container, it is corrected (but not left of the container). // This way, we save space and, especially within tables, avoid @@ -1254,8 +1264,7 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth, x = max (0, container->getLineBreakWidth () - vloat->size.width); DBG_OBJ_MSGF ("resize.common", 1, "corrected to: max (0, %d - %d) = %d", - container->getLineBreakWidth (), vloat->size.width, - x); + container->getLineBreakWidth (), vloat->size.width, x); } break; @@ -1264,17 +1273,13 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth, // shifted to the right when they are too big (instead of // shifting the generator to the right). - // Notice that not the actual width, but the line break width is - // used. (This changed for GROWS, where the width of a textblock - // is often smaller that the line break.) - - x = max (gbX + gbLineBreakWidth - vloat->size.width - - vloat->generatingBlock->boxRestWidth(), + x = max (gbX + gbWidth - vloat->size.width + - vloat->generatingBlock->getStyle()->boxRestWidth(), // Do not exceed CB allocation: 0); DBG_OBJ_MSGF ("resize.common", 1, "x = max (%d + %d - %d - %d, 0) = %d", - gbX, gbLineBreakWidth, vloat->size.width, - vloat->generatingBlock->boxRestWidth(), x); + gbX, gbWidth, vloat->size.width, + vloat->generatingBlock->getStyle()->boxRestWidth(), x); break; default: @@ -1745,8 +1750,7 @@ bool OOFFloatsMgr::collidesH (Float *vloat, Float *other, SFVType type) calcFloatX (vloat, vloat->getWidget()->getStyle()->vloat == FLOAT_LEFT ? LEFT : RIGHT, - gba->x, gba->width, - vloat->generatingBlock->getLineBreakWidth ()); + gba->x, getGBWidthForAllocation (vloat)); // Generally: right border of the left float > left border of // the right float (all in canvas coordinates). @@ -1844,27 +1848,41 @@ void OOFFloatsMgr::getFloatsSize (Requisition *cbReq, Side side, int *width, DBG_OBJ_MSGF ("resize.oofm", 1, "float %p has generator %p (container is %p)", vloat->getWidget (), vloat->generatingBlock, container); - - // BTW: as opposed to positioned elements, those floats which - // are not generated by the container, or not yet allocated, and - // so not considered here, need not be considered later; since - // the relevant cases will trigger a call to borderChanged after - // a positive hasRelationChanged test. - + if (vloat->generatingBlock == container || wasAllocated (vloat->generatingBlock)) { ensureFloatSize (vloat); int x, y; + + int effWidth; + if (container->mustBeWidenedToAvailWidth ()) + // For most textblocks, the line break width is used for + // calculating the x position. (This changed for GROWS, + // where the width of a textblock is often smaller that + // the line break.) + effWidth = vloat->generatingBlock->getLineBreakWidth (); + else + // For some textblocks, like inline blocks, the line break + // width would be too large for right floats in some + // cases. + // + // (i) Consider a small inline block with only a few words + // in one line, narrower that line break width minus + // float width. In this case, the sum should be used. + // + // (ii) If there is more than one line, the line break + // will already be exceeded, and so be smaller that + // GB width + float width. + effWidth = min (cbReq->width + vloat->size.width, + vloat->generatingBlock->getLineBreakWidth ()); if (vloat->generatingBlock == container) { - x = calcFloatX (vloat, side, 0, cbReq->width, - vloat->generatingBlock->getLineBreakWidth ()); + x = calcFloatX (vloat, side, 0, effWidth); y = vloat->yReal; } else { Allocation *gba = getAllocation(vloat->generatingBlock); - x = calcFloatX (vloat, side, - gba->x - containerAllocation.x, gba->width, - vloat->generatingBlock->getLineBreakWidth ()); + x = calcFloatX (vloat, side, gba->x - containerAllocation.x, + effWidth); y = gba->y - containerAllocation.y + vloat->yReal; } @@ -1938,11 +1956,11 @@ void OOFFloatsMgr::getFloatsExtremes (Extremes *cbExtr, Side side, vloat->getWidget()->getExtremes (&extr); // The calculation of extremes must be kept consistent with - // getSize(). Especially this means for the *minimal* width: + // getFloatsSize(). Especially this means for the *minimal* width: // // - The right border (difference between float and // container) does not have to be considered (see - // getSize()). + // getFloatsSize()). // // - This is also the case for the left border, as seen in // calcFloatX() ("... but when the float exceeds the line diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh index b82019fe..12f7d7da 100644 --- a/dw/ooffloatsmgr.hh +++ b/dw/ooffloatsmgr.hh @@ -264,8 +264,8 @@ private: void moveFromGBToCB (Side side); void sizeAllocateFloats (Side side, int newLastAllocatedFloat); - int calcFloatX (Float *vloat, Side side, int gbX, int gbWidth, - int gbLineBreakWidth); + int getGBWidthForAllocation (Float *vloat); + int calcFloatX (Float *vloat, Side side, int gbX, int gbWidth); bool hasRelationChanged (TBInfo *tbInfo,int *minFloatPos, core::Widget **minFloat); diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc index c46c1e2c..1e753bda 100644 --- a/dw/oofpositionedmgr.cc +++ b/dw/oofpositionedmgr.cc @@ -529,7 +529,7 @@ int OOFPositionedMgr::getAvailWidthOfChild (Widget *child, bool forceValue) } if (width != -1) - width = max (width, child->getMinWidth (NULL, true, forceValue)); + width = max (width, child->getMinWidth (NULL, forceValue)); DBG_OBJ_MSGF ("resize.oofm", 1, "=> %d", width); DBG_OBJ_LEAVE (); diff --git a/dw/regardingborder.cc b/dw/regardingborder.cc new file mode 100644 index 00000000..2eb0b4bf --- /dev/null +++ b/dw/regardingborder.cc @@ -0,0 +1,39 @@ +/* + * Dillo Widget + * + * Copyright 2015 Sebastian Geerken <sgeerken@dillo.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "regardingborder.hh" + +#include <stdio.h> + +namespace dw { + +int RegardingBorder::CLASS_ID = -1; + +RegardingBorder::RegardingBorder () +{ + DBG_OBJ_CREATE ("dw::RegardingBorder"); + registerName ("dw::RegardingBorder", &CLASS_ID); +} + +RegardingBorder::~RegardingBorder () +{ + DBG_OBJ_DELETE (); +} + +} // namespace dw diff --git a/dw/regardingborder.hh b/dw/regardingborder.hh new file mode 100644 index 00000000..1cb6c25f --- /dev/null +++ b/dw/regardingborder.hh @@ -0,0 +1,24 @@ +#ifndef __DW_REGARDINGBORDER_HH__ +#define __DW_REGARDINGBORDER_HH__ + +#include "oofawarewidget.hh" + +namespace dw { + +/** + * \brief Base class (rather a tag interface) for those widgets + * regarding borders defined by floats, and so allocated on the + * full width. + */ +class RegardingBorder: public oof::OOFAwareWidget +{ +public: + static int CLASS_ID; + + RegardingBorder (); + ~RegardingBorder (); +}; + +} // namespace dw + +#endif // __DW_REGARDINGBORDER_HH__ diff --git a/dw/ruler.cc b/dw/ruler.cc index 979cb03c..f29ac5dd 100644 --- a/dw/ruler.cc +++ b/dw/ruler.cc @@ -26,8 +26,17 @@ namespace dw { +int Ruler::CLASS_ID = -1; + Ruler::Ruler () { + DBG_OBJ_CREATE ("dw::Ruler"); + registerName ("dw::Ruler", &CLASS_ID); +} + +Ruler::~Ruler () +{ + DBG_OBJ_DELETE (); } void Ruler::sizeRequestImpl (core::Requisition *requisition) @@ -42,7 +51,9 @@ void Ruler::getExtremesImpl (core::Extremes *extremes) extremes->minWidth = extremes->maxWidth = boxDiffWidth (); extremes->minWidthIntrinsic = extremes->minWidth; extremes->maxWidthIntrinsic = extremes->maxWidth; - correctExtremes (extremes); + correctExtremes (extremes, false); + extremes->adjustmentWidth = + lout::misc::min (extremes->minWidthIntrinsic, extremes->minWidth); } bool Ruler::isBlockLevel () diff --git a/dw/ruler.hh b/dw/ruler.hh index c94c2e55..50789398 100644 --- a/dw/ruler.hh +++ b/dw/ruler.hh @@ -1,7 +1,7 @@ #ifndef __RULER_HH__ #define __RULER_HH__ -#include "core.hh" +#include "regardingborder.hh" namespace dw { @@ -10,10 +10,14 @@ namespace dw { * * This is really an empty widget, the HTML parser puts a border * around it, and drawing is done in dw::core::Widget::drawWidgetBox. - * The only remarkable point is that the HAS_CONTENT flag is - * cleared. + * + * Ruler implements RegardingBorder; this way, it is simpler to fit + * the ruler exactly within the space between floats. Currently, the + * drawn area of the ruler is too large (but most of the superfluous + * part is hidden by the floats); this problem will soon solved here + * in the "dillo_grows" repository. */ -class Ruler: public core::Widget +class Ruler: public RegardingBorder { protected: void sizeRequestImpl (core::Requisition *requisition); @@ -25,7 +29,10 @@ protected: Widget **interruptedWidget); public: + static int CLASS_ID; + Ruler (); + ~Ruler (); bool isBlockLevel (); diff --git a/dw/simpletablecell.cc b/dw/simpletablecell.cc index 62b4a0a4..0f1d31c9 100644 --- a/dw/simpletablecell.cc +++ b/dw/simpletablecell.cc @@ -50,6 +50,11 @@ bool SimpleTableCell::isBlockLevel () return tablecell::isBlockLevel (); } +bool SimpleTableCell::mustBeWidenedToAvailWidth () +{ + return tablecell::mustBeWidenedToAvailWidth (); +} + int SimpleTableCell::getAvailWidthOfChild (Widget *child, bool forceValue) { DBG_OBJ_ENTER ("resize", 0, "SimpleTableCell/getAvailWidthOfChild", @@ -94,15 +99,17 @@ void SimpleTableCell::correctRequisitionOfChild (Widget *child, } void SimpleTableCell::correctExtremesOfChild (Widget *child, - core::Extremes *extremes) + core::Extremes *extremes, + bool useAdjustmentWidth) { DBG_OBJ_ENTER ("resize", 0, "SimpleTableCell/correctExtremesOfChild", "%p, %d (%d) / %d (%d)", child, extremes->minWidth, extremes->minWidthIntrinsic, extremes->maxWidth, extremes->maxWidthIntrinsic); - Textblock::correctExtremesOfChild (child, extremes); - tablecell::correctCorrectedExtremesOfChild (this, child, extremes); + Textblock::correctExtremesOfChild (child, extremes, useAdjustmentWidth); + tablecell::correctCorrectedExtremesOfChild (this, child, extremes, + useAdjustmentWidth); DBG_OBJ_LEAVE (); } diff --git a/dw/simpletablecell.hh b/dw/simpletablecell.hh index c90fc040..90f24ae4 100644 --- a/dw/simpletablecell.hh +++ b/dw/simpletablecell.hh @@ -14,7 +14,8 @@ protected: void correctRequisitionOfChild (Widget *child, core::Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - void correctExtremesOfChild (Widget *child, core::Extremes *extremes); + void correctExtremesOfChild (Widget *child, core::Extremes *extremes, + bool useAdjustmentWidth); bool getAdjustMinWidth (); @@ -30,6 +31,8 @@ public: int applyPerHeight (int containerHeight, core::style::Length perHeight); bool isBlockLevel (); + + bool mustBeWidenedToAvailWidth (); }; } // namespace dw diff --git a/dw/table.cc b/dw/table.cc index d6dbe633..dc112ef8 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -135,12 +135,13 @@ void Table::getExtremesImpl (core::Extremes *extremes) if (numCols == 0) extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth = - extremes->maxWidthIntrinsic = boxDiffWidth (); + extremes->maxWidthIntrinsic = extremes->adjustmentWidth = + boxDiffWidth (); else { forceCalcColumnExtremes (); extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth = - extremes->maxWidthIntrinsic = + extremes->maxWidthIntrinsic = extremes->adjustmentWidth = (numCols + 1) * getStyle()->hBorderSpacing + boxDiffWidth (); for (int col = 0; col < numCols; col++) { extremes->minWidth += colExtremes->getRef(col)->minWidth; @@ -149,10 +150,11 @@ void Table::getExtremesImpl (core::Extremes *extremes) extremes->maxWidth += colExtremes->getRef(col)->maxWidth; extremes->maxWidthIntrinsic += colExtremes->getRef(col)->maxWidthIntrinsic; + extremes->adjustmentWidth += colExtremes->getRef(col)->adjustmentWidth; } } - correctExtremes (extremes); + correctExtremes (extremes, true); // For the order, see similar reasoning for dw::Textblock. correctExtremesByOOF (extremes); @@ -231,14 +233,32 @@ int Table::getAvailWidthOfChild (Widget *child, bool forceValue) oofm->dealingWithSizeOfChild (child)) width = oofm->getAvailWidthOfChild (child, forceValue); else { - // Unlike other containers, the table widget sometimes narrows - // columns to a width less than specified by CSS (see - // forceCalcCellSizes). For this reason, the column widths have to - // be calculated in all cases. - if (forceValue) { - calcCellSizes (false); + // We do not calculate the column widths at this point, because + // this tends to be rather inefficient for tables with many + // cells: + // + // For each of the n cells, some text is added (say, only one word + // per cell). Textblock::addText will eventually (via addText0 + // etc.) call this method, Table::getAvailWidthOfChild. If + // calcCellSizes() is called here, this will call + // forceCalcCellSizes(), since the last call, sizes have to be + // re-calculated (because cells have been added). This will + // calculate the extremes for each existing cell, so + // Widget::getExtremes is called n * (n + 1) / 2 times. Even if the + // extremes are cached (so that getExtremesImpl does not have to be + // called in each case), this would make rendering tables with more + // than a few hundred cells unacceptably slow. + // + // Instead, column widths are calculated in Table::sizeRequestImpl. + // + // An alternative would be incremental resizing for tables; this + // approach resembles the behaviour before GROWS. + + // TODO Does it still make sence to return -1 when forceValue is + // set? + if (forceValue) width = calcAvailWidthForDescendant (child); - } else + else width = -1; } @@ -259,39 +279,31 @@ int Table::calcAvailWidthForDescendant (Widget *child) assert (actualChild != NULL); - // TODO This is inefficient. (Use parentRef?) - int width = -1; - for (int row = numRows - 1; width == -1 && row >= 0; row--) { - for (int col = 0; width == -1 && col < numCols; col++) { - int n = row * numCols + col; - if (childDefined (n) && - children->get(n)->cell.widget == actualChild) { - DBG_OBJ_MSGF ("resize", 1, "calculated from column %d", col); - width = (children->get(n)->cell.colspanEff - 1) - * getStyle()->hBorderSpacing; - for (int i = 0; i < children->get(n)->cell.colspanEff; i++) - width += colWidths->get (col + i); - width = misc::max (width, 0); - - if (child != actualChild) { - // For table cells (direct children: child == actualChild), - // CSS 'width' is already regarded in the column calculation. - // However, for children of the table cells, CSS 'width' must - // be regarded here. - - int corrWidth = width; - child->calcFinalWidth (child->getStyle(), -1, this, 0, true, - &corrWidth); - - // But better not exceed it ... (TODO: Only here?) - width = misc::min (width, corrWidth); - } - } - } + // ActualChild->parentRef contains the position in the children + // array (see addCell()), so the column can be easily determined. + int col = actualChild->parentRef % numCols; + int colspanEff = children->get(actualChild->parentRef)->cell.colspanEff; + DBG_OBJ_MSGF ("resize", 1, "calculated from column %d, colspanEff = %d", + col, colspanEff); + + int width = (colspanEff - 1) * getStyle()->hBorderSpacing; + for (int i = 0; i < colspanEff; i++) + width += colWidths->get (col + i); + width = misc::max (width, 0); + + if (child != actualChild) { + // For table cells (direct children: child == actualChild), CSS + // 'width' is already regarded in the column calculation. + // However, for children of the table cells, CSS 'width' must be + // regarded here. + + int corrWidth = width; + child->calcFinalWidth (child->getStyle(), -1, this, 0, true, &corrWidth); + + // But better not exceed it ... (TODO: Only here?) + width = misc::min (width, corrWidth); } - assert (width != -1); - DBG_OBJ_MSGF ("resize", 1, "=> %d", width); DBG_OBJ_LEAVE (); return width; @@ -563,6 +575,12 @@ void Table::addCell (Widget *widget, int colspan, int rowspan) child->cell.rowspan = rowspan; children->set (curRow * numCols + curCol, child); + // The position in the children array is assigned to parentRef, + // although incremental resizing is not implemented. Useful, e. g., + // in calcAvailWidthForDescendant(). See also reallocChildren(). + widget->parentRef = curRow * numCols + curCol; + DBG_OBJ_SET_NUM_O (widget, "parentRef", widget->parentRef); + curCol += colspanEff; widget->parentRef = makeParentRefInFlow (0); @@ -799,9 +817,35 @@ void Table::reallocChildren (int newNumCols, int newNumRows) rowStyle->set (row, NULL); // Rest is increased, when needed. + if (newNumCols > numCols) { + // Re-calculate parentRef. See addCell(). + for (int row = 1; row < newNumRows; row++) + for (int col = 0; col < newNumCols; col++) { + int n = row * newNumCols + col; + Child *child = children->get (n); + if (child != NULL && child->type == Child::CELL) { + child->cell.widget->parentRef = n; + DBG_OBJ_SET_NUM_O (child->cell.widget, "parentRef", + child->cell.widget->parentRef); + } + } + } + numCols = newNumCols; numRows = newNumRows; + // We initiate the column widths with a random value, to have a + // defined available width for the children before the column + // widths are actually calculated. + + colWidths->setSize (numCols, 100); + + DBG_IF_RTFL { + DBG_OBJ_SET_NUM ("colWidths.size", colWidths->size ()); + for (int i = 0; i < colWidths->size (); i++) + DBG_OBJ_ARRSET_NUM ("colWidths", i, colWidths->get (i)); + } + DBG_OBJ_SET_NUM ("numCols", numCols); DBG_OBJ_SET_NUM ("numRows", numCols); } @@ -826,6 +870,64 @@ void Table::calcCellSizes (bool calcHeights) void Table::forceCalcCellSizes (bool calcHeights) { + // Since Table::getAvailWidthOfChild does not calculate the column + // widths, and so initially a random value (100) is returned, a + // correction is necessary. The old values are temporary preserved + // ... + + lout::misc::SimpleVector<int> oldColWidths (8); + oldColWidths.setSize (colWidths->size ()); + colWidths->copyTo (&oldColWidths); + + actuallyCalcCellSizes (calcHeights); + + // ... and then compared to the new ones. In case of a difference, + // the cell is told about this. + + for (int col = 0; col < colWidths->size (); col++) { + if (oldColWidths.get (col) != colWidths->get (col)) { + for (int row = 0; row < numRows; row++) { + int n = row * numCols + col, col2; + Child *child = children->get(n); + if (child) { + Widget *cell; + switch (child->type) { + case Child::CELL: + cell = child->cell.widget; + break; + + case Child::SPAN_SPACE: + // TODO Are Child::spanSpace::startRow and + // Child::spanSpace::startCol not defined? + + // Search for actual cell. If not found, this means + // that a cell is spanning multiple columns *and* + // rows; in this case it has been processed before. + + cell = NULL; + for (col2 = col - 1; col2 >= 0 && cell == NULL; col2--) { + int n2 = row * numCols + col2; + Child *child2 = children->get(n2); + if (child2 != NULL && child2->type == Child::CELL) + cell = child2->cell.widget; + } + break; + + default: + misc::assertNotReached (); + cell = NULL; + } + + if (cell) + cell->containerSizeChanged (); + } + } + } + } +} + +void Table::actuallyCalcCellSizes (bool calcHeights) +{ DBG_OBJ_ENTER0 ("resize", 0, "forceCalcCellSizes"); int childHeight; @@ -835,10 +937,10 @@ void Table::forceCalcCellSizes (bool calcHeights) getExtremes (&extremes); int availWidth = getAvailWidth (true); - // When adjust_table_min_width is set, use the minimal (intrinsic) - // width for correction. + // When adjust_table_min_width is set, use perhaps the adjustment + // width for correction. (TODO: Is this necessary?) int corrWidth = - Table::getAdjustTableMinWidth () ? extremes.minWidthIntrinsic : 0; + Table::getAdjustTableMinWidth () ? extremes.adjustmentWidth : 0; int totalWidth = misc::max (availWidth, corrWidth) - ((numCols + 1) * getStyle()->hBorderSpacing + boxDiffWidth ()); @@ -847,13 +949,14 @@ void Table::forceCalcCellSizes (bool calcHeights) availWidth, corrWidth, numCols, getStyle()->hBorderSpacing, boxDiffWidth (), totalWidth); - colWidths->setSize (numCols, 0); + assert (colWidths->size () == numCols); // This is set in addCell. cumHeight->setSize (numRows + 1, 0); rowSpanCells->setSize (0); baseline->setSize (numRows); misc::SimpleVector<int> *oldColWidths = colWidths; colWidths = new misc::SimpleVector <int> (8); + colWidths->setSize (numCols); int minWidth = 0, minWidthIntrinsic = 0, maxWidth = 0; for (int col = 0; col < colExtremes->size(); col++) { @@ -924,8 +1027,6 @@ void Table::forceCalcCellSizes (bool calcHeights) } else { DBG_OBJ_MSG ("resize", 1, "case 1b: treat percentages specially"); - colWidths->setSize (colExtremes->size(), 0); - // Keep track of the width which is apportioned to the rest // of the columns with percentage width (widthPartPer), and // the minimal width (intrinsic minimum) which is needed for @@ -1048,7 +1149,6 @@ void Table::forceCalcCellSizes (bool calcHeights) DBG_OBJ_MSG ("resize", 1, "finally setting column widths:"); DBG_OBJ_MSG_START (); - colWidths->setSize (colExtremes->size()); indexNotSpecified = 0; for (int col = 0; col < colExtremes->size(); col++) if (colWidthSpecified->get (col)) { @@ -1253,6 +1353,7 @@ void Table::forceCalcColumnExtremes () colExtremes->getRef(col)->minWidthIntrinsic = 0; colExtremes->getRef(col)->maxWidth = 0; colExtremes->getRef(col)->maxWidthIntrinsic = 0; + colExtremes->getRef(col)->adjustmentWidth = 0; for (int row = 0; row < numRows; row++) { DBG_OBJ_MSGF ("resize", 1, "row %d", row); @@ -1284,6 +1385,10 @@ void Table::forceCalcColumnExtremes () colExtremes->getRef(col)->maxWidth, cellExtremes.maxWidth); + colExtremes->getRef(col)->adjustmentWidth = + misc::max (colExtremes->getRef(col)->adjustmentWidth, + cellExtremes.adjustmentWidth); + core::style::Length childWidth = children->get(n)->cell.widget->getStyle()->width; if (childWidth != core::style::LENGTH_AUTO) { @@ -1322,9 +1427,10 @@ void Table::forceCalcColumnExtremes () core::Extremes cellExtremes; children->get(n)->cell.widget->getExtremes (&cellExtremes); - calcExtremesSpanMulteCols (col, cs, &cellExtremes, MIN, MAX, NULL); - calcExtremesSpanMulteCols (col, cs, &cellExtremes, MIN_INTR, MAX_INTR, + calcExtremesSpanMultiCols (col, cs, &cellExtremes, MIN, MAX, NULL); + calcExtremesSpanMultiCols (col, cs, &cellExtremes, MIN_INTR, MAX_INTR, NULL); + calcAdjustmentWidthSpanMultiCols (col, cs, &cellExtremes); core::style::Length childWidth = children->get(n)->cell.widget->getStyle()->width; @@ -1380,7 +1486,7 @@ void Table::forceCalcColumnExtremes () DBG_OBJ_LEAVE (); } -void Table::calcExtremesSpanMulteCols (int col, int cs, +void Table::calcExtremesSpanMultiCols (int col, int cs, core::Extremes *cellExtremes, ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData) @@ -1431,6 +1537,28 @@ void Table::calcExtremesSpanMulteCols (int col, int cs, DBG_OBJ_LEAVE (); } +void Table::calcAdjustmentWidthSpanMultiCols (int col, int cs, + core::Extremes *cellExtremes) +{ + DBG_OBJ_ENTER ("resize", 0, "calcAdjustmentWidthSpanMultiCols", + "%d, %d, ...", col, cs); + + int sumAdjustmentWidth = 0; + for (int j = 0; j < cs; j++) + sumAdjustmentWidth += colExtremes->getRef(col + j)->adjustmentWidth; + + if (cellExtremes->adjustmentWidth > sumAdjustmentWidth) { + misc::SimpleVector<int> newAdjustmentWidth; + apportion2 (cellExtremes->adjustmentWidth, col, col + cs - 1, MIN, MAX, + NULL, &newAdjustmentWidth, 0); + for (int j = 0; j < cs; j++) + colExtremes->getRef(col + j)->adjustmentWidth = + newAdjustmentWidth.get (j); + } + + DBG_OBJ_LEAVE (); +} + /** * \brief Actual apportionment function. */ diff --git a/dw/table.hh b/dw/table.hh index 2ad56447..1a12cb60 100644 --- a/dw/table.hh +++ b/dw/table.hh @@ -434,14 +434,17 @@ private: void calcCellSizes (bool calcHeights); void forceCalcCellSizes (bool calcHeights); + void actuallyCalcCellSizes (bool calcHeights); void apportionRowSpan (); void _unused_calcColumnExtremes (); void forceCalcColumnExtremes (); - void calcExtremesSpanMulteCols (int col, int cs, + void calcExtremesSpanMultiCols (int col, int cs, core::Extremes *cellExtremes, ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData); + void calcAdjustmentWidthSpanMultiCols (int col, int cs, + core::Extremes *cellExtremes); void apportion2 (int totalWidth, int firstCol, int lastCol, ExtrMod minExtrMod, ExtrMod maxExtrMod, void *extrData, diff --git a/dw/tablecell.cc b/dw/tablecell.cc index 5c34c781..3e143c96 100644 --- a/dw/tablecell.cc +++ b/dw/tablecell.cc @@ -98,7 +98,8 @@ void correctCorrectedRequisitionOfChild (core::Widget *widget, } void correctCorrectedExtremesOfChild (core::Widget *widget, core::Widget *child, - core::Extremes *extremes) + core::Extremes *extremes, + bool useAdjustmentWidth) { // Something to do? } diff --git a/dw/tablecell.hh b/dw/tablecell.hh index f7936203..1300a944 100644 --- a/dw/tablecell.hh +++ b/dw/tablecell.hh @@ -7,6 +7,8 @@ namespace dw { namespace tablecell { +inline bool mustBeWidenedToAvailWidth () { return true; } + bool getAdjustMinWidth (); bool isBlockLevel (); @@ -21,7 +23,8 @@ void correctCorrectedRequisitionOfChild (core::Widget *widget, void (*splitHeightFun) (int, int*, int*)); void correctCorrectedExtremesOfChild (core::Widget *widget, core::Widget *child, - core::Extremes *extremes); + core::Extremes *extremes, + bool useAdjustmentWidth); int applyPerWidth (core::Widget *widget, int containerWidth, core::style::Length perWidth); diff --git a/dw/textblock.cc b/dw/textblock.cc index 250c12d6..00968c61 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -434,7 +434,8 @@ void Textblock::getWordExtremes (Word *word, core::Extremes *extremes) word->content.widget->getExtremes (extremes); else extremes->minWidth = extremes->minWidthIntrinsic = extremes->maxWidth = - extremes->maxWidthIntrinsic = word->size.width; + extremes->maxWidthIntrinsic = extremes->adjustmentWidth = + word->size.width; } void Textblock::getExtremesImpl (core::Extremes *extremes) @@ -462,12 +463,14 @@ void Textblock::getExtremesImpl (core::Extremes *extremes) extremes->minWidthIntrinsic = 0; extremes->maxWidth = 0; extremes->maxWidthIntrinsic = 0; + extremes->adjustmentWidth = 0; } else { Paragraph *lastPar = paragraphs->getLastRef (); extremes->minWidth = lastPar->maxParMin; extremes->minWidthIntrinsic = lastPar->maxParMinIntrinsic; extremes->maxWidth = lastPar->maxParMax; extremes->maxWidthIntrinsic = lastPar->maxParMaxIntrinsic; + extremes->adjustmentWidth = lastPar->maxParAdjustmentWidth; DBG_OBJ_MSGF ("resize", 1, "paragraphs[%d]->maxParMin = %d (%d)", paragraphs->size () - 1, lastPar->maxParMin, @@ -486,6 +489,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes) extremes->minWidthIntrinsic += diff; extremes->maxWidth += diff; extremes->maxWidthIntrinsic += diff; + extremes->adjustmentWidth += diff; DBG_OBJ_MSGF ("resize", 0, "after adding diff: %d (%d) / %d (%d)", extremes->minWidth, extremes->minWidthIntrinsic, @@ -493,7 +497,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes) // For the order, see similar reasoning in sizeRequestImpl. - correctExtremes (extremes); + correctExtremes (extremes, true); DBG_OBJ_MSGF ("resize", 0, "after correction: %d (%d) / %d (%d)", extremes->minWidth, extremes->minWidthIntrinsic, @@ -2947,6 +2951,27 @@ void Textblock::queueDrawRange (int index1, int index2) DBG_OBJ_LEAVE (); } +bool Textblock::mustBeWidenedToAvailWidth () +{ + DBG_OBJ_ENTER0 ("resize", 0, "mustBeWidenedToAvailWidth"); + bool toplevel = getParent () == NULL, + block = getStyle()->display == core::style::DISPLAY_BLOCK, + vloat = testWidgetFloat (this), + abspos = testWidgetAbsolutelyPositioned (this), + fixpos = testWidgetFixedlyPositioned (this), + // In detail, this depends on what the respective OOFM does + // with the child widget: + result = toplevel || (block && !(vloat || abspos || fixpos)); + DBG_OBJ_MSGF ("resize", 0, + "=> %s (toplevel: %s, block: %s, float: %s, abspos: %s, " + "fixpos: %s)", + result ? "true" : "false", toplevel ? "true" : "false", + block ? "true" : "false", vloat ? "true" : "false", + abspos ? "true" : "false", fixpos ? "true" : "false"); + DBG_OBJ_LEAVE (); + return result; +} + /** * Called by dw::OOFFloatsMgr when the border has changed due to a * float (or some floats). @@ -3136,48 +3161,49 @@ bool Textblock::isPossibleContainerParent (int oofmIndex) return true; } -Textblock *Textblock::getTextblockForLine (Line *line) +RegardingBorder *Textblock::getWidgetRegardingBorderForLine (Line *line) { - return getTextblockForLine (line->firstWord, line->lastWord); + return getWidgetRegardingBorderForLine (line->firstWord, line->lastWord); } -Textblock *Textblock::getTextblockForLine (int lineNo) +RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int lineNo) { // Can also be used for a line not yet existing. int firstWord = lineNo == 0 ? 0 : lines->getRef(lineNo - 1)->lastWord + 1; int lastWord = lineNo < lines->size() ? lines->getRef(lineNo)->lastWord : words->size() - 1; - return getTextblockForLine (firstWord, lastWord); + return getWidgetRegardingBorderForLine (firstWord, lastWord); } -Textblock *Textblock::getTextblockForLine (int firstWord, int lastWord) +RegardingBorder *Textblock::getWidgetRegardingBorderForLine (int firstWord, + int lastWord) { - DBG_OBJ_ENTER ("resize", 0, "getTextblockForLine", "%d, %d", + DBG_OBJ_ENTER ("resize", 0, "getWidgetRegardingBorderForLine", "%d, %d", firstWord, lastWord); DBG_OBJ_MSGF ("resize", 1, "words.size = %d", words->size ()); - Textblock *textblock = NULL; + RegardingBorder *widgetRegardingBorder = NULL; if (firstWord < words->size ()) { - // A textblock is always between two line breaks, and so the - // first word of the line. + // Any instance of a subclass of WidgetRegardingBorder is always + // between two line breaks, and so the first word of the line. Word *word = words->getRef (firstWord); DBG_MSG_WORD ("resize", 1, "<i>first word:</i> ", firstWord, ""); if (word->content.type == core::Content::WIDGET_IN_FLOW) { Widget *widget = word->content.widget; - if (widget->instanceOf (Textblock::CLASS_ID) && + if (widget->instanceOf (RegardingBorder::CLASS_ID) && // Exclude cases where a textblock constitutes a new floats // container. !isOOFContainer (widget, OOFM_FLOATS)) - textblock = (Textblock*)widget; + widgetRegardingBorder = (RegardingBorder*)widget; } } - DBG_OBJ_MSGF ("resize", 1, "=> %p", textblock); + DBG_OBJ_MSGF ("resize", 1, "=> %p", widgetRegardingBorder); DBG_OBJ_LEAVE (); - return textblock; + return widgetRegardingBorder; } /** diff --git a/dw/textblock.hh b/dw/textblock.hh index 0834e183..143cede3 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -3,7 +3,7 @@ #include <limits.h> -#include "oofawarewidget.hh" +#include "regardingborder.hh" #include "../lout/misc.hh" // These were used when improved line breaking and hyphenation were implemented. @@ -200,7 +200,7 @@ namespace dw { * - dw::oof::OOFAwareWidget (base class) and * - \ref dw-out-of-flow. */ -class Textblock: public oof::OOFAwareWidget +class Textblock: public RegardingBorder { private: /** @@ -353,6 +353,7 @@ protected: hyphen width etc.) since the last possible break within this paragraph. */ int parMinIntrinsic; + int parAdjustmentWidth; int parMax; /* The sum of all word maxima in this paragraph (plus spaces, hyphen width etc.). */ @@ -361,6 +362,7 @@ protected: int maxParMin; /* Maximum of all paragraph minima (value of "parMin"), including this paragraph. */ int maxParMinIntrinsic; + int maxParAdjustmentWidth; int maxParMax; /* Maximum of all paragraph maxima (value of "parMax""), including this paragraph. */ int maxParMaxIntrinsic; @@ -689,12 +691,12 @@ protected: */ inline bool mustBorderBeRegarded (Line *line) { - return getTextblockForLine (line) == NULL; + return getWidgetRegardingBorderForLine (line) == NULL; } inline bool mustBorderBeRegarded (int lineNo) { - return getTextblockForLine (lineNo) == NULL; + return getWidgetRegardingBorderForLine (lineNo) == NULL; } inline int _lineYOffsetWidgetAllocation (Line *line, @@ -759,9 +761,10 @@ protected: } } - Textblock *getTextblockForLine (Line *line); - Textblock *getTextblockForLine (int lineNo); - Textblock *getTextblockForLine (int firstWord, int lastWord); + RegardingBorder *getWidgetRegardingBorderForLine (Line *line); + RegardingBorder *getWidgetRegardingBorderForLine (int lineNo); + RegardingBorder *getWidgetRegardingBorderForLine (int firstWord, + int lastWord); void printBorderChangedErrorAndAbort (int y, Widget *vloat, int wrapLineIndex); int yOffsetOfLineToBeCreated (); @@ -850,29 +853,6 @@ protected: int numBreaks, int *breakPos, core::Requisition *wordSize); - inline bool mustBeWidenedToAvailWidth () { - DBG_OBJ_ENTER0 ("resize", 0, "mustBeWidenedToAvailWidth"); - bool toplevel = getParent () == NULL, - block = getStyle()->display == core::style::DISPLAY_BLOCK, - listitem = getStyle()->display == core::style::DISPLAY_LIST_ITEM, - vloat = testWidgetFloat (this), - abspos = testWidgetAbsolutelyPositioned (this), - fixpos = testWidgetFixedlyPositioned (this), - // In detail, this depends on what the respective OOFM does - // with the child widget: - result = - toplevel || ((block || listitem) && !(vloat || abspos || fixpos)); - DBG_OBJ_MSGF ("resize", 0, - "=> %s (toplevel: %s, block: %s, listitem: %s, float: %s, " - "abspos: %s, fixpos: %s)", - result ? "true" : "false", toplevel ? "true" : "false", - block ? "true" : "false", listitem ? "true" : "false", - vloat ? "true" : "false", abspos ? "true" : "false", - fixpos ? "true" : "false"); - DBG_OBJ_LEAVE (); - return result; - } - public: static int CLASS_ID; @@ -905,6 +885,7 @@ public: void changeWordStyle (int from, int to, core::style::Style *style, bool includeFirstSpace, bool includeLastSpace); + bool mustBeWidenedToAvailWidth (); void borderChanged (int y, core::Widget *vloat); void clearPositionChanged (); void oofSizeChanged (bool extremesChanged); diff --git a/dw/textblock_linebreaking.cc b/dw/textblock_linebreaking.cc index 666a38f8..a987d62f 100644 --- a/dw/textblock_linebreaking.cc +++ b/dw/textblock_linebreaking.cc @@ -435,6 +435,15 @@ Textblock::Line *Textblock::addLine (int firstWord, int lastWord, word->effSpace, word->origSpace, i, lineWidth); } + // Until here, lineWidth refers does not include floats on the left + // side. To include left floats, so that maxLineWidth, and + // eventually the requisition, is correct, line->textOffset has to + // be added, which was calculated just before in calcTextOffset(). + // The correction in sizeAllocateImpl() is irrelevant in this + // regard. Also, right floats are not regarded here, but in + // OutOfFlowMgr::getSize(), + //lineWidth += line->textOffset; -- TODO: Does not work! + if (lines->size () == 1) { // first line line->maxLineWidth = lineWidth; @@ -1259,17 +1268,18 @@ void Textblock::handleWordExtremes (int wordIndex) Paragraph *par = paragraphs->getLastRef(); par->firstWord = par->lastWord = wordIndex; - par->parMin = par->parMinIntrinsic = par->parMax = par->parMaxIntrinsic - = 0; + par->parMin = par->parMinIntrinsic = par->parMax = par->parMaxIntrinsic = + par->parAdjustmentWidth = 0; if (prevPar) { par->maxParMin = prevPar->maxParMin; par->maxParMinIntrinsic = prevPar->maxParMinIntrinsic; par->maxParMax = prevPar->maxParMax; par->maxParMaxIntrinsic = prevPar->maxParMaxIntrinsic; + par->maxParAdjustmentWidth = prevPar->maxParAdjustmentWidth; } else par->maxParMin = par->maxParMinIntrinsic = par->maxParMax = - par->maxParMaxIntrinsic = 0; + par->maxParMaxIntrinsic = par->maxParAdjustmentWidth = 0; DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "maxParMin", par->maxParMin); @@ -1301,9 +1311,13 @@ void Textblock::handleWordExtremes (int wordIndex) lastPar->parMin += wordExtremes.minWidth + word->hyphenWidth + corrDiffMin; lastPar->parMinIntrinsic += wordExtremes.minWidthIntrinsic + word->hyphenWidth + corrDiffMin; + lastPar->parAdjustmentWidth += + wordExtremes.adjustmentWidth + word->hyphenWidth + corrDiffMin; lastPar->maxParMin = misc::max (lastPar->maxParMin, lastPar->parMin); lastPar->maxParMinIntrinsic = misc::max (lastPar->maxParMinIntrinsic, lastPar->parMinIntrinsic); + lastPar->maxParAdjustmentWidth = + misc::max (lastPar->maxParAdjustmentWidth, lastPar->parAdjustmentWidth); DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "parMin", lastPar->parMin); @@ -1313,15 +1327,24 @@ void Textblock::handleWordExtremes (int wordIndex) lastPar->maxParMin); DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "maxParMinIntrinsic", lastPar->maxParMinIntrinsic); + DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, + "parAdjustmentWidth", lastPar->parAdjustmentWidth); + DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, + "maxParAdjustmentWidth", + lastPar->maxParAdjustmentWidth); if (word->badnessAndPenalty.lineCanBeBroken (1) && (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) { - lastPar->parMin = lastPar->parMinIntrinsic = 0; + lastPar->parMin = lastPar->parMinIntrinsic = lastPar->parAdjustmentWidth + = 0; DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "parMin", lastPar->parMin); DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, "parMinIntrinsic", lastPar->parMinIntrinsic); + DBG_OBJ_ARRATTRSET_NUM ("paragraphs", paragraphs->size() - 1, + "parAdjustmentWidth", + lastPar->parAdjustmentWidth); } // Maximum: between two *necessary* breaks. @@ -1354,8 +1377,9 @@ void Textblock::correctLastWordExtremes () Word *word = words->getLastRef (); if (word->badnessAndPenalty.lineCanBeBroken (1) && (word->flags & Word::UNBREAKABLE_FOR_MIN_WIDTH) == 0) { - paragraphs->getLastRef()->parMin = - paragraphs->getLastRef()->parMinIntrinsic = 0; + Paragraph *lastPar = paragraphs->getLastRef(); + lastPar->parMin = lastPar->parMinIntrinsic = + lastPar->parAdjustmentWidth = 0; PRINTF (" => corrected; parMin = %d\n", paragraphs->getLastRef()->parMin); } diff --git a/dw/types.hh b/dw/types.hh index 081b8db4..87f688aa 100644 --- a/dw/types.hh +++ b/dw/types.hh @@ -182,6 +182,7 @@ struct Extremes int maxWidth; int minWidthIntrinsic; int maxWidthIntrinsic; + int adjustmentWidth; }; struct Content @@ -56,7 +56,9 @@ void Embed::sizeRequestImpl (Requisition *requisition) void Embed::getExtremesImpl (Extremes *extremes) { resource->getExtremes (extremes); - correctExtremes (extremes); + correctExtremes (extremes, false); + extremes->adjustmentWidth = + misc::max (extremes->minWidthIntrinsic, extremes->minWidth); } void Embed::sizeAllocateImpl (Allocation *allocation) @@ -81,9 +83,10 @@ void Embed::correctRequisitionOfChild (Widget *child, resource->correctRequisitionOfChild (child, requisition, splitHeightFun); } -void Embed::correctExtremesOfChild (Widget *child, Extremes *extremes) +void Embed::correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth) { - resource->correctExtremesOfChild (child, extremes); + resource->correctExtremesOfChild (child, extremes, useAdjustmentWidth); } void Embed::containerSizeChangedForChildren () @@ -249,7 +252,8 @@ void Resource::correctRequisitionOfChild (Widget *child, misc::assertNotReached (); } -void Resource::correctExtremesOfChild (Widget *child, Extremes *extremes) +void Resource::correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth) { // Only used when the resource contains other dillo widgets. misc::assertNotReached (); @@ -439,7 +443,8 @@ void ComplexButtonResource::correctRequisitionOfChild (Widget *child, } void ComplexButtonResource::correctExtremesOfChild (Widget *child, - Extremes *extremes) + Extremes *extremes, + bool useAdjustmentWidth) { // Similar to Widget::correctExtremesOfChild, but for percentage // the relief has to be considered. @@ -455,7 +460,8 @@ void ComplexButtonResource::correctExtremesOfChild (Widget *child, child->applyPerWidth (baseWidth, child->getStyle()->width); } } else - getEmbed()->correctExtremesOfChildNoRec (child, extremes); + getEmbed()->correctExtremesOfChildNoRec (child, extremes, + useAdjustmentWidth); } void ComplexButtonResource::containerSizeChangedForChildren () @@ -237,7 +237,8 @@ protected: void correctRequisitionOfChild (Widget *child, Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - void correctExtremesOfChild (Widget *child, Extremes *extremes); + void correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth); void containerSizeChangedForChildren (); @@ -270,8 +271,9 @@ public: int*)) { Widget::correctReqHeightOfChild (child, requisition, splitHeightFun); } - virtual void correctExtremesOfChildNoRec (Widget *child, Extremes *extremes) - { Widget::correctExtremesOfChild (child, extremes); } + virtual void correctExtremesOfChildNoRec (Widget *child, Extremes *extremes, + bool useAdjustmentWidth) + { Widget::correctExtremesOfChild (child, extremes, useAdjustmentWidth); } }; /** @@ -363,7 +365,8 @@ public: Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - virtual void correctExtremesOfChild (Widget *child, Extremes *extremes); + virtual void correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth); virtual void containerSizeChangedForChildren (); virtual void setDisplayed (bool displayed); @@ -439,7 +442,8 @@ public: void correctRequisitionOfChild (Widget *child, Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - void correctExtremesOfChild (Widget *child, Extremes *extremes); + void correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth); void containerSizeChangedForChildren (); Iterator *iterator (Content::Type mask, bool atEnd); diff --git a/dw/widget.cc b/dw/widget.cc index d5c856d2..8f93701d 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -734,18 +734,18 @@ void Widget::sizeRequest (Requisition *requisition) * context of correctExtemes etc., to avoid cyclic dependencies. * */ -int Widget::getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue) -{ - if (extremes) - DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "[%d (%d) / %d (%d), %s, %s", - extremes->minWidth, extremes->minWidthIntrinsic, - extremes->maxWidth, extremes->maxWidthIntrinsic, - useCorrected ? "true" : "false", - forceValue ? "true" : "false"); - else - DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "(nil), %s, %s", - useCorrected ? "true" : "false", - forceValue ? "true" : "false"); +int Widget::getMinWidth (Extremes *extremes, bool forceValue) +{ + DBG_IF_RTFL { + if (extremes) + DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "[%d (%d) / %d (%d), %s", + extremes->minWidth, extremes->minWidthIntrinsic, + extremes->maxWidth, extremes->maxWidthIntrinsic, + forceValue ? "true" : "false"); + else + DBG_OBJ_ENTER ("resize", 0, "getMinWidth", "(nil), %s", + forceValue ? "true" : "false"); + } int minWidth; @@ -761,13 +761,9 @@ int Widget::getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue) // TODO Not completely clear whether this is feasable: Within // the context of getAvailWidth(false) etc., getExtremes may not // be called. We ignore the minimal width then. - if (extremes) { - if (useCorrected) - minWidth = - misc::max (extremes->minWidth, extremes->minWidthIntrinsic); - else - minWidth = extremes->minWidthIntrinsic; - } else + if (extremes) + minWidth = extremes->adjustmentWidth; + else minWidth = 0; } else minWidth = 0; @@ -894,7 +890,7 @@ void Widget::correctRequisition (Requisition *requisition, DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport"); DBG_OBJ_MSG_START (); - int limitMinWidth = getMinWidth (NULL, true, true); + int limitMinWidth = getMinWidth (NULL, true); int viewportWidth = layout->viewportWidth - (layout->canvasHeightGreater ? layout->vScrollbarThickness : 0); @@ -941,7 +937,7 @@ void Widget::correctRequisition (Requisition *requisition, DBG_OBJ_LEAVE (); } -void Widget::correctExtremes (Extremes *extremes) +void Widget::correctExtremes (Extremes *extremes, bool useAdjustmentWidth) { DBG_OBJ_ENTER ("resize", 0, "correctExtremes", "%d (%d) / %d (%d)", extremes->minWidth, extremes->minWidthIntrinsic, @@ -951,7 +947,8 @@ void Widget::correctExtremes (Extremes *extremes) DBG_OBJ_MSG ("resize", 1, "no parent, regarding viewport"); DBG_OBJ_MSG_START (); - int limitMinWidth = getMinWidth (extremes, false, false); + int limitMinWidth = + useAdjustmentWidth ? getMinWidth (extremes, false) : 0; int viewportWidth = layout->viewportWidth - (layout->canvasHeightGreater ? layout->vScrollbarThickness : 0); @@ -977,12 +974,12 @@ void Widget::correctExtremes (Extremes *extremes) } else if (parent) { DBG_OBJ_MSG ("resize", 1, "delegated to parent"); DBG_OBJ_MSG_START (); - parent->correctExtremesOfChild (this, extremes); + parent->correctExtremesOfChild (this, extremes, useAdjustmentWidth); DBG_OBJ_MSG_END (); } else /* if (quasiParent) */ { DBG_OBJ_MSG ("resize", 1, "delegated to quasiParent"); DBG_OBJ_MSG_START (); - quasiParent->correctExtremesOfChild (this, extremes); + quasiParent->correctExtremesOfChild (this, extremes, useAdjustmentWidth); DBG_OBJ_MSG_END (); } @@ -1153,6 +1150,7 @@ void Widget::getExtremes (Extremes *extremes) DBG_OBJ_SET_NUM ("extremes.maxWidth", extremes->maxWidth); DBG_OBJ_SET_NUM ("extremes.maxWidthIntrinsic", extremes->maxWidthIntrinsic); + DBG_OBJ_SET_NUM ("extremes.adjustmentWidth", extremes->adjustmentWidth); } else *extremes = this->extremes; @@ -1835,7 +1833,7 @@ void Widget::correctReqWidthOfChild (Widget *child, Requisition *requisition) assert (this == child->quasiParent || this == child->container); - int limitMinWidth = child->getMinWidth (NULL, true, true); + int limitMinWidth = child->getMinWidth (NULL, true); child->calcFinalWidth (child->getStyle(), -1, this, limitMinWidth, false, &requisition->width); @@ -1881,7 +1879,8 @@ void Widget::correctReqHeightOfChild (Widget *child, Requisition *requisition, DBG_OBJ_LEAVE (); } -void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes) +void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth) { // See comment in correctRequisitionOfChild. @@ -1895,7 +1894,8 @@ void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes) (child->container ? child->container : child->parent); if (effContainer == this) { - int limitMinWidth = child->getMinWidth (extremes, false, false); + int limitMinWidth = + useAdjustmentWidth ? child->getMinWidth (extremes, false) : 0; int width = child->calcWidth (child->getStyle()->width, -1, this, limitMinWidth, false); int minWidth = child->calcWidth (child->getStyle()->minWidth, -1, this, @@ -1915,7 +1915,8 @@ void Widget::correctExtremesOfChild (Widget *child, Extremes *extremes) } else { DBG_OBJ_MSG ("resize", 1, "delegated to (effective) container"); DBG_OBJ_MSG_START (); - effContainer->correctExtremesOfChild (child, extremes); + effContainer->correctExtremesOfChild (child, extremes, + useAdjustmentWidth); DBG_OBJ_MSG_END (); } diff --git a/dw/widget.hh b/dw/widget.hh index a14cd55b..b1b51201 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -319,7 +319,8 @@ protected: void correctReqWidthOfChild (Widget *child, Requisition *requisition); void correctReqHeightOfChild (Widget *child, Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - virtual void correctExtremesOfChild (Widget *child, Extremes *extremes); + virtual void correctExtremesOfChild (Widget *child, Extremes *extremes, + bool useAdjustmentWidth); virtual void containerSizeChangedForChildren (); @@ -448,7 +449,7 @@ public: virtual bool getAdjustMinWidth () { return Widget::adjustMinWidth; } void correctRequisition (Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); - void correctExtremes (Extremes *extremes); + void correctExtremes (Extremes *extremes, bool useAdjustmentWidth); int calcWidth (style::Length cssValue, int refWidth, Widget *refWidget, int limitMinWidth, bool forceValue); void calcFinalWidth (style::Style *style, int refWidth, Widget *refWidget, @@ -459,7 +460,7 @@ public: virtual int applyPerWidth (int containerWidth, style::Length perWidth); virtual int applyPerHeight (int containerHeight, style::Length perHeight); - int getMinWidth (Extremes *extremes, bool useCorrected, bool forceValue); + int getMinWidth (Extremes *extremes, bool forceValue); virtual bool isBlockLevel (); virtual bool isPossibleContainer (); diff --git a/lout/misc.hh b/lout/misc.hh index b362fc2f..a0beb1b6 100644 --- a/lout/misc.hh +++ b/lout/misc.hh @@ -231,6 +231,22 @@ public: assert (this->num > 0); this->array[this->num - 1] = t; } + + /** + * \brief Copies some elements into another vector of the same + * type. + * + * Cannot be used to copy elements within one vector. (For this, + * it would have to be extended to copy backwards in some cases.) + */ + inline void copyTo(SimpleVector<T> *dest, int thisStart = 0, + int thisLast = -1, int destStart = 0) { + assert (dest != this); + if (thisLast == -1) + thisLast = this->size () - 1; + for (int i = thisStart; i <= thisLast; i++) + dest->set (i - thisStart + destStart, get (i)); + } }; /** diff --git a/src/dillo.cc b/src/dillo.cc index 0e49e7b5..1efd3b2c 100644 --- a/src/dillo.cc +++ b/src/dillo.cc @@ -508,6 +508,10 @@ int main(int argc, char **argv) Fl_Window::default_xclass("dillo"); Fl::scheme(prefs.theme); + + // Disable drag and drop as it crashes on MacOSX + Fl::dnd_text_ops(0); + setColors(); if (!prefs.show_ui_tooltip) { diff --git a/src/html.cc b/src/html.cc index be4d3526..8e4f6ded 100644 --- a/src/html.cc +++ b/src/html.cc @@ -357,16 +357,22 @@ bool a_Html_tag_set_valign_attr(DilloHtml *html, const char *tag, int tagsize) /* - * Create and add a new Textblock to the current Textblock + * Create and add a new Textblock to the current Textblock. Typically + * only one of addBreaks and addBreakOpt is true. */ -static void Html_add_textblock(DilloHtml *html, bool addBreaks, int breakSpace) +static void Html_add_textblock(DilloHtml *html, bool addBreaks, int breakSpace, + bool addBreakOpt) { Textblock *textblock = new Textblock (prefs.limit_text_width); if (addBreaks) HT2TB(html)->addParbreak (breakSpace, html->wordStyle ()); + HT2TB(html)->addWidget (textblock, html->style ()); /* Works also for floats etc. */ + if (addBreakOpt) + HT2TB(html)->addBreakOption (html->style (), false); + if (addBreaks) HT2TB(html)->addParbreak (breakSpace, html->wordStyle ()); S_TOP(html)->textblock = html->dw = textblock; @@ -2029,7 +2035,7 @@ static void Html_tag_content_frameset (DilloHtml *html, { HT2TB(html)->addParbreak (9, html->wordStyle ()); HT2TB(html)->addText("--FRAME--", html->wordStyle ()); - Html_add_textblock(html, true, 5); + Html_add_textblock(html, true, 5, false); } /* @@ -2811,7 +2817,7 @@ static void Html_tag_close_a(DilloHtml *html) static void Html_tag_open_blockquote(DilloHtml *html, const char *tag, int tagsize) { - Html_add_textblock(html, true, 9); + Html_add_textblock(html, true, 9, false); } /* @@ -3075,7 +3081,7 @@ static void Html_tag_open_dt(DilloHtml *html, const char *tag, int tagsize) */ static void Html_tag_open_dd(DilloHtml *html, const char *tag, int tagsize) { - Html_add_textblock(html, true, 9); + Html_add_textblock(html, true, 9, false); } /* @@ -3868,12 +3874,13 @@ static void Html_check_html5_obsolete(DilloHtml *html, int ni) static void Html_display_block(DilloHtml *html) { - Html_add_textblock(html, !Html_will_textblock_be_out_of_flow (html), 0); + Html_add_textblock(html, !Html_will_textblock_be_out_of_flow (html), 0, + false /* Perhaps true for widgets oof? */); } static void Html_display_inline_block(DilloHtml *html) { - Html_add_textblock(html, false, 0); + Html_add_textblock(html, false, 0, true); } static void Html_display_listitem(DilloHtml *html) diff --git a/test/dw_simple_container.cc b/test/dw_simple_container.cc index 94dec2d5..c1f22458 100644 --- a/test/dw_simple_container.cc +++ b/test/dw_simple_container.cc @@ -27,183 +27,186 @@ using namespace lout::misc; namespace dw { - int SimpleContainer::CLASS_ID = -1; +int SimpleContainer::CLASS_ID = -1; - // ---------------------------------------------------------------------- +// ---------------------------------------------------------------------- - SimpleContainer::SimpleContainerIterator::SimpleContainerIterator - (SimpleContainer *simpleContainer, Content::Type mask, bool atEnd) : - Iterator (simpleContainer, mask, atEnd) - { - content.type = atEnd ? Content::END : Content::START; - } +SimpleContainer::SimpleContainerIterator::SimpleContainerIterator +(SimpleContainer *simpleContainer, Content::Type mask, bool atEnd) : + Iterator (simpleContainer, mask, atEnd) +{ + content.type = atEnd ? Content::END : Content::START; +} - lout::object::Object *SimpleContainer::SimpleContainerIterator::clone () - { - SimpleContainerIterator *sci = - new SimpleContainerIterator ((SimpleContainer*)getWidget(), - getMask(), false); - sci->content = content; - return sci; - } +lout::object::Object *SimpleContainer::SimpleContainerIterator::clone () +{ + SimpleContainerIterator *sci = + new SimpleContainerIterator ((SimpleContainer*)getWidget(), + getMask(), false); + sci->content = content; + return sci; +} - int SimpleContainer::SimpleContainerIterator::index () - { - switch (content.type) { - case Content::START: - return 0; - case Content::WIDGET_IN_FLOW: - return 1; - case Content::END: - return 2; - default: - assertNotReached (); - return 0; - } +int SimpleContainer::SimpleContainerIterator::index () +{ + switch (content.type) { + case Content::START: + return 0; + case Content::WIDGET_IN_FLOW: + return 1; + case Content::END: + return 2; + default: + assertNotReached (); + return 0; } +} - int SimpleContainer::SimpleContainerIterator::compareTo - (lout::object::Comparable *other) - { - return index () - ((SimpleContainerIterator*)other)->index (); - } +int SimpleContainer::SimpleContainerIterator::compareTo +(lout::object::Comparable *other) +{ + return index () - ((SimpleContainerIterator*)other)->index (); +} - bool SimpleContainer::SimpleContainerIterator::next () - { - SimpleContainer *simpleContainer = (SimpleContainer*)getWidget(); +bool SimpleContainer::SimpleContainerIterator::next () +{ + SimpleContainer *simpleContainer = (SimpleContainer*)getWidget(); - if (content.type == Content::END) - return false; + if (content.type == Content::END) + return false; - // simple containers only contain widgets: - if ((getMask() & Content::WIDGET_IN_FLOW) == 0) { - content.type = Content::END; - return false; - } + // simple containers only contain widgets: + if ((getMask() & Content::WIDGET_IN_FLOW) == 0) { + content.type = Content::END; + return false; + } - if (content.type == Content::START) { - if (simpleContainer->child != NULL) { - content.type = Content::WIDGET_IN_FLOW; - content.widget = simpleContainer->child; - return true; - } else { - content.type = Content::END; - return false; - } - } else /* if (content.type == Content::WIDGET) */ { + if (content.type == Content::START) { + if (simpleContainer->child != NULL) { + content.type = Content::WIDGET_IN_FLOW; + content.widget = simpleContainer->child; + return true; + } else { content.type = Content::END; return false; } + } else /* if (content.type == Content::WIDGET) */ { + content.type = Content::END; + return false; } +} - bool SimpleContainer::SimpleContainerIterator::prev () - { - SimpleContainer *simpleContainer = (SimpleContainer*)getWidget(); +bool SimpleContainer::SimpleContainerIterator::prev () +{ + SimpleContainer *simpleContainer = (SimpleContainer*)getWidget(); - if (content.type == Content::START) - return false; + if (content.type == Content::START) + return false; - // simple containers only contain widgets: - if ((getMask() & Content::WIDGET_IN_FLOW) == 0) { - content.type = Content::START; - return false; - } + // simple containers only contain widgets: + if ((getMask() & Content::WIDGET_IN_FLOW) == 0) { + content.type = Content::START; + return false; + } - if (content.type == Content::END) { - if (simpleContainer->child != NULL) { - content.type = Content::WIDGET_IN_FLOW; - content.widget = simpleContainer->child; - return true; - } else { - content.type = Content::START; - return false; - } - } else /* if (content.type == Content::WIDGET) */ { + if (content.type == Content::END) { + if (simpleContainer->child != NULL) { + content.type = Content::WIDGET_IN_FLOW; + content.widget = simpleContainer->child; + return true; + } else { content.type = Content::START; return false; } + } else /* if (content.type == Content::WIDGET) */ { + content.type = Content::START; + return false; } +} - void SimpleContainer::SimpleContainerIterator::highlight (int start, - int end, - HighlightLayer layer) - { - /** todo Needs this an implementation? */ - } - - void SimpleContainer::SimpleContainerIterator::unhighlight (int direction, - HighlightLayer - layer) - { - /** todo Needs this an implementation? */ - } - - void SimpleContainer::SimpleContainerIterator::getAllocation (int start, - int end, - Allocation - *allocation) - { - /** \bug Not implemented. */ - } - - // ---------------------------------------------------------------------- - - SimpleContainer::SimpleContainer () - { - registerName ("dw::SimpleContainer", &CLASS_ID); - child = NULL; - } +void SimpleContainer::SimpleContainerIterator::highlight (int start, + int end, + HighlightLayer layer) +{ + /** todo Needs this an implementation? */ +} - SimpleContainer::~SimpleContainer () - { - if (child) - delete child; - } +void SimpleContainer::SimpleContainerIterator::unhighlight (int direction, + HighlightLayer + layer) +{ + /** todo Needs this an implementation? */ +} - void SimpleContainer::sizeRequestImpl (Requisition *requisition) - { - Requisition childReq; - if (child) - child->sizeRequest (&childReq); - else - childReq.width = childReq.ascent = childReq.descent = 0; +void SimpleContainer::SimpleContainerIterator::getAllocation (int start, + int end, + Allocation + *allocation) +{ + /** \bug Not implemented. */ +} - requisition->width = childReq.width + boxDiffWidth (); - requisition->ascent = childReq.ascent + boxOffsetY (); - requisition->descent = childReq.descent + boxRestHeight (); +// ---------------------------------------------------------------------- - correctRequisition (requisition, splitHeightPreserveAscent); - } +SimpleContainer::SimpleContainer () +{ + registerName ("dw::SimpleContainer", &CLASS_ID); + child = NULL; +} +SimpleContainer::~SimpleContainer () +{ + if (child) + delete child; +} - void SimpleContainer::getExtremesImpl (Extremes *extremes) - { - Extremes childExtr; - if (child) - child->getExtremes (&childExtr); - else - childExtr.minWidth = childExtr.maxWidth = 0; +void SimpleContainer::sizeRequestImpl (Requisition *requisition) +{ + Requisition childReq; + if (child) + child->sizeRequest (&childReq); + else + childReq.width = childReq.ascent = childReq.descent = 0; - extremes->minWidth = childExtr.minWidth + boxDiffWidth (); - extremes->maxWidth = childExtr.maxWidth + boxDiffWidth (); + requisition->width = childReq.width + boxDiffWidth (); + requisition->ascent = childReq.ascent + boxOffsetY (); + requisition->descent = childReq.descent + boxRestHeight (); - correctExtremes (extremes); - } + correctRequisition (requisition, splitHeightPreserveAscent); +} - void SimpleContainer::sizeAllocateImpl (Allocation *allocation) - { - Allocation childAlloc; +void SimpleContainer::getExtremesImpl (Extremes *extremes) +{ + Extremes childExtr; + if (child) + child->getExtremes (&childExtr); + else + childExtr.minWidth = childExtr.minWidthIntrinsic = childExtr.maxWidth = + childExtr.maxWidthIntrinsic = extremes->adjustmentWidth = 0; + + extremes->minWidth = childExtr.minWidth + boxDiffWidth (); + extremes->minWidthIntrinsic = childExtr.minWidthIntrinsic + boxDiffWidth (); + extremes->maxWidth = childExtr.maxWidth + boxDiffWidth (); + extremes->maxWidthIntrinsic = childExtr.maxWidthIntrinsic + boxDiffWidth (); + extremes->adjustmentWidth = childExtr.adjustmentWidth + boxDiffWidth (); + + correctExtremes (extremes, true); +} - if (child) { - childAlloc.x = allocation->x + boxOffsetX (); - childAlloc.y = allocation->y + boxOffsetY (); - childAlloc.width = allocation->width - boxDiffWidth (); - childAlloc.ascent = allocation->ascent - boxOffsetY (); - childAlloc.descent = allocation->descent - boxRestHeight (); - child->sizeAllocate (&childAlloc); - } +void SimpleContainer::sizeAllocateImpl (Allocation *allocation) +{ + Allocation childAlloc; + + if (child) { + childAlloc.x = allocation->x + boxOffsetX (); + childAlloc.y = allocation->y + boxOffsetY (); + childAlloc.width = allocation->width - boxDiffWidth (); + childAlloc.ascent = allocation->ascent - boxOffsetY (); + childAlloc.descent = allocation->descent - boxRestHeight (); + child->sizeAllocate (&childAlloc); } +} void SimpleContainer::draw (View *view, Rectangle *area, StackingIteratorStack *iteratorStack, |