1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.8"/>
<title>Dillo: GROWS - Grand Redesign Of Widget Sizes</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="https://www.dillo.org/dw/html/jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td style="padding-left: 0.5em;">
<div id="projectname">Dillo
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.8 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="namespaces.html"><span>Namespaces</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">GROWS - Grand Redesign Of Widget Sizes </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><div style="border: 2px solid #ffff00; margin: 1em 0;
padding: 0.5em 1em; background-color: #ffffe0">The complex "widget
sizes" is currently divided into three documents: <a class="el" href="dw-widget-sizes.html">Sizes of Dillo Widgets</a>, <b>Grand Redesign Of Widget Sizes</b> (this document), and <a class="el" href="dw-size-request-pos.html">Size requisitions depending on positions</a>. </div><p>This paper describes (will describe) some design changes to calculating widget sizes. Goals are:</p>
<ul>
<li>Simplification of widget size calculation by the parent widget; dw::Textblock::calcWidgetSize, dw::OutOfFlowMgr::ensureFloatSize etc. should become simpler or perhaps even obsolete.</li>
<li>Making the implementation of some features possible:<ul>
<li><em>max-width</em>, <em>max-height</em>, <em>min-width</em>, <em>min-height</em>;</li>
<li>correct aspect ratio for images with only one percentage size defined;</li>
<li><em>display: inline-block</em>;</li>
<li><button>.</li>
</ul>
</li>
</ul>
<h1>A short sketch </h1>
<p><a class="el" href="classdw_1_1core_1_1Widget.html#a34dcfd744c6eec49fa87baaa8591896e" title="This method is a wrapper for Widget::sizeRequestImpl(); it calls the latter only when needed...">dw::core::Widget::sizeRequest</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#aec23092b0cfe5624b9751a59671fe251" title="Wrapper for Widget::getExtremesImpl(). ">dw::core::Widget::getExtremes</a> will return final results.** The caller does not have to correct the size, e. g. when percentages are defined. As an example, dw::Textblock::calcWidgetSize has already become much simpler.</p>
<p>A new hierarchy, <em>container</em>:** Aside from <a class="el" href="classdw_1_1core_1_1Widget.html#ab93cbba14db2dbf59e8b3ce481cd4dd4" title="The parent widget, NULL for top-level widgets. ">dw::core::Widget::parent</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#a7f0cfc1577df8f038124ba02c34b3372" title="The generating widget, NULL for top-level widgets, or if not set; in the latter case, the effective generator (see getGenerator) is the parent. ">dw::core::Widget::generator</a>, there is a third hierarchy <a class="el" href="classdw_1_1core_1_1Widget.html#a1c7115fa213b9bf03cbbd05d00af2db4" title="The containing widget, equivalent to the "containing block" defined by CSS. May be NULL...">dw::core::Widget::container</a>, which is (unlike <em>generator</em>) always a direct ancestor, and represents what in CSS is called <em>containing block</em>. Containers are important to define the "context size", which is (not solely) used for percentage sizes.</p>
<p>(There is another "containing block", dw::Textblock::containingBlock; these may be consolidated some day.)</p>
<p>The process of size calculation is split between the widget itself and its container:**</p>
<ul>
<li>The container provides some abstract methods: <a class="el" href="classdw_1_1core_1_1Widget.html#a32de61d3d5fdd66f953f7613f3f9c514">dw::core::Widget::getAvailWidthOfChild</a>, <a class="el" href="classdw_1_1core_1_1Widget.html#a6a1f938ff0aae3eb16b6c535a3266815">dw::core::Widget::getAvailHeightOfChild</a>, <a class="el" href="classdw_1_1core_1_1Widget.html#a70fc538e0cf4acdcb8e7b88ce1d405d2">dw::core::Widget::correctRequisitionOfChild</a>, and <a class="el" href="classdw_1_1core_1_1Widget.html#a79a9be8c5f31ee5936ae4916112be046">dw::core::Widget::correctExtremesOfChild</a>, which can be used in the actual implementation of <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeRequestImpl</a>; different containers with different ways how to arrange their children will implement these methods in a different way. (Simple example: the <em>available width</em> for children within a textblock is the <em>available width</em> 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.)</li>
<li>The actual size calculation is, however, controlled by the widget itself, which only <em>uses</em> these methods above.</li>
</ul>
<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><p>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.</p>
<p>Extremes are extended by intrinsic values.** In some cases (see <a class="el" href="classdw_1_1Table.html#a42587c01297075332dd57f345d4b4ccd">dw::Table::forceCalcCellSizes</a>, case <em>minWidth</em> > <em>totalWidth</em>, for an example) it is useful to know about minimal and maximal width of a widget independent of CSS attributes. For this, <a class="el" href="structdw_1_1core_1_1Extremes.html">dw::core::Extremes</a> is extended by:</p>
<ul>
<li><a class="el" href="structdw_1_1core_1_1Extremes.html#a2c513c4504d52a97af035e1f094d648b">dw::core::Extremes::minWidthIntrinsic</a> and</li>
<li><a class="el" href="structdw_1_1core_1_1Extremes.html#a572ea67b8c9f5ff3c6b72e730f552401">dw::core::Extremes::maxWidthIntrinsic</a>.</li>
</ul>
<p>The rules for the calculation:</p>
<ol type="1">
<li>If a widget has no children, it calculates <em>minWidthIntrinsic</em> and maxWidthIntrinsic* as those values not affected by CSS hints. (<a class="el" href="classdw_1_1core_1_1Widget.html#ae3ecd16a384316494e55e1d5e4874ad9">dw::core::Widget::correctExtremes</a> will not change these values.)</li>
<li>A widget must calculate <em>minWidthIntrinsic</em> and <em>maxWidthIntrinsic</em> from <em>minWidthIntrinsic</em> and <em>maxWidthIntrinsic</em> of its children, and <em>minWidth</em> and <em>maxWidth</em> from <em>minWidth</em> and <em>maxWidth</em> of its children.</li>
<li>At the end, <em>minWidth</em> and <em>maxWidth</em> of a widget are corrected by CSS attributes. (<a class="el" href="classdw_1_1core_1_1Widget.html#ae3ecd16a384316494e55e1d5e4874ad9">dw::core::Widget::correctExtremes</a> will do this.)</li>
</ol>
<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, <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::core::Widget::getExtremesImpl</a> must set all four members in <a class="el" href="structdw_1_1core_1_1Extremes.html">dw::core::Extremes</a>; this may change.</div><p>Another <b>extension of extremes: <em>adjustmentWidth</em>.</b> This is used as minimum for the width, when "adjust_min_width" (or, "adjust_table_min_width", respectively) is set.</p>
<p>The rules for the calculation:</p>
<ol type="1">
<li>If a widget has no children, it can choose a suitable value, typically based on <a class="el" href="structdw_1_1core_1_1Extremes.html#a743de2619d9d62cefb8e2bb0f3a19fb1">dw::core::Extremes::minWidth</a> and <a class="el" href="structdw_1_1core_1_1Extremes.html#a2c513c4504d52a97af035e1f094d648b">dw::core::Extremes::minWidthIntrinsic</a>.</li>
<li><p class="startli">A widget must calculate <em>adjustmentWidth</em> from <em>adjustmentWidth</em> of its children.</p>
<p class="startli">Note:* An implementation of <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::core::Widget::getExtremesImpl</a> may set this value <em>after</em> calling <a class="el" href="classdw_1_1core_1_1Widget.html#a79a9be8c5f31ee5936ae4916112be046">dw::core::Widget::correctExtremesOfChild</a>, so that it cannot be used for the correction of extremes. In this case useAdjustmentWidth = false* should be passed to <a class="el" href="classdw_1_1core_1_1Widget.html#a79a9be8c5f31ee5936ae4916112be046">dw::core::Widget::correctExtremesOfChild</a>. On the other hand, if known before, <em>useAdjustmentWidth</em> should be set to <em>true</em>.</p>
</li>
</ol>
<h1>Rules for <em>new</em> methods related to resizing </h1>
<ul>
<li>Of course, <em>sizeRequestImpl</em> may (should) call <em>correctRequisition</em>, and <em>getExtremesImpl</em> may (should) call <em>correctExtremes</em>.</li>
<li><em>sizeRequestImpl</em> (and <em>correctRequisition</em>) is allowed to call getAvailWidth* and <em>getAvailHeight</em> with <em>forceValue</em> set, but getExtremesImpl* (and <em>correctExtremes</em>) is allowed to call these only with <em>forceValue</em> unset.</li>
<li>For this reason, <em>sizeRequestImpl</em> is indeed allowed to call getExtremes* (<a class="el" href="classdw_1_1Table.html" title="A Widget for rendering tables. ">dw::Table</a> does so), but the opposite (<em>getExtremesImpl</em> calling <em>sizeRequest</em>) is not allowed anymore. (Before GROWS, the standard implementation <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::core::Widget::getExtremesImpl</a> did so.)</li>
<li>Finally, <em>getAvailWidth</em> and <em>getAvailHeight</em> may call getExtremes*, if and only if <em>forceValue</em> is set.</li>
</ul>
<p>Here is a diagram showing all permitted dependencies:</p>
<div align="center">
<img src="dot_inline_dotgraph_1.png" alt="dot_inline_dotgraph_1.png" border="0" usemap="#dot_inline_dotgraph_1.map"/>
<map name="dot_inline_dotgraph_1.map" id="dot_inline_dotgraph_1.map"></map>
</div>
<h1>Open issues </h1>
<p>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?</p>
<p>Currently, in the CSS size specification is honoured in all cases, with one exception: see <a class="el" href="classdw_1_1Textblock.html#adb2f79277f25d9e2bb406214ae7af83f">dw::Textblock::sizeRequestImpl</a> and see <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::Textblock::getExtremesImpl</a> (the time when <a class="el" href="classdw_1_1core_1_1Widget.html#a438574f0b74a6f43b6001995a9a466ef">dw::core::Widget::correctRequisition</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#ae3ecd16a384316494e55e1d5e4874ad9">dw::core::Widget::correctExtremes</a>, respectively, is called).</p>
<p>Not* honouring the CSS size specification in all cases could improve readability in some cases, so this could depend on a user preference.</p>
<p>Update:** There is now a dillorc option <code>adjust_min_width</code>, which is implemented for widths, but not heights (since it is based on width extremes, but there are currently no height extremes).</p>
<p>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.</p>
<p>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 <a class="el" href="classdw_1_1core_1_1Widget.html#a608917a82e6f0ca6c8c4b404159cce23" title="Space around the margin box. Allocation is extraSpace + margin + border + padding + contents...">dw::core::Widget::extraSpace</a> could solve the problem of widgets sticking out of the allocation of parent.</p>
<p>Clarify percentage heights.** Search in <a class="el" href="widget_8cc.html">widget.cc</a>, and compare section 10.5 ('height') of the CSS 2.1 specification to section 10.2 ('width').</p>
<p>Fast queue resize does not work fully.** Example: run test/dw-simple-container-test* (<a class="el" href="dw__simple__container__test_8cc.html">dw_simple_container_test.cc</a>), resize (best maximize) the window and follow (e. g. by using RTFL) what happens in consequence of <a class="el" href="classdw_1_1core_1_1Layout.html#a51f1aecef5f041cdb398802f2349d6f6">dw::core::Layout::viewportSizeChanged</a>. The <a class="el" href="classdw_1_1SimpleContainer.html">dw::SimpleContainer</a> in the middle is not affected, so only the two <a class="el" href="classdw_1_1Textblock.html" title="A Widget for rendering text blocks, i.e. paragraphs or sequences of paragraphs. ">dw::Textblock</a>'s (at the top and at the bottom) call queueResize with fast = true*, and so get <em>NEEDS_RESIZE</em> set; but since it is not set for the <a class="el" href="classdw_1_1SimpleContainer.html">dw::SimpleContainer</a>, <em>sizeRequest</em> is never called for the bottom <a class="el" href="classdw_1_1Textblock.html" title="A Widget for rendering text blocks, i.e. paragraphs or sequences of paragraphs. ">dw::Textblock</a>.</p>
<p>There does not seem to be a real case for this problem in dillo, since all widgets which may contain other widgets (except <a class="el" href="classdw_1_1SimpleContainer.html">dw::SimpleContainer</a>, which is not used outside tests) use the available width and height (<a class="el" href="classdw_1_1core_1_1Widget.html#a1e281906e54633462b1c3d61a4f5d71b" title="Must be implemengted by a method returning true, when getAvailWidth() is called. ">dw::core::Widget::usesAvailWidth</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#ac73f4795954e264d7678fc0968f4cbfb" title="Must be implemengted by a method returning true, when getAvailHeight() is called. ...">dw::core::Widget::usesAvailHeight</a>), and so are always affected by viewport size changes. </p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Sat May 28 2016 11:47:43 for Dillo by  <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.8
</small></address>
</body>
</html>
|