aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/Makefile.am3
-rw-r--r--doc/dw-example-screenshot.pngbin3808 -> 2264 bytes
-rw-r--r--doc/dw-floats-01.pngbin0 -> 3410 bytes
-rw-r--r--doc/dw-grows.doc184
-rw-r--r--doc/dw-out-of-flow-2.doc69
-rw-r--r--doc/dw-out-of-flow.doc214
-rw-r--r--doc/dw-size-of-widget.pngbin2825 -> 1749 bytes
-rw-r--r--doc/dw-style-box-model.pngbin5116 -> 3889 bytes
-rw-r--r--doc/dw-style-length-absolute.pngbin756 -> 575 bytes
-rw-r--r--doc/dw-style-length-percentage.pngbin1105 -> 890 bytes
-rw-r--r--doc/dw-style-length-relative.pngbin1083 -> 868 bytes
-rw-r--r--doc/dw-widget-sizes.doc251
-rw-r--r--doc/not-so-simple-container.pngbin13812 -> 5738 bytes
-rw-r--r--doc/user_help.html2
14 files changed, 642 insertions, 81 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index d48e3e73..8ade3d15 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -11,6 +11,8 @@ EXTRA_DIST = \
dw-widget-sizes.doc \
dw-changes.doc \
dw-images-and-backgrounds.doc \
+ dw-dw-out-of-flow.doc \
+ dw-dw-out-of-flow-2.doc \
fltk-problems.doc \
rounding-errors.doc \
uml-legend.doc \
@@ -27,6 +29,7 @@ EXTRA_DIST = \
dw-textblock-collapsing-spaces-1-2.png \
dw-textblock-collapsing-spaces-2-1.png \
dw-textblock-collapsing-spaces-2-2.png \
+ dw-floats-01.png \
not-so-simple-container.png \
Cache.txt \
Cookies.txt \
diff --git a/doc/dw-example-screenshot.png b/doc/dw-example-screenshot.png
index a4d37903..94f272ab 100644
--- a/doc/dw-example-screenshot.png
+++ b/doc/dw-example-screenshot.png
Binary files differ
diff --git a/doc/dw-floats-01.png b/doc/dw-floats-01.png
new file mode 100644
index 00000000..116d36b3
--- /dev/null
+++ b/doc/dw-floats-01.png
Binary files differ
diff --git a/doc/dw-grows.doc b/doc/dw-grows.doc
new file mode 100644
index 00000000..15150338
--- /dev/null
+++ b/doc/dw-grows.doc
@@ -0,0 +1,184 @@
+/** \page dw-grows GROWS - Grand Redesign Of Widget Sizes
+
+This paper describes (will describe) some design changes to
+calculating widget sizes. Goals are:
+
+- Simplification of widget size calculation by the parent widget;
+ dw::Textblock::calcWidgetSize, dw::OutOfFlowMgr::ensureFloatSize
+ etc. should become simpler or perhaps even obsolete.
+
+- Making the implementation of some features possible:
+
+ - *max-width*, *max-height*, *min-width*, *min-height*;
+ - correct aspect ratio for images with only one percentage size defined;
+ - *display: inline-block*;
+ - <button>.
+
+
+A short sketch
+==============
+
+**dw::core::Widget::sizeRequest and dw::core::Widget::getExtremes will
+return final results.** The caller does not have to correct the size,
+e.&nbsp;g. when percentages are defined. As an example,
+dw::Textblock::calcWidgetSize has already become much simpler.
+
+**A new hierarchy, *container*:** Aside from dw::core::Widget::parent
+and dw::core::Widget::generator, there is a third hierarchy
+dw::core::Widget::container, which is (unlike *generator*) always a
+direct ancestor, and represents what in CSS is called *containing
+block*. Containers are important to define the "context size", which
+is (not solely) used for percentage sizes.
+
+(There is another "containing block", dw::Textblock::containingBlock;
+these may be consolidated some day.)
+
+**The process of size calculation is split between the widget itself
+and its container:**
+
+- The container provides some abstract methods:
+ dw::core::Widget::getAvailWidthOfChild,
+ dw::core::Widget::getAvailHeightOfChild,
+ dw::core::Widget::correctRequisitionOfChild, and
+ dw::core::Widget::correctExtremesOfChild, which can be used in the
+ actual implementation of dw::core::Widget::sizeRequestImpl;
+ different containers with different ways how to arrange their
+ children will implement these methods in a different way. (Simple
+ example: the *available width* for children within a textblock is
+ the *available width* for the textblock itself, minus
+ margin/border/padding; on the other hand, it is completely different
+ for children of tables, for which a complex column width calculation
+ is used.)
+
+- The actual size calculation is, however, controlled by the widget
+ itself, which only *uses* these methods above.
+
+<div style="border: 2px solid #ffff00; margin-top: 0.5em;
+ margin-bottom: 0.5em; padding: 0.5em 1em; background-color: #ffffe0">
+ <b>Update:</b> This is not fully correct; the parents are also involved
+ for calculating available widths and heights, at least when CSS 'width'
+ and 'height' are not set.</div>
+
+**Size hints are removed.** Instead, the container methods in the
+previous paragraph are used. Changes of container sizes (especially
+viewport the size) are handled in a different way.
+
+**Extremes are extended by intrinsic values.** In some cases (see
+dw::Table::forceCalcCellSizes, case *minWidth* > *totalWidth*, for an
+example) it is useful to know about minimal and maximal width of a
+widget independent of CSS attributes. For this, dw::core::Extremes is
+extended by:
+
+- dw::core::Extremes::minWidthIntrinsic and
+- dw::core::Extremes::maxWidthIntrinsic.
+
+The rules for the calculation:
+
+1. If a widget has no children, it calculates *minWidthIntrinsic* and
+ *maxWidthIntrinsic* as those values not affected by CSS hints.
+ (dw::core::Widget::correctExtremes will not change these values.)
+2. A widget must calculate *minWidthIntrinsic* and *maxWidthIntrinsic*
+ from *minWidthIntrinsic* and *maxWidthIntrinsic* of its children,
+ and *minWidth* and *maxWidth* from *minWidth* and *maxWidth* of its
+ children.
+3. At the end, *minWidth* and *maxWidth* of a widget are corrected by
+ CSS attributes. (dw::core::Widget::correctExtremes will do this.)
+
+<div style="border: 2px solid #ffff00; margin-top: 0.5em;
+ margin-bottom: 0.5em; padding: 0.5em 1em; background-color: #ffffe0">
+ <b>Notice:</b> Currently, dw::core::Widget::getExtremesImpl must
+ set all four members in dw::core::Extremes; this may change.</div>
+
+
+Rules for *new* methods related to resizing
+===========================================
+
+- Of course, *sizeRequestImpl* may (should) call *correctRequisition*,
+ and *getExtremesImpl* may (should) call *correctExtremes*.
+
+- *sizeRequestImpl* (and *correctRequisition*) is allowed to call
+ *getAvailWidth* and *getAvailHeight* with *forceValue* set, but
+ *getExtremesImpl* (and *correctExtremes*) is allowed to call these
+ only with *forceValue* unset.
+
+- For this reason, *sizeRequestImpl* is indeed allowed to call
+ *getExtremes* (dw::Table does so), but the opposite
+ (*getExtremesImpl* calling *sizeRequest*) is not allowed
+ anymore. (Before GROWS, the standard implementation
+ dw::core::Widget::getExtremesImpl did so.)
+
+- Finally, *getAvailWidth* and *getAvailHeight* may call
+ *getExtremes*, if and only if *forceValue* is set.
+
+Here is a diagram showing all permitted dependencies:
+
+\dot
+digraph G {
+ node [shape=record, fontname=Helvetica, fontsize=10, color="#c0c0c0"];
+ edge [arrowhead="open", arrowtail="none", color="#404040"];
+
+ "sizeRequest[Impl]" -> "getExtremes[Impl]";
+ "sizeRequest[Impl]" -> correctRequisition;
+ "getExtremes[Impl]" -> correctExtremes;
+ "sizeRequest[Impl]" -> "getAvail[Width|Height] (true)";
+ "getExtremes[Impl]" -> "getAvail[Width|Height] (false)";
+ correctRequisition -> "getAvail[Width|Height] (true)";
+ correctExtremes -> "getAvail[Width|Height] (false)";
+ "getAvail[Width|Height] (true)" -> "getExtremes[Impl]";
+}
+\enddot
+
+Open issues
+===========
+
+**Do CSS size dimensions override intrinsic sizes in all cases?** If a
+textblock needs at least, say, 100 pixels width so that the text can
+be read, but has a specification "width: 50px", should half of the
+text be invisible? Or should the width be corrected again to 100
+pixels?
+
+Currently, in the CSS size specification is honoured in all cases,
+with one exception: see dw::Textblock::sizeRequestImpl and see
+dw::Textblock::getExtremesImpl (the time when
+dw::core::Widget::correctRequisition and
+dw::core::Widget::correctExtremes, respectively, is called).
+
+*Not* honouring the CSS size specification in all cases could improve
+readability in some cases, so this could depend on a user preference.
+
+**Update:** There is now a dillorc option <tt>adjust_min_width</tt>,
+which is implemented for widths, but not heights (since it is based on
+width extremes, but there are currently no height extremes).
+
+Another problem is that in most cases, there is no clippping, so that
+contents may exceed the allocation of the widget, but redrawing is not
+necessarily triggered.
+
+**Percentage values for margins and paddings, as well as negative
+margins** are interesting applications, but have not been considered
+yet. For negative margins, a new attribute
+dw::core::Widget::extraSpace could solve the problem of widgets
+sticking out of the allocation of parent.
+
+**Clarify percentage heights.** Search in widget.cc, and compare
+section 10.5 ('height') of the CSS 2.1 specification to section 10.2
+('width').
+
+**Fast queue resize does not work fully.** Example: run
+*test/dw-simple-container-test* (dw_simple_container_test.cc), resize
+(best maximize) the window and follow (e.&nbsp;g. by using RTFL) what
+happens in consequence of dw::core::Layout::viewportSizeChanged. The
+dw::SimpleContainer in the middle is not affected, so only the two
+dw::Textblock's (at the top and at the bottom) call queueResize with
+*fast = true*, and so get *NEEDS_RESIZE* set; but since it is not set
+for the dw::SimpleContainer, *sizeRequest* is never called for the
+bottom dw::Textblock.
+
+There does not seem to be a real case for this problem in dillo, since
+all widgets which may contain other widgets (except
+dw::SimpleContainer, which is not used outside tests) use the
+available width and height (dw::core::Widget::usesAvailWidth and
+dw::core::Widget::usesAvailHeight), and so are always affected by
+viewport size changes.
+
+*/
diff --git a/doc/dw-out-of-flow-2.doc b/doc/dw-out-of-flow-2.doc
new file mode 100644
index 00000000..d9d70565
--- /dev/null
+++ b/doc/dw-out-of-flow-2.doc
@@ -0,0 +1,69 @@
+/** \page dw-out-of-flow-2 Handling Elements Out Of Flow (notes 2)
+
+This has to be integrated into \ref dw-out-of-flow.
+
+Constructing a page with floats
+-------------------------------
+When a page is constructed (dw::Textblock::addWord), the *generating*
+block tells the positions of floats (or, generally, widgets out of
+flow) via dw::OutOfFlowMgr::tellPosition. This method considers
+already collisions with other floats (only previous floats; floats
+following this float are not considered); after the call,
+dw::OutOfFlowMgr::getBorder will return correct values.
+
+dw::OutOfFlowMgr::tellPosition also checks for overlaps of this float
+with other textblocks, except this textblock (the *generator*, which
+is just constructed, so nothing has to be done). The fact that the
+position of the float is the top, and so the float has only an
+allocation below this position, leads to the effect that only the
+textblocks following the generator are affected. (**Check:** Can the
+search be limited here?) When a page is constructed, no textblocks
+should be following the generating block, so no textblocks are
+affected.
+
+**Todo:** Clarify details of line breaking (\ref dw-line-breaking).
+
+Float changes its size
+----------------------
+The float itself will call queueResize, which will result in a call of
+markSizeChange for the *containing* block, which will then call
+dw::OutOfFlowMgr::markSizeChange. Here, the vloat is only *marked* as
+dirty; the size will be calculated later (in
+dw::OutOfFlowMgr::ensureFloatSize).
+
+This will trigger the resize idle function, so sizeRequest and
+sizeAllocate for all floats and textblocks. In this run,
+dw::OutOfFlowMgr::hasRelationChanged will return *true*, and so result
+in a call of dw::Textblock::borderChanged, and trigger a second run of
+the resize idle function, dealing correctly with the new size.
+
+(This case is handles in a not perfectly optimal way, since two runs
+of the resize idle function are neccessary; but size changes of floats
+is not a very common case.
+
+When a page is constructed (see above), a changing size of a float
+currently constructed typically only affects the most bottom
+textblock; the other textblocks are not covered by this float.)
+
+**Error:** In this case, new collisions are not yet considered.
+
+
+Changing the width of the page
+------------------------------
+
+When the page width is changed, this will result in a reconstruction
+of the page; see *Constructing a page with floats*. Anyway, checking
+for overlaps will play a more important role. This is handled in an
+optimal way by dw::OutOfFlowMgr::hasRelationChanged.
+
+**Check:** Are "cascades" avoided, like this:
+
+1. All textblocks are constructed. A float in textblock 1 overlaps
+ with textblock 2, so dw::Textblock::borderChanged is called for
+ textblock 2.
+2. In another resize idle run, textblock 2 is constructed again. A
+ float in textblock 2 overlaps with textblock 3, so that
+ dw::Textblock::borderChanged is called for textblock 3.
+3. Etc.
+
+*/ \ No newline at end of file
diff --git a/doc/dw-out-of-flow.doc b/doc/dw-out-of-flow.doc
new file mode 100644
index 00000000..ea4a52bc
--- /dev/null
+++ b/doc/dw-out-of-flow.doc
@@ -0,0 +1,214 @@
+/** \page dw-out-of-flow Handling Elements Out Of Flow
+
+
+<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>
+
+Introduction
+============
+
+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&nbsp;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.)
+
+Both in this text and the code, generating and containing block are
+abbreviated with **GB** and **CB**, respectively.
+
+
+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 |
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+ | left float index | 0 | 0 | 1 |
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+ | right float index | 1 | 0 | 1 |
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+ | absolutely positioned index | 1 | 1 |
+ +---+ - - - +---+---+- - - - - -+---+---+---+---+
+
+Details are hidden by static inline methods of dw::OutOfFlowMgr.
+
+
+The sizeRequest/sizeAllocate problem
+========================================
+
+*See also:* \ref dw-widget-sizes, especially the section *Rules for
+Methods Related to Resizing*.
+
+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 previosly calculated size. Each widget must allocate its
+ children; here, the condition for the toplevel widget (allocated
+ size equals requested size) is not necessary; instead, 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) to determine the borders, which
+is done in dw::Textblock::sizeRequestImpl.
+
+For this, the size model has been extended (see \ref dw-widget-sizes,
+section *Rules for Methods Related to Resizing*): *sizeRequest* can be
+called within *sizeRequestImpl* for other widgets that children (with
+some caution). Namely, dw::Textblock::sizeRequestImpl calls
+dw::core::Widget::sizeRequest for the float, via
+dw::OutOfFlowMgr::getBorder and dw::OutOfFlowMgr::ensureFloatSize.
+
+**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. See below (*hasRelationChanged*) for details.
+
+Generally, this pattern (distinguishing between GB and CB) can be
+found everywhere in dw::OutOfFlowMgr.
+
+For details see:
+
+- dw::OutOfFlowMgr::getLeftBorder, dw::OutOfFlowMgr::getRightBorder,
+ dw::OutOfFlowMgr::getBorder (called by the first two), and
+ especially, dw::OutOfFlowMgr::getFloatsListForTextblock (called by
+ the latter), where these three cases are distinguished;
+- dw::OutOfFlowMgr::sizeAllocateStart,
+ dw::OutOfFlowMgr::sizeAllocateEnd which are called by the containing
+ block.
+
+(This could be solved in a more simple, elegant way, when
+*sizeRequest* would depend on the position. This is, however, only a
+vague idea, perhaps not even feasible, and for which there are no
+concrete plans, certainly not in \ref dw-grows.)
+
+
+Implementation details
+======================
+
+- CB and GB lists (general pattern) (see previous section)
+- binary search; different search criteria, how they accord
+- lastLeftTBIndex, lastRightTBIndex etc.
+- limitiation of search; extIndex etc.
+
+
+How *hasRelationChanged* works
+==============================
+
+...
+
+
+Integration of line breaking and floats
+=======================================
+
+(Positioning of floats, loop, recent works.)
+
+
+Absolute and fixed positiones
+=============================
+
+See <http://flpsed.org/hgweb/dillo_grows>.
+
+*/ \ No newline at end of file
diff --git a/doc/dw-size-of-widget.png b/doc/dw-size-of-widget.png
index eda93ee1..dbdbe0c4 100644
--- a/doc/dw-size-of-widget.png
+++ b/doc/dw-size-of-widget.png
Binary files differ
diff --git a/doc/dw-style-box-model.png b/doc/dw-style-box-model.png
index aa65ecb7..bf2fb1f1 100644
--- a/doc/dw-style-box-model.png
+++ b/doc/dw-style-box-model.png
Binary files differ
diff --git a/doc/dw-style-length-absolute.png b/doc/dw-style-length-absolute.png
index 6b4d8389..9ea28cad 100644
--- a/doc/dw-style-length-absolute.png
+++ b/doc/dw-style-length-absolute.png
Binary files differ
diff --git a/doc/dw-style-length-percentage.png b/doc/dw-style-length-percentage.png
index 15b36958..b1ad79c9 100644
--- a/doc/dw-style-length-percentage.png
+++ b/doc/dw-style-length-percentage.png
Binary files differ
diff --git a/doc/dw-style-length-relative.png b/doc/dw-style-length-relative.png
index d54d99b5..ee79b1a9 100644
--- a/doc/dw-style-length-relative.png
+++ b/doc/dw-style-length-relative.png
Binary files differ
diff --git a/doc/dw-widget-sizes.doc b/doc/dw-widget-sizes.doc
index 419a4a73..a82d3b99 100644
--- a/doc/dw-widget-sizes.doc
+++ b/doc/dw-widget-sizes.doc
@@ -1,22 +1,24 @@
/** \page dw-widget-sizes Sizes of Dillo Widgets
-<h2>Allocation</h2>
+<div style="border: 2px solid #ff4040; margin-bottom: 0.5em;
+padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b>
+Not up to date, see \ref dw-grows.</div>
+
+Allocation
+==========
Each widget has an \em allocation at a given time, this includes
-<ul>
-<li> the position (\em x, \em y) relative to the upper left corner of the
- canvas, and
-<li> the size (\em width, \em ascent, \em descent).
-</ul>
+- the position (\em x, \em y) relative to the upper left corner of the
+ canvas, and
+- the size (\em width, \em ascent, \em descent).
The \em canvas is the whole area available for the widgets, in most
-cases, only a part is seen in a viewport. The allocation of the toplevel widget is exactly the allocation of the canvas, i.e.
+cases, only a part is seen in a viewport. The allocation of the
+toplevel widget is exactly the allocation of the canvas, i.e.
-<ul>
-<li> the position of the toplevel widget is always (0, 0), and
-<li> the canvas size is defined by the size of the toplevel widget.
-</ul>
+- the position of the toplevel widget is always (0, 0), and
+- the canvas size is defined by the size of the toplevel widget.
The size of a widget is not simply defined by the width and the
height, instead, widgets may have a base line, and so are vertically
@@ -31,13 +33,11 @@ defined by the limits of the C++ type \em int.
In the example in the image, the widget has the following allocation:
-<ul>
-<li>\em x = 50
-<li>\em y = 50
-<li>\em width = 150
-<li>\em ascent = 150
-<li>\em descent = 100
-</ul>
+- \em x = 50
+- \em y = 50
+- \em width = 150
+- \em ascent = 150
+- \em descent = 100
The current allocation of a widget is hold in
dw::core::Widget::allocation. It can be set from outside by
@@ -54,7 +54,9 @@ appropriate child allocations. dw::core::Widget::allocation should not
be changed here, this is already done in
dw::core::Widget::sizeAllocate.
-<h2>Requisitions</h2>
+
+Requisitions
+============
A widget may prefer a given size for the allocation. This size, the
\em requisition, should be returned by the method
@@ -62,14 +64,12 @@ dw::core::Widget::sizeRequestImpl. In the simplest case, this is
independent of the context, e.g. for an
image. dw::Image::sizeRequestImpl returns the following size:
-<ul>
-<li> If no buffer has yet been assigned (see dw::Image for more details),
- the size necessary for the alternative text is returned. If no
- alternative text has been set, zero is returned.
+- If no buffer has yet been assigned (see dw::Image for more details),
+ the size necessary for the alternative text is returned. If no
+ alternative text has been set, zero is returned.
-<li> If a buffer has been assigned (by dw::Image::setBuffer), the root
- size is returned (i.e. the original size of the image to display).
-</ul>
+- If a buffer has been assigned (by dw::Image::setBuffer), the root
+ size is returned (i.e. the original size of the image to display).
This is a bit simplified, dw::Image::sizeRequestImpl should also deal
with margins, borders and paddings, see dw::core::style.
@@ -87,64 +87,49 @@ widget), may, but also may not consider the requisition. Instead, a
widget must deal with any allocation. (For example, dw::Image scales
the image buffer when allocated at another size.)
-<h2>Size Hints</h2>
-
-Some widgets do not have an inherent size, but depend on the context,
-e.g. the viewport size. These widgets should adhere to <i>size hints</i>,
-i.e. implement the methods dw::core::Widget::setWidth,
-dw::core::Widget::setAscent and dw::core::Widget::setDescent. The values
-passed to the callees are
-
-<ul>
-<li> the viewport size (ascent is the heigt here, while descent is 0) for
- the toplevel widget, and
-<li> determined by the parent for its child widgets.
-</ul>
-Generally, the values should define the available space for the
-widget.
+Size Hints
+==========
-A widget, which depends on size hints, should call
-dw::core::Widget::queueResize, when apropriate.
+<div style="border: 2px solid #ff4040; margin-bottom: 0.5em;
+padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b>
+Size hints have been removed, see \ref dw-grows.</div>
-\todo There should be a definition of "available space".
-<h2>Width Extremes</h2>
+Width Extremes
+==============
dw::Table uses width extremes for fast calculation of column
widths. The structure dw::core::Extremes represents the minimal and
maximal width of a widget, as defined by:
-<ul>
-<li> the minimal width is the smallest width, at which a widget can still
- display contents, and
-<li> the maximal width is the largest width, above which increasing the width
- does not make any sense.
-</ul>
+- the minimal width is the smallest width, at which a widget can still
+ display contents, and
+- the maximal width is the largest width, above which increasing the
+ width- does not make any sense.
Especially the latter is vaguely defined, here are some examples:
-<ul>
-<li> For those widgets, which do not depend on size hints, the minimal and
- the maximal width is the inherent width (the one returned by
- dw::core::Widget::sizeRequest).
+- For those widgets, which do not depend on size hints, the minimal
+ and the maximal width is the inherent width (the one returned by
+ dw::core::Widget::sizeRequest).
-<li> For a textblock, the minimal width is the width of the widest
- (unbreakable) word, the maximal width is the width of the total
- paragraph (stretching a paragraph further would only waste space).
- Actually, the implementation of dw::Textblock::getExtremesImpl is
- a bit more complex.
+- For a textblock, the minimal width is the width of the widest
+ (unbreakable) word, the maximal width is the width of the total
+ paragraph (stretching a paragraph further would only waste space).
+ Actually, the implementation of dw::Textblock::getExtremesImpl is a
+ bit more complex.
-<li> dw::Table is an example, where the width extremes are calculated
- from the width extremes of the children.
-</ul>
+- dw::Table is an example, where the width extremes are calculated
+ from the width extremes of the children.
Handling width extremes is similar to handling requisitions, a widget
must implement dw::core::Widget::getExtremesImpl, but a caller will
use dw::core::Widget::getExtremes.
-<h2>Resizing</h2>
+Resizing
+========
When the widget changes its size (requisition), it should call
dw::core::Widget::queueResize. The next call of
@@ -160,27 +145,133 @@ done before. In this case, a widget must exactly know the reasons, why
a call of dw::core::Widget::sizeRequestImpl is necessary. To make use
of this, a widget must implement the following:
-<ol>
-<li> There is a member dw::core::Widget::parentRef, which is
- totally under control of the parent widget (and so sometimes not
- used at all). It is necessary to define how parentRef is used
- by a specific parent widget, and it has to be set to the correct
- value whenever necessary.
-
-<li> The widget must implement dw::core::Widget::markSizeChange and
+1. There is a member dw::core::Widget::parentRef, which is totally
+ under control of the parent widget (and so sometimes not used at
+ all). It is necessary to define how parentRef is used by a specific
+ parent widget, and it has to be set to the correct value whenever
+ necessary.
+2. The widget must implement dw::core::Widget::markSizeChange and
dw::core::Widget::markExtremesChange, these methods are called in
two cases:
-
- <ol>
- <li> directly after dw::core::Widget::queueResize, with the argument
- ref was passed to dw::core::Widget::queueResize, and
- <li> if a child widget has called dw::core::Widget::queueResize,
- with the value of the parent_ref member of this child.
- </ol>
-</ol>
+ 1. directly after dw::core::Widget::queueResize, with the
+ argument ref was passed to dw::core::Widget::queueResize,
+ and
+ 2. if a child widget has called dw::core::Widget::queueResize,
+ with the value of the parent_ref member of this child.
This way, a widget can exactly keep track on size changes, and so
implement resizing in a faster way. A good example on how to use this
is dw::Textblock.
+
+Rules for Methods Related to Resizing
+=====================================
+
+Which method can be called, when the call of another method is not
+finished? These rules are important in two circumstances:
+
+1. To know which method can be called, and, especially, which methods
+ *must not* be called, within the implementation of
+ *sizeRequestImpl* (called by *sizeRequest*), *markSizeChange*, and
+ *markExtremesChange* (the latter two are called by *queueResize*).
+2. On the other hand, to make sure that the calls, which are allowed,
+ are handled correctly, especially in implementations of
+ *sizeRequestImpl*, *markSizeChange*, *markExtremesChange*
+
+Generally, the rules defined below are, in case of doubt, rather
+strict; when changing the rules, loosening is simpler than to tighten
+them, since this will make it neccessary to review old code for calls
+previously allowed but now forbidden.
+
+Short recap:
+
+- *QueueResize* directly calls *markSizeChange* and
+ *markExtremesChanges*, and queues an idle function for the actual
+ resizing (dw::core::Layout::resizeIdle). (The idle function is
+ called some time after *queueResize* is finished.)
+- The resize idle function first calls *sizeRequest*, then
+ *sizeAllocate*, for the toplevel widget.
+
+In the following table, the rules are defined in detail. "Within call
+of ..." includes all methods called from the original method: the
+first row (*queueResize*) defines also the rules for
+*markExtremesChanges* and *markExtremesChanges*, and in the second row
+(*sizeAllocate*), even *sizeRequest* has to be considered.
+
+<div style="border: 2px solid #ff4040; margin-bottom: 0.5em;
+padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b>
+Not up to date: *queueResize* can now be called recursively (so to
+speak). See code there.</div>
+
+<table>
+ <tr>
+ <th>Within call of ... ↓
+ <th>... is call allowed of ... ? →
+ <th>queueResize
+ <th>sizeAllocate
+ <th>sizeRequest
+ <th>getExtremes
+ <tr>
+ <th colspan=2>queueResize
+ <td>No
+ <td>No<sup>1</sup>
+ <td>No<sup>1</sup>
+ <td>No<sup>1</sup>
+ <tr>
+ <th colspan=2>sizeAllocate
+ <td>Yes
+ <td>Only for children<sup>2</sup>
+ <td>Yes(?)
+ <td>Yes(?)
+ <tr>
+ <th colspan=2>sizeRequest
+ <td>Yes<sup>3</sup>
+ <td>No
+ <td>Limited<sup>4</sup>
+ <td>Limited<sup>4</sup>
+ <tr>
+ <th colspan=2>getExtremes
+ <td>Yes<sup>3</sup>
+ <td>No
+ <td>Limited<sup>4</sup>
+ <td>Limited<sup>4</sup>
+ <tr>
+ <td colspan=6><sup>1</sup>) Otherwise, since these other methods
+may be call *queueResize*, the limitation that *queueResize* must not
+call *queueResize* can be violated.
+
+<sup>2</sup>) Could perhaps be loosened as for *sizeRequest* and
+*getExtremes*, but there is probably no need.
+
+<sup>3</sup>) Therefore the distinction between *RESIZE_QUEUED* and
+*NEEDS_RESIZE*, and *EXTREMES_QUEUED* and *EXTREMES_CHANGED*,
+respectively.
+
+<sup>4</sup>) Calls only for children are safe. In other cases, you
+take a large responsibility to prevent endless recursions by
+(typically indirectly) calling *sizeRequest* / *getExtremes* for
+direct ancestors.
+</table>
+
+Furthermore, *sizeAllocate* can only be called within a call of
+dw::core::Layout::resizeIdleId, so (if you do not touch dw::core) do
+not call it outside of *sizeAllocateImpl*. The other methods can be
+called outsize; e.&nbsp;g. *sizeRequest* is called in
+dw::Textblock::addWidget.
+
+To avoid painful debugging, there are some tests for the cases that
+one method call is strictly forbidden while another method is called.
+
+This could be done furthermore:
+
+- The tests could be refined.
+- Is it possible to define exacter rules, along with a proof that no
+ problems (like endless recursion) can occur?
+
+
+See also
+========
+
+- \ref dw-grows
+
*/
diff --git a/doc/not-so-simple-container.png b/doc/not-so-simple-container.png
index 886b72a8..0af067b5 100644
--- a/doc/not-so-simple-container.png
+++ b/doc/not-so-simple-container.png
Binary files differ
diff --git a/doc/user_help.html b/doc/user_help.html
index 9de2056f..88218f70 100644
--- a/doc/user_help.html
+++ b/doc/user_help.html
@@ -314,7 +314,7 @@
<p>
Example, in dillorc:<br>
<blockquote>
- <code>search_url="dd Duckduckgo http://duckduckgo.com/lite/?kp=-1&q=%s"</code>
+ <code>search_url="dd Duckduckgo http://duckduckgo.com/lite/?kp=-1&amp;q=%s"</code>
</blockquote>
means you can reach the location bar (CTRL+L), then type:
<blockquote>