aboutsummaryrefslogtreecommitdiff
path: root/devdoc/dw-interrupted-drawing.doc
diff options
context:
space:
mode:
Diffstat (limited to 'devdoc/dw-interrupted-drawing.doc')
-rw-r--r--devdoc/dw-interrupted-drawing.doc121
1 files changed, 121 insertions, 0 deletions
diff --git a/devdoc/dw-interrupted-drawing.doc b/devdoc/dw-interrupted-drawing.doc
new file mode 100644
index 00000000..c7037666
--- /dev/null
+++ b/devdoc/dw-interrupted-drawing.doc
@@ -0,0 +1,121 @@
+/** \page dw-interrupted-drawing Interrupted drawing
+
+Describing the problem
+======================
+
+Without interrupting drawing (which is described below), a widget can
+define the order in which its parts (background, non-widget content,
+child widgets, etc.) are drawn, but it must be drawn as a whole. There
+are situations when this is not possible.
+
+Consider the following simple HTML document:
+
+ <head>
+ <style>
+ #sc-1 { position: relative; z-index: 1; background: #ffe0e0; }
+ #fl-1 { float: right; background: #b0ffb0; }
+ #sc-2 { position: relative; z-index: 1; background: #f0f0ff; }
+ </style>
+ </head>
+ <body>
+ <div id="sc-1">
+ <div id="fl-1">
+ Float, line 1/3<br/>
+ Float, line 2/3<br/>
+ Float, line 3/3
+ </div>
+ Stacking Context 1
+ <div id="sc-2">Stacking Context 2</div>
+ </div>
+ </body>
+
+The rendering will look like this:
+
+\image html dw-interrupted-drawing-1.png
+
+Note the missing "Float, line 2/3" of element #fl-1, which is covered
+by element #sc-2.
+
+As described in \ref dw-out-of-flow, it has to be distinguished
+between the *container* hierarchy (equivalent to the hierarchy of
+dw::core::Widget.) and the the *generator* hierarchy. In the following
+diagram, the former is represented by solid lines, the latter by
+dotted lines:
+
+\dot
+digraph G {
+ node [shape=rect, fontname=Helvetica, fontsize=10];
+ edge [arrowhead="vee"];
+
+ "#sc-1" [fillcolor="#ffe0e0", style="filled"];
+ "#fl-1" [fillcolor="#b0ffb0", style="filled"];
+ "#sc-2" [fillcolor="#f0f0ff", style="filled"];
+
+ "body" -> "#sc-1";
+ "body" -> "#fl-1";
+ { rank=same; "#sc-1" -> "#fl-1" [style=dotted]; }
+ "#sc-1" -> "#sc-2";
+}
+\enddot
+
+
+The drawing order of the four elements (represented by widgets) is:
+
+- body,
+- #sc-1,
+- #fl-1,
+- #sc-2.
+
+Since
+
+1. #sc-2 is a child of #sc-1, but
+2. #fl-1 is a child of the body, and
+3. a widget can only draw its descendants (not neccessary children,
+ but drawing siblings is not allowed),
+
+#sc-1 cannot be drawn as a whole; instead drawing is **interrupted**
+by #fl-1. This means:
+
+1. the background and text of #sc-1 is drawn;
+2. drawing of #sc-1 is **interrupted** by #fl-1 (see below for details),
+3. drawing of #sc-1 is **continued**, by drawing #sc-2.
+
+The exact control flow is described in this sequence diagram:
+
+\image html dw-interrupted-drawing-2.png
+
+
+When is drawing interrupted?
+============================
+
+A widget out of flow is regarded as part of the stacking context (see
+\ref dw-stacking-context) of its *generator* (in the example above:
+#fl-1 is part of the stacking context stablished by #sc-1, not the one
+established by body). For this reason, a widget out of flow must, in
+some cases, drawn while the *gerator* is drawn, as an
+interruption. The exact rule:
+
+A widget out of flow must be drawn as an interruption (while the
+*generator* is drawn) if the stacking context of the generator (to
+which this widget belongs) is in front of the stacking context of the
+container (the parent widget).
+
+See dw::oof::OOFAwareWidget::doesWidgetOOFInterruptDrawing.
+
+
+How does interruption of drawing work?
+======================================
+
+When a widget detects that an other widget should be drawn as
+interruption (see above), it calls dw::core::Widget::drawInterruption,
+which
+
+1. draws the widget within another "context" (area and reference
+ widget); for this the original drawing area
+ (dw::core::DrawingContext::getToplevelArea) is used.
+2. Using dw::core::DrawingContext::addWidgetDrawnAsInterruption, and
+ checking later with
+ dw::core::DrawingContext::hasWidgetBeenDrawnAsInterruption prevents
+ these widgets from being drawn twice.
+
+*/