diff options
Diffstat (limited to 'old/dw/html/dw-widget-sizes.html')
-rw-r--r-- | old/dw/html/dw-widget-sizes.html | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/old/dw/html/dw-widget-sizes.html b/old/dw/html/dw-widget-sizes.html new file mode 100644 index 0000000..d8131dd --- /dev/null +++ b/old/dw/html/dw-widget-sizes.html @@ -0,0 +1,161 @@ +<!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: Sizes of Dillo Widgets</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">Sizes of Dillo Widgets </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: <b>Sizes of Dillo Widgets</b> (this document), <a class="el" href="dw-grows.html">GROWS - Grand Redesign Of Widget Sizes</a>, and <a class="el" href="dw-size-request-pos.html">Size requisitions depending on positions</a>. </div><div style="border: 2px solid #ff4040; margin: 1em 0; + padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b> Not up to date, see other documents.</div><h1>Allocation </h1> +<p>Each widget has an <em>allocation</em> at a given time, this includes</p> +<ul> +<li>the position (<em>x</em>, <em>y</em>) relative to the upper left corner of the canvas, and</li> +<li>the size (<em>width</em>, <em>ascent</em>, <em>descent</em>).</li> +</ul> +<p>The <em>canvas</em> 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.</p> +<ul> +<li>the position of the toplevel widget is always (0, 0), and</li> +<li>the canvas size is defined by the size of the toplevel widget.</li> +</ul> +<p>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 divided into an ascender (which height is called <em>ascent</em>), and a descender (which height is called <em>descent</em>). The total height is so the sum of <em>ascent</em> and <em>descent</em>.</p> +<p>Sizes of zero are allowed. The upper limit for the size of a widget is defined by the limits of the C++ type <em>int</em>.</p> +<div class="image"> +<img src="dw-size-of-widget.png" alt="dw-size-of-widget.png"/> +<div class="caption"> +Allocation of a Widget</div></div> +<p>In the example in the image, the widget has the following allocation:</p> +<ul> +<li><em>x</em> = 50</li> +<li><em>y</em> = 50</li> +<li><em>width</em> = 150</li> +<li><em>ascent</em> = 150</li> +<li><em>descent</em> = 100</li> +</ul> +<p>The current allocation of a widget is hold in <a class="el" href="classdw_1_1core_1_1Widget.html#a2212fc4b9b2b0e26c7345f1b4adb7d28" title="The current allocation: size and position, always relative to the canvas. ">dw::core::Widget::allocation</a>. It can be set from outside by calling <a class="el" href="classdw_1_1core_1_1Widget.html#a0fa3284a21b20bd79f7de13bc0aca5e4" title="Wrapper for Widget::sizeAllocateImpl, calls the latter only when needed. ">dw::core::Widget::sizeAllocate</a>. This is a concrete method, which will call <a class="el" href="classdw_1_1core_1_1Widget.html#a756379942a5254e22c087f6bb62a23a5" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeAllocateImpl</a> (see code of <a class="el" href="classdw_1_1core_1_1Widget.html#a0fa3284a21b20bd79f7de13bc0aca5e4" title="Wrapper for Widget::sizeAllocateImpl, calls the latter only when needed. ">dw::core::Widget::sizeAllocate</a> for details).</p> +<p>For trivial widgets (like <a class="el" href="classdw_1_1Bullet.html" title="Displays different kind of bullets. ">dw::Bullet</a>), <a class="el" href="classdw_1_1core_1_1Widget.html#a756379942a5254e22c087f6bb62a23a5" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeAllocateImpl</a> does not need to be implemented. For more complex widgets, the implementation should call <a class="el" href="classdw_1_1core_1_1Widget.html#a0fa3284a21b20bd79f7de13bc0aca5e4" title="Wrapper for Widget::sizeAllocateImpl, calls the latter only when needed. ">dw::core::Widget::sizeAllocate</a> (not <a class="el" href="classdw_1_1core_1_1Widget.html#a756379942a5254e22c087f6bb62a23a5" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeAllocateImpl</a>) on all child widgets, with appropriate child allocations. <a class="el" href="classdw_1_1core_1_1Widget.html#a2212fc4b9b2b0e26c7345f1b4adb7d28" title="The current allocation: size and position, always relative to the canvas. ">dw::core::Widget::allocation</a> should not be changed here, this is already done in <a class="el" href="classdw_1_1core_1_1Widget.html#a0fa3284a21b20bd79f7de13bc0aca5e4" title="Wrapper for Widget::sizeAllocateImpl, calls the latter only when needed. ">dw::core::Widget::sizeAllocate</a>.</p> +<h1>Requisitions </h1> +<p>A widget may prefer a given size for the allocation. This size, the <em>requisition</em>, should be returned by the method <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeRequestImpl</a>. In the simplest case, this is independent of the context, e.g. for an image. <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::Image::sizeRequestImpl</a> returns the following size:</p> +<ul> +<li>If no buffer has yet been assigned (see <a class="el" href="classdw_1_1Image.html" title="Displays an instance of dw::core::Imgbuf. ">dw::Image</a> for more details), the size necessary for the alternative text is returned. If no alternative text has been set, zero is returned.</li> +<li>If a buffer has been assigned (by <a class="el" href="classdw_1_1Image.html#aba1218df074496b12176464c43022f7c" title="Called, when an image buffer is attached. ">dw::Image::setBuffer</a>), the root size is returned (i.e. the original size of the image to display).</li> +</ul> +<p>This is a bit simplified, <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::Image::sizeRequestImpl</a> should also deal with margins, borders and paddings, see <a class="el" href="namespacedw_1_1core_1_1style.html" title="Anything related to Dillo Widget styles is defined here. ">dw::core::style</a>.</p> +<p>From the outside, <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::Image::sizeRequest</a> should be called, which does a bit of optimization. Notice that in <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::Image::sizeRequestImpl</a>, no optimization like lazy evaluation is necessary, this is already done in <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::Image::sizeRequest</a>.</p> +<p>A widget, which has children, will likely call <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::Image::sizeRequest</a> on its children, to calculate the total requisition.</p> +<p>The caller (this is either the <a class="el" href="classdw_1_1core_1_1Layout.html" title="The central class for managing and drawing a widget tree. ">dw::core::Layout</a>, or the parent widget), may, but also may not consider the requisition. Instead, a widget must deal with any allocation. (For example, <a class="el" href="classdw_1_1Image.html" title="Displays an instance of dw::core::Imgbuf. ">dw::Image</a> scales the image buffer when allocated at another size.)</p> +<h1>Size Hints </h1> +<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 <a class="el" href="dw-grows.html">GROWS - Grand Redesign Of Widget Sizes</a>.</div><h1>Width Extremes </h1> +<p><a class="el" href="classdw_1_1Table.html" title="A Widget for rendering tables. ">dw::Table</a> uses width extremes for fast calculation of column widths. The structure <a class="el" href="structdw_1_1core_1_1Extremes.html">dw::core::Extremes</a> represents the minimal and maximal width of a widget, as defined by:</p> +<ul> +<li>the minimal width is the smallest width, at which a widget can still display contents, and</li> +<li>the maximal width is the largest width, above which increasing the width- does not make any sense.</li> +</ul> +<p>Especially the latter is vaguely defined, here are some examples:</p> +<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 <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>).</li> +<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 <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::Textblock::getExtremesImpl</a> is a bit more complex.</li> +<li><a class="el" href="classdw_1_1Table.html" title="A Widget for rendering tables. ">dw::Table</a> is an example, where the width extremes are calculated from the width extremes of the children.</li> +</ul> +<p>Handling width extremes is similar to handling requisitions, a widget must implement <a class="el" href="classdw_1_1core_1_1Widget.html#a984eb786b8d9c9bf63cfd24bdf465e6f" title="See Sizes of Dillo Widgets. ">dw::core::Widget::getExtremesImpl</a>, but a caller will use <a class="el" href="classdw_1_1core_1_1Widget.html#aec23092b0cfe5624b9751a59671fe251" title="Wrapper for Widget::getExtremesImpl(). ">dw::core::Widget::getExtremes</a>.</p> +<h1>Resizing </h1> +<p>When the widget changes its size (requisition), it should call <a class="el" href="classdw_1_1core_1_1Widget.html#ac00e44ccde79daf2b90247c352de67ef" title="This method should be called, when a widget changes its size. ">dw::core::Widget::queueResize</a>. The next call of <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeRequestImpl</a> should then return the new size. See <a class="el" href="classdw_1_1Image.html#aba1218df074496b12176464c43022f7c" title="Called, when an image buffer is attached. ">dw::Image::setBuffer</a> as an example.</p> +<p>Interna are described in the code of <a class="el" href="classdw_1_1core_1_1Widget.html#ac00e44ccde79daf2b90247c352de67ef" title="This method should be called, when a widget changes its size. ">dw::core::Widget::queueResize</a>.</p> +<h3>Incremental Resizing</h3> +<p>A widget may calculate its size based on size calculations already done before. In this case, a widget must exactly know the reasons, why a call of <a class="el" href="classdw_1_1core_1_1Widget.html#ac3764607155e58daee03db5cbb76d8e2" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeRequestImpl</a> is necessary. To make use of this, a widget must implement the following:</p> +<ol type="1"> +<li>There is a member <a class="el" href="classdw_1_1core_1_1Widget.html#a3a8324c1cc6859bd9bab133b44096f1b" title="This value is defined by the parent widget, and used for incremential resizing. ">dw::core::Widget::parentRef</a>, 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> +<li>The widget must implement <a class="el" href="classdw_1_1core_1_1Widget.html#ac8b5d6fd4fe3868a154c638e66ad75a2" title="See Sizes of Dillo Widgets. ">dw::core::Widget::markSizeChange</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#a30cb906a0382c1034bb398e7ea30a4a3" title="See Sizes of Dillo Widgets. ">dw::core::Widget::markExtremesChange</a>, these methods are called in two cases:<ol type="a"> +<li>directly after <a class="el" href="classdw_1_1core_1_1Widget.html#ac00e44ccde79daf2b90247c352de67ef" title="This method should be called, when a widget changes its size. ">dw::core::Widget::queueResize</a>, with the argument ref was passed to <a class="el" href="classdw_1_1core_1_1Widget.html#ac00e44ccde79daf2b90247c352de67ef" title="This method should be called, when a widget changes its size. ">dw::core::Widget::queueResize</a>, and</li> +<li>if a child widget has called <a class="el" href="classdw_1_1core_1_1Widget.html#ac00e44ccde79daf2b90247c352de67ef" title="This method should be called, when a widget changes its size. ">dw::core::Widget::queueResize</a>, with the value of the parent_ref member of this child.</li> +</ol> +</li> +</ol> +<p>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 <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> +<h1>Rules for Methods Related to Resizing </h1> +<p>Which method can be called, when the call of another method is not finished? These rules are important in two circumstances:</p> +<ol type="1"> +<li>To know which method can be called, and, especially, which methods must not* be called, within the implementation of sizeRequestImpl* (called by <em>sizeRequest</em>), <em>markSizeChange</em>, and markExtremesChange* (the latter two are called by <em>queueResize</em>).</li> +<li>On the other hand, to make sure that the calls, which are allowed, are handled correctly, especially in implementations of sizeRequestImpl*, <em>markSizeChange</em>, <em>markExtremesChange</em></li> +</ol> +<p>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.</p> +<p>Short recap:</p> +<ul> +<li><em>QueueResize</em> directly calls <em>markSizeChange</em> and markExtremesChanges*, and queues an idle function for the actual resizing (<a class="el" href="classdw_1_1core_1_1Layout.html#a7792ba666460057e47208128719e4659">dw::core::Layout::resizeIdle</a>). (The idle function is called some time after <em>queueResize</em> is finished.)</li> +<li>The resize idle function first calls <em>sizeRequest</em>, then sizeAllocate*, for the toplevel widget.</li> +</ul> +<p>In the following table, the rules are defined in detail. "Within call +of ..." includes all methods called from the original method: the first row (<em>queueResize</em>) defines also the rules for markExtremesChanges* and <em>markExtremesChanges</em>, and in the second row (<em>sizeAllocate</em>), even <em>sizeRequest</em> has to be considered.</p> +<div style="border: 2px solid #ff4040; margin-bottom: 0.5em; +padding: 0.5em 1em; background-color: #fff0f0"><b>Info:</b> Not up to date: <em>queueResize</em> can now be called recursively (so to speak). See code there.</div><table class="doxtable"> +<tr> +<th>Within call of ... ↓ </th><th>... is call allowed of ... ? → </th><th>queueResize </th><th>sizeAllocate </th><th>sizeRequest </th><th>getExtremes </th></tr> +<tr> +<th colspan="2">queueResize </th><td>No </td><td>No<sup>1</sup> </td><td>No<sup>1</sup> </td><td>No<sup>1</sup> </td></tr> +<tr> +<th colspan="2">sizeAllocate </th><td>Yes </td><td>Only for children<sup>2</sup> </td><td>Yes(?) </td><td>Yes(?) </td></tr> +<tr> +<th colspan="2">sizeRequest </th><td>Yes<sup>3</sup> </td><td>No </td><td>Limited<sup>4</sup> </td><td>Limited<sup>4</sup> </td></tr> +<tr> +<th colspan="2">getExtremes </th><td>Yes<sup>3</sup> </td><td>No </td><td>Limited<sup>4</sup> </td><td>Limited<sup>4</sup> </td></tr> +<tr> +<td colspan="6"><p class="starttd"><sup>1</sup>) Otherwise, since these other methods may be call <em>queueResize</em>, the limitation that <em>queueResize</em> must not call <em>queueResize</em> can be violated.</p> +<p><sup>2</sup>) Could perhaps be loosened as for <em>sizeRequest</em> and getExtremes*, but there is probably no need.</p> +<p><sup>3</sup>) Therefore the distinction between <em>RESIZE_QUEUED</em> and NEEDS_RESIZE*, and <em>EXTREMES_QUEUED</em> and <em>EXTREMES_CHANGED</em>, respectively.</p> +<p class="endtd"><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 <em>sizeRequest</em> / <em>getExtremes</em> for direct ancestors. </p> +</td></tr> +</table> +<p>Furthermore, <em>sizeAllocate</em> can only be called within a call of <a class="el" href="classdw_1_1core_1_1Layout.html#a207403098d5487ea6fdcd4b6d31cee5a">dw::core::Layout::resizeIdleId</a>, so (if you do not touch <a class="el" href="namespacedw_1_1core.html" title="The core of Dw is defined in this namespace. ">dw::core</a>) do not call it outside of <em>sizeAllocateImpl</em>. The other methods can be called outsize; e. g. <em>sizeRequest</em> is called in <a class="el" href="classdw_1_1Textblock.html#a1bebe0d704f071b07066bfb671cede7c">dw::Textblock::addWidget</a>.</p> +<p>To avoid painful debugging, there are some tests for the cases that one method call is strictly forbidden while another method is called.</p> +<p>This could be done furthermore:</p> +<ul> +<li>The tests could be refined.</li> +<li>Is it possible to define exacter rules, along with a proof that no problems (like endless recursion) can occur? </li> +</ul> +</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> |