diff options
Diffstat (limited to 'doc/dw-out-of-flow.doc')
-rw-r--r-- | doc/dw-out-of-flow.doc | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/doc/dw-out-of-flow.doc b/doc/dw-out-of-flow.doc new file mode 100644 index 00000000..1cedbdda --- /dev/null +++ b/doc/dw-out-of-flow.doc @@ -0,0 +1,177 @@ +/** \page dw-out-of-flow Handling Elements Out Of Flow + +<div style="border: 2px solid #ff4040; margin-bottom: 0.5em; +padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b> +Incomplete; some parts have been removed, beause they are not up to +date.</div> + +<div style="border: 2px solid #ffff00; margin-bottom: 0.5em; +padding: 0.5em 1em; background-color: #ffffe0"><b>Info:</b> +Should be incorporated into dw::Textblock.</div> + +This texts deals with both floats and absolute positions, which have +in common, that there is a distinction between generating block and +containing block (we are here using the same notation as in the +CSS 2 specification). Consider this snippet (regarding floats): + + + <ul> + <li>Some text.</li> + <li> + <div style="float:right; width=50%">Some longer text, so + that the effect described in this passage can be + demonstrated. + </div> + Some more and longer text.</li> + <li>Final text. Plus some more to demonstrate how text flows + around the float on the right side.</li> + </ul> + +which may be rendered like this + +\image html dw-floats-01.png + +The float (the DIV section, yellow in the image) is defined +("generated") within the list item (blue), so, in CSS 2 terms, the +list item is the generating block of the float. However, as the image +shows, the float is not contained by the list item, but another block, +several levels above (not shown here). In terms of ::dw, this means +that the dw::Textblock representing the float cannot be a child of the +dw::Textblock representing the generating block, the list item, since +the allocation of a child widget must be within the allocation of the +parent widget. Instead, to each dw::Textblock, another dw::Textblock +is assigned as the containing box. + +(Notice also that other text blocks must regard floats to calculate +their borders, and so their size. In this example, the following list +item (green) must consider the position of the float. This is +discussed in detail in the next section.) + + +Implication for size calculations and allocation +================================================ + +*See also:* \ref dw-widget-sizes + +The size/position model of ::dw consists mainly of the following two +steps: + +1. First, the size of the toplevel widget is calculated. Size + calculation typically depends on the sizes of the widgets, which + are calculated recursively, but not more. +2. After this, the toplevel widget is allocated at position (0, 0), + with the preiosly calculated size. Each widget must allocate its + children, although the condition for the toplevel widget is not + necessary, but each widget may be allocated at every size. + +Especially for floats, this model becomes a bit difficult, for reasons +described below. For the solutions, much is centralized at the level +of the containing block, which delegates most to an instance of +dw::OutOfFlowMgr (details below). + +**The size of a widget depends on the size not only of the children.** +In the example above, the last list item (green, following the +generating list item) must know the size of the the float (which is +not a child or, generally, descendant, but generally the sibling of an +anchestor) to determine the borders, which is done in +dw::Textblock::sizeRequestImpl. + +In this situation, it is important not to call, within +dw::Textblock::sizeRequestImpl of this textblock, +dw::core::Widget::sizeRequest for the float. Instead, ... (?) + +(Actually, dw::Textblock::sizeRequestImpl calls +dw::core::Widget::sizeRequest for the float, which conflicts with the +rules defined in \ref dw-widget-sizes; but actually should not cause +conflicts. Should be revised.) + +**The size of a widget depends on the allocation of another widget.** +In the example above, both list items (blue and green) must know the +position of the float widget, within dw::Textblock::sizeRequestImpl, +to calculate the borders. The position, however, is stored in the +allocation, which is typically calculated later. + +Here, two cases must be distinguished. The position of a float is +always relative to its generating block, so for calculating the +borders for the generating block, the allocation needs not to be +know. For other textblocks, it needs to be known, so the calculation +of the borders will ignore floats generated by other textblocks, until +all widgets are allocated. The latter will call (when neccessary) +dw::core::Widget::queueResize, so that all border calculations are +repeated. + +For details see: + +- dw::OutOfFlowMgr::getLeftBorder, dw::OutOfFlowMgr::getRightBorder, + dw::OutOfFlowMgr::getBorder (called by the first two), and + especially, dw::OutOfFlowMgr::getYWidget (called by the latter), + where these three cases are distinguished; +- dw::OutOfFlowMgr::sizeAllocate, which is called by the containing + block. + +Implementation overview +======================= + +Widget level +------------ + +The terms _generating block_ and _containing block_ have been raised +to a higher level, the one of dw::core::Widget, and are here called +_generating widget_ and _containing widget_. To represent the +distinction, the type of dw::core::Content has been split into three +parts: + +- If a widget is out of flow, the generating widget keeps a reference + with the type dw::core::Content::WIDGET_OOF_REF, while the + containing block refers to it as dw::core::Content::WIDGET_OOF_CONT. + +- For widgets within flow, dw::core::Content::WIDGET_IN_FLOW is used. + +Notice that in the first case, there are two pieces of content +referring to the same widget. + +An application of this distinction is iterators. TODO: more. And still +missing: DeepIterator may need the generating parent widget in some +cases. + + +Textblock level +--------------- +Both dw::Textblock::notifySetAsTopLevel and +dw::Textblock::notifySetParent set the member +dw::Textblock::containingBlock appropriately, (according to rules +which should be defined in this document). + +Handling widgets out of flow is partly the task of the new class +dw::OutOfFlowMgr, which is stored by dw::Textblock::outOfFlowMgr, but +only for containing blocks. Generating blocks should refer to +_containingBlock->outOfFlowMgr_. (Perhaps dw::OutOfFlowMgr may become +independent of dw::Textblock.) + +dw::Textblock::addWidget is extended, so that floats and absolutely +positioned elements can be added. Notice that not this widget, but the +containing block becomes the parent of the newly added child, if it is +out of flow. dw::Textblock::addWidget decides this by calling +dw::OutOfFlowMgr::isOutOfFlow. (See new content types above.) + +dw::core::Widget::parentRef has become a new representation. Before, +it represented the line numer. Now (least signifant bit left): + + +---+---+- - - - - - - - - - -+---+ + | line number | 0 | + +---+---+- - - - - - - - - - -+---+ + + +---+---+- - - - - - - - -+---+---+ + | number of left float | 0 | 1 | + +---+---+- - - - - - - - -+---+---+ + + +---+---+- - - - - - - - -+---+---+ + | number of right float | 1 | 1 | + +---+---+- - - - - - - - -+---+---+ + +The latter two must be changed, as soom as absolute positions are +introduced. Details are hidden by static inline methods of +dw::OutOfFlowMgr. + + +*/
\ No newline at end of file |