diff options
Diffstat (limited to 'old/dw/html/dw-layout-widgets.html')
-rw-r--r-- | old/dw/html/dw-layout-widgets.html | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/old/dw/html/dw-layout-widgets.html b/old/dw/html/dw-layout-widgets.html new file mode 100644 index 0000000..f8a7143 --- /dev/null +++ b/old/dw/html/dw-layout-widgets.html @@ -0,0 +1,198 @@ +<!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: Layout and 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">Layout and Widgets </div> </div> +</div><!--header--> +<div class="contents"> +<div class="textblock"><p>Both, the layouting and the drawing is delegated to a tree of widgets. A widget represents a given part of the document, e.g. a text block, a table, or an image. Widgets may be nested, so layouting and drawing may be delegated by one widget to its child widgets.</p> +<p>Where to define the borders of a widget, whether to combine different widgets to one, or to split one widget into multiple ones, should be considered based on different concerns:</p> +<ul> +<li> +<p class="startli">First, there are some restrictions of Dw:</p> +<ul> +<li> +The allocation (this is the space a widget allocates at a time) of a dillo widget is always rectangular, and </li> +<li> +the allocation of a child widget must be a within the allocation of the parent widget. </li> +</ul> +<p class="endli"></p> +</li> +<li> +<p class="startli">Since some widgets are already rather complex, an important goal is to keep the implementation of the widget simple.</p> +<p class="endli"></p> +</li> +<li> +Furthermore, the granularity should not be too fine, because of the overhead each single widget adds. </li> +</ul> +<p>For CSS, there will be a document tree on top of Dw, this will be flexible enough when mapping the document structure on the widget structure, so you should not have the document structure in mind.</p> +<h2>Sizes</h2> +<p><a class="el" href="dw-widget-sizes.html">Sizes of Dillo Widgets</a></p> +<h2>Styles</h2> +<p>Each widget is assigned a style, 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> for more informations.</p> +<h2>Iterators</h2> +<p>Widgets must implement <a class="el" href="classdw_1_1core_1_1Widget.html#ab66387121a56322ea6e4168db857e013" title="Return an iterator for this widget. ">dw::core::Widget::iterator</a>. There are several common iterators:</p> +<ul> +<li> +<a class="el" href="classdw_1_1core_1_1EmptyIterator.html" title="This implementation of dw::core::Iterator can be used by widgets with no contents. ">dw::core::EmptyIterator</a>, and </li> +<li> +<a class="el" href="classdw_1_1core_1_1TextIterator.html" title="This implementation of dw::core::Iterator can be used by widgets having one text word as contents...">dw::core::TextIterator</a>. </li> +</ul> +<p>Both hide the constructor, use the <em>create</em> method.</p> +<p>These simple iterators only iterate through one widget, it does not have to iterate recursively through child widgets. Instead, the type dw::core::Content::WIDGET is returned, and the next call of <a class="el" href="classdw_1_1core_1_1Iterator.html#a72f475e2c830ed8ef3b437f23a37c976" title="Move iterator forward and store content it. ">dw::core::Iterator::next</a> will return the piece of contents <em>after</em> (not within) this child widget.</p> +<p>This makes implementation much simpler, for recursive iteration, there is <a class="el" href="classdw_1_1core_1_1DeepIterator.html" title="A stack of iterators, to iterate recursively through a widget tree. ">dw::core::DeepIterator</a>.</p> +<h2>Anchors and Scrolling</h2> +<dl class="todo"><dt><b><a class="el" href="todo.html#_todo000001">Todo:</a></b></dt><dd>This section is not implemented yet, after the implementation, the documentation should be reviewed.</dd></dl> +<p>Here is a description, what is to be done for a widget implementation. How to jump to anchors, set scrolling positions etc. is described in <a class="el" href="dw-usage.html">Dillo Widget Usage</a>.</p> +<h3>Anchors</h3> +<p>Anchors are position markers, which are identified by a name, which is unique in the widget tree. The widget must care about anchors in three different situations:</p> +<ol> +<li> +<p class="startli">Adding an anchor is inititiated by a specific widget method, e.g. <a class="el" href="classdw_1_1Textblock.html#a773ae4c773fee751945c78c67e10caac">dw::Textblock::addAnchor</a>. Here, <a class="el" href="classdw_1_1core_1_1Widget.html#a70dfa18448d79453d468b4946ac97e35">dw::core::Widget::addAnchor</a> must be called,</p> +<p class="endli"></p> +</li> +<li> +<p class="startli">Whenever the position of an anchor is changed, <a class="el" href="classdw_1_1core_1_1Widget.html#a7da6906a643cd93d893dbfa902f17065">dw::core::Widget::changeAnchor</a> is called (typically, this is done in the implementation of <a class="el" href="classdw_1_1core_1_1Widget.html#a756379942a5254e22c087f6bb62a23a5" title="See Sizes of Dillo Widgets. ">dw::core::Widget::sizeAllocateImpl</a>).</p> +<p class="endli"></p> +</li> +<li> +When a widget is destroyed, the anchor must be removed, by calling <a class="el" href="classdw_1_1core_1_1Widget.html#adc3f28fc5dd2cdb76118c2d39fe7b5f5">dw::core::Widget::removeAnchor</a>. </li> +</ol> +<p>All these methods are delegated to <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>, which manages anchors centrally. If the anchor in question has been set to jump to, the viewport position is automatically adjusted, see <a class="el" href="dw-usage.html">Dillo Widget Usage</a>.</p> +<h2>Drawing</h2> +<p>In two cases, a widget has to be drawn:</p> +<ol> +<li> +as a reaction on an expose event, </li> +<li> +if the widget content has changed and it needs to be redrawn. </li> +</ol> +<p>In both cases, drawing is done by the implementation of <a class="el" href="classdw_1_1core_1_1Widget.html#a2e7d05212aabad32824fd577fb7e3dd7">dw::core::Widget::draw</a>, which draws into the view.</p> +<p>Each view provides some primitive methods for drawing, most should be obvious. Note that the views do not know anything about dillo widgets, and so coordinates have to be passed as canvas coordinates.</p> +<p>A widget may only draw in its own allocation. If this cannot be achieved, a <em>clipping view</em> can be used, this is described in <a class="el" href="dw-layout-views.html">Layout and Views</a>. Generally, drawing should then look like:</p> +<div class="fragment"><div class="line"><span class="keywordtype">void</span> Foo::draw (<a class="code" href="classdw_1_1core_1_1View.html">dw::core::View</a> *view, <a class="code" href="classdw_1_1core_1_1Rectangle.html">dw::core::Rectangle</a> *area)</div> +<div class="line">{</div> +<div class="line"> <span class="comment">// 1. Create a clipping view.</span></div> +<div class="line"> <a class="code" href="classdw_1_1core_1_1View.html">dw::core::View</a> clipView =</div> +<div class="line"> view-><a class="code" href="classdw_1_1core_1_1View.html#ac65430bcd8b9c6c18d5d184dc22d1615">getClippingView</a> (allocation.x, allocation.y,</div> +<div class="line"> allocation.width, getHeight ());</div> +<div class="line"></div> +<div class="line"> <span class="comment">// 2. Draw into clip_view</span></div> +<div class="line"> clipView->doSomeDrawing (...);</div> +<div class="line"></div> +<div class="line"> <span class="comment">// 3. Draw the children, they receive the clipping view as argument.</span></div> +<div class="line"> <a class="code" href="classdw_1_1core_1_1Rectangle.html">dw::core::Rectangle</a> *childArea</div> +<div class="line"> <span class="keywordflow">for</span> (<all relevant children>) {</div> +<div class="line"> <span class="keywordflow">if</span> (child->intersects (area, &childArea))</div> +<div class="line"> child-><a class="code" href="classdw_1_1core_1_1Rectangle.html#a499c5b7e4acaf3afa2cee3d71b2152df">draw</a> (clipView, childArea);</div> +<div class="line"> }</div> +<div class="line"></div> +<div class="line"> <span class="comment">// 4. Merge</span></div> +<div class="line"> view-><a class="code" href="classdw_1_1core_1_1View.html#a040f3722c187b7f73464f7d0dc38c80a">mergeClippingView</a> (clipView);</div> +<div class="line">}</div> +</div><!-- fragment --><p>Clipping views are expensive, so they should be avoided when possible.</p> +<p>The second argument to <a class="el" href="classdw_1_1core_1_1Widget.html#a2e7d05212aabad32824fd577fb7e3dd7">dw::core::Widget::draw</a> is the region, which has to be drawn. This may (but needs not) be used for optimization.</p> +<p>If a widget contains child widgets, it must explicitly draw these children (see also code example above). For this, there is the useful method <a class="el" href="classdw_1_1core_1_1Widget.html#a1e7825cca2c7caa025f33a80fc4aa5ed" title="Calculates the intersection of the visible allocation (i. e. the intersection with the visible parent...">dw::core::Widget::intersects</a>, which returns, which area of the child must be drawn.</p> +<h3>Explicit Redrawing</h3> +<p>If a widget changes its contents, so that it must be redrawn, it must call <a class="el" href="classdw_1_1core_1_1Widget.html#a68e995505b0885143024e3254253f2d8">dw::core::Widget::queueDrawArea</a> or <a class="el" href="classdw_1_1core_1_1Widget.html#ad29af9bf2a21855596fbc26214aed57b">dw::core::Widget::queueDraw</a>. The first variant expects a region within the widget, the second will cause the whole widget to be redrawn. This will cause an asynchronous call of <a class="el" href="classdw_1_1core_1_1Widget.html#a2e7d05212aabad32824fd577fb7e3dd7">dw::core::Widget::draw</a>.</p> +<p>If only the size changes, a call 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> is sufficient, this will also queue a complete redraw (see <a class="el" href="dw-widget-sizes.html">Sizes of Dillo Widgets</a>.)</p> +<h2>Mouse Events</h2> +<p>A widget may process mouse events. The view (<a class="el" href="dw-layout-views.html">Layout and Views</a>) passes mouse events to the layout, which then passes them to the widgets. There are two kinds of mouse events:</p> +<ul> +<li> +events returning bool, and </li> +<li> +events returning nothing (void). </li> +</ul> +<p>The first group consists of:</p> +<ul> +<li> +<a class="el" href="classdw_1_1core_1_1Widget.html#a8f80526115c77c5278dd2a55908ddafc">dw::core::Widget::buttonPressImpl</a>, </li> +<li> +<a class="el" href="classdw_1_1core_1_1Widget.html#ae678879143710922e300ef84469db06c">dw::core::Widget::buttonReleaseImpl</a>, and </li> +<li> +<a class="el" href="classdw_1_1core_1_1Widget.html#a503758ba435032d5099012677b547c18">dw::core::Widget::motionNotifyImpl</a>. </li> +</ul> +<p>For these events, a widget returns a boolean value, which denotes, whether the widget has processed this event (true) or not (false). In the latter case, the event is delegated according to the following rules:</p> +<ol> +<li> +First, this event is passed to the bottom-most widget, in which allocation the mouse position is in. </li> +<li> +If the widget does not process this event (returning false), it is passed to the parent, and so on. </li> +<li> +The final result (whether <em>any</em> widget has processed this event) is returned to the view. </li> +</ol> +<p>The view may return this to the UI toolkit, which then interprets this in a similar way (whether the viewport, a UI widget, has processed this event).</p> +<p>These events return nothing:</p> +<ul> +<li> +<a class="el" href="classdw_1_1core_1_1Widget.html#a6047114d9f01dd62c722f97fa24d6307">dw::core::Widget::enterNotifyImpl</a> and </li> +<li> +<a class="el" href="classdw_1_1core_1_1Widget.html#a0e1921ae635435b9cd1a55da7b0c0e09">dw::core::Widget::leaveNotifyImpl</a>. </li> +</ul> +<p>since they are bound to a widget.</p> +<p>When processing mouse events, the layout always deals with two widgets: the widget, the mouse pointer was in, when the previous mouse event was processed, (below called the "old widget") and the widget, in which the mouse pointer is now ("new widget").</p> +<p>The following paths are calculated:</p> +<ol> +<li> +the path from the old widget to the nearest common ancestor of the old and the new widget, and </li> +<li> +the path from this ancestor to the new widget. </li> +</ol> +<p>For the widgets along these paths, <a class="el" href="classdw_1_1core_1_1Widget.html#a6047114d9f01dd62c722f97fa24d6307">dw::core::Widget::enterNotifyImpl</a> and <a class="el" href="classdw_1_1core_1_1Widget.html#a0e1921ae635435b9cd1a55da7b0c0e09">dw::core::Widget::leaveNotifyImpl</a> are called.</p> +<h3>Signals</h3> +<p>If a caller outside of the widget is interested in these events, he can connect a <a class="el" href="classdw_1_1core_1_1Layout_1_1LinkReceiver.html">dw::core::Layout::LinkReceiver</a>. For those events with a boolean return value, the results of the signal emission is regarded, i.e. the delegation of an event to the parent of the widget can be stopped by a signal receiver returning true, even if the widget method returns false.</p> +<p>First, the widget method is called, then (in any case) the signal is emitted.</p> +<h3>Selection</h3> +<p>If your widget has selectable contents, it should delegate the events to <a class="el" href="classdw_1_1core_1_1SelectionState.html" title="This class handles selections, as well as activation of links, which is closely related. ">dw::core::SelectionState</a> (<a class="el" href="classdw_1_1core_1_1Layout.html#a667dab9d62b69fe95ffbe5e1c579ab92">dw::core::Layout::selectionState</a>).</p> +<h2>Miscellaneous</h2> +<h3>Cursors</h3> +<p>Each widget has a cursor, which is set by <a class="el" href="classdw_1_1core_1_1Widget.html#a761535b4f71744668c78a81914002bd1">dw::core::Widget::setCursor</a>. If a cursor is assigned to a part of a widget, this widget must process mouse events, and call <a class="el" href="classdw_1_1core_1_1Widget.html#a761535b4f71744668c78a81914002bd1">dw::core::Widget::setCursor</a> explicitly.</p> +<p>(This will change, cursors should become part of <a class="el" href="classdw_1_1core_1_1style_1_1Style.html">dw::core::style::Style</a>.)</p> +<h3>Background</h3> +<p>Backgrounds are part of styles (<a class="el" href="classdw_1_1core_1_1style_1_1StyleAttrs.html#aeb27b877af330de69ab7f03a2015d5ea">dw::core::style::Style::backgroundColor</a>). If a widget assigns background colors to parts of a widget (as <a class="el" href="classdw_1_1Table.html" title="A Widget for rendering tables. ">dw::Table</a> does for rows), it must call <a class="el" href="classdw_1_1core_1_1Widget.html#ad19935d3edd15314426251e06f5daf0e" title="Set the background "behind" the widget, if it is not the background of the parent widget...">dw::core::Widget::setBgColor</a> for the children inside this part. </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> |