aboutsummaryrefslogtreecommitdiff
path: root/dw
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-09-12 20:28:56 +0200
committerSebastian Geerken <devnull@localhost>2014-09-12 20:28:56 +0200
commitae2d990af432ea56375936e5ec9872fe0503d61f (patch)
tree0b5bf1d9fbce4481ae3fc49b86b6362ae071a12f /dw
parentf9f3fcc4b5f72de36d6cb231baeaf21a3b615704 (diff)
Table gets OOF aware, part 1. Warning: crashes!
Diffstat (limited to 'dw')
-rw-r--r--dw/oofawarewidget.cc81
-rw-r--r--dw/oofawarewidget.hh58
-rw-r--r--dw/oofpositionedmgr.cc2
-rw-r--r--dw/outofflowmgr.hh3
-rw-r--r--dw/table.cc14
-rw-r--r--dw/table.hh4
-rw-r--r--dw/textblock.cc81
-rw-r--r--dw/textblock.hh32
8 files changed, 173 insertions, 102 deletions
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index 5747b78e..a71b3f0d 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -45,6 +45,17 @@ OOFAwareWidget::OOFAwareWidget ()
OOFAwareWidget::~OOFAwareWidget ()
{
+ for (int i = 0; i < NUM_OOFM; i++) {
+ if(outOfFlowMgr[i]) {
+ // I feel more comfortable by letting the OOF aware widget delete
+ // these widgets, instead of doing this in ~OutOfFlowMgr.
+ for (int j = 0; j < outOfFlowMgr[i]->getNumWidgets (); j++)
+ delete outOfFlowMgr[i]->getWidget (j);
+
+ delete outOfFlowMgr[i];
+ }
+ }
+
DBG_OBJ_DELETE ();
}
@@ -132,8 +143,7 @@ void OOFAwareWidget::notifySetParent ()
oofContainer[oofmIndex] = (OOFAwareWidget*)widget;
}
- DBG_OBJ_ARRSET_PTR ("containingBlock", oofmIndex,
- containingBlock[oofmIndex]);
+ DBG_OBJ_ARRSET_PTR ("oofContainer", oofmIndex, oofContainer[oofmIndex]);
assert (oofContainer[oofmIndex] != NULL);
}
@@ -163,6 +173,46 @@ void OOFAwareWidget::initOutOfFlowMgrs ()
}
}
+void OOFAwareWidget::correctRequisitionByOOF (Requisition *requisition)
+{
+ for (int i = 0; i < NUM_OOFM; i++) {
+ if (outOfFlowMgr[i]) {
+ int oofWidth, oofHeight;
+ DBG_OBJ_MSGF ("resize", 1,
+ "before considering widgets by OOFM #%d: %d * (%d + %d)",
+ i, requisition->width, requisition->ascent,
+ requisition->descent);
+
+ outOfFlowMgr[i]->getSize (requisition, &oofWidth, &oofHeight);
+
+ if (oofWidth > requisition->width)
+ requisition->width = oofWidth;
+ if (oofHeight > requisition->ascent + requisition->descent)
+ requisition->descent = oofHeight - requisition->ascent;
+ }
+ }
+}
+
+void OOFAwareWidget::correctExtremesByOOF (Extremes *extremes)
+{
+ for (int i = 0; i < NUM_OOFM; i++) {
+ if (outOfFlowMgr[i]) {
+ int oofMinWidth, oofMaxWidth;
+ outOfFlowMgr[i]->getExtremes (extremes, &oofMinWidth, &oofMaxWidth);
+
+ DBG_OBJ_MSGF ("resize", 1, "OOFM (#%d) correction: %d / %d",
+ i, oofMinWidth, oofMaxWidth);
+
+ extremes->minWidth = max (extremes->minWidth, oofMinWidth);
+ extremes->minWidthIntrinsic = max (extremes->minWidthIntrinsic,
+ oofMinWidth);
+ extremes->maxWidth = max (extremes->maxWidth, oofMaxWidth);
+ extremes->maxWidthIntrinsic = max (extremes->maxWidthIntrinsic,
+ oofMinWidth);
+ }
+ }
+}
+
void OOFAwareWidget::sizeAllocateStart (core::Allocation *allocation)
{
@@ -178,6 +228,33 @@ void OOFAwareWidget::sizeAllocateEnd ()
oofContainer[i]->outOfFlowMgr[i]->sizeAllocateEnd (this);
}
+void OOFAwareWidget::containerSizeChangedForChildrenOOF ()
+{
+ for (int i = 0; i < NUM_OOFM; i++)
+ if (outOfFlowMgr[i])
+ outOfFlowMgr[i]->containerSizeChangedForChildren ();
+}
+
+void OOFAwareWidget::drawOOF (View *view, Rectangle *area)
+{
+ for (int i = 0; i < NUM_OOFM; i++)
+ if(outOfFlowMgr[i])
+ outOfFlowMgr[i]->draw(view, area);
+}
+
+Widget *OOFAwareWidget::getWidgetOOFAtPoint (int x, int y, int level)
+{
+ for (int i = 0; i < NUM_OOFM; i++) {
+ Widget *oofWidget =
+ outOfFlowMgr[i] ?
+ outOfFlowMgr[i]->getWidgetAtPoint (x, y, level) : NULL;
+ if (oofWidget)
+ return oofWidget;
+ }
+
+ return NULL;
+}
+
void OOFAwareWidget::borderChanged (int y, Widget *vloat)
{
assertNotReached ();
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index 7121f9ea..9421bae0 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -14,6 +14,26 @@ namespace oof {
*
* (Perhaps it should be diffenciated between the two roles, container
* and generator, but this would make multiple inheritance necessary.)
+ *
+ * A sub class should at least take care to call these methods at the
+ * respective points:
+ *
+ * - dw::oof::OOFAwareWidget::correctRequisitionByOOF (from
+ * dw::core::Widget::getExtremesImpl)
+ * - dw::oof::OOFAwareWidget::correctExtremesByOOF (from
+ * dw::core::Widget::sizeRequestImpl)
+ * - dw::oof::OOFAwareWidget::sizeAllocateStart
+ * - dw::oof::OOFAwareWidget::sizeAllocateEnd (latter two from
+ * dw::core::Widget::sizeAllocateImpl)
+ * - dw::oof::OOFAwareWidget::containerSizeChangedForChildrenOOF
+ * (from dw::core::Widget::containerSizeChangedForChildren)
+ * - dw::oof::OOFAwareWidget::drawOOF (from dw::core::Widget::draw)
+ * - dw::oof::OOFAwareWidget::getWidgetOOFAtPoint (from
+ * dw::core::Widget::getWidgetAtPoint)
+ *
+ * See dw::Textblock on how this is done best. For both generators and
+ * containers of floats (which is only implemented by dw::Textblock)
+ * it gets a bit more complicated.
*/
class OOFAwareWidget: public core::Widget
{
@@ -22,6 +42,39 @@ protected:
enum { PARENT_REF_OOFM_BITS = 2,
PARENT_REF_OOFM_MASK = (1 << PARENT_REF_OOFM_BITS) - 1 };
+ inline bool isParentRefOOF (int parentRef)
+ { return parentRef != -1 && (parentRef & PARENT_REF_OOFM_MASK); }
+
+ inline int makeParentRefInFlow (int inFlowSubRef)
+ { return (inFlowSubRef << PARENT_REF_OOFM_BITS); }
+ inline int getParentRefInFlowSubRef (int parentRef)
+ { assert (!isParentRefOOF (parentRef));
+ return parentRef >> PARENT_REF_OOFM_BITS; }
+
+ inline int makeParentRefOOF (int oofmIndex, int oofmSubRef)
+ { return (oofmSubRef << PARENT_REF_OOFM_BITS) | (oofmIndex + 1); }
+ inline int getParentRefOOFSubRef (int parentRef)
+ { assert (isParentRefOOF (parentRef));
+ return parentRef >> PARENT_REF_OOFM_BITS; }
+ inline int getParentRefOOFIndex (int parentRef)
+ { assert (isParentRefOOF (parentRef));
+ return (parentRef & PARENT_REF_OOFM_MASK) - 1; }
+ inline oof::OutOfFlowMgr *getParentRefOutOfFlowMgr (int parentRef)
+ { return outOfFlowMgr[getParentRefOOFIndex (parentRef)]; }
+
+ inline bool isWidgetOOF (Widget *widget)
+ { return isParentRefOOF (widget->parentRef); }
+
+ inline int getWidgetInFlowSubRef (Widget *widget)
+ { return getParentRefInFlowSubRef (widget->parentRef); }
+
+ inline int getWidgetOOFSubRef (Widget *widget)
+ { return getParentRefOOFSubRef (widget->parentRef); }
+ inline int getWidgetOOFIndex (Widget *widget)
+ { return getParentRefOOFIndex (widget->parentRef); }
+ inline oof::OutOfFlowMgr *getWidgetOutOfFlowMgr (Widget *widget)
+ { return getParentRefOutOfFlowMgr (widget->parentRef); }
+
OOFAwareWidget *oofContainer[NUM_OOFM];
OutOfFlowMgr *outOfFlowMgr[NUM_OOFM];
@@ -43,8 +96,13 @@ protected:
{ return widget->getStyle()->position == core::style::POSITION_RELATIVE; }
void initOutOfFlowMgrs ();
+ void correctRequisitionByOOF (core::Requisition *requisition);
+ void correctExtremesByOOF (core::Extremes *extremes);
void sizeAllocateStart (core::Allocation *allocation);
void sizeAllocateEnd ();
+ void containerSizeChangedForChildrenOOF ();
+ void drawOOF (core::View *view, core::Rectangle *area);
+ core::Widget *getWidgetOOFAtPoint (int x, int y, int level);
void notifySetAsTopLevel();
void notifySetParent();
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index e314e641..709a5b91 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -181,7 +181,7 @@ void OOFPositionedMgr::addWidgetInFlow (OOFAwareWidget *widget,
{
}
-int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generater,
+int OOFPositionedMgr::addWidgetOOF (Widget *widget, OOFAwareWidget *generator,
int externalIndex)
{
DBG_OBJ_ENTER ("construct.oofm", 0, "addWidgetOOF", "%p, %p, %d",
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index 0245803c..405db354 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -5,6 +5,9 @@
namespace dw {
+/**
+ * \brief Out Of Flow. See \ref dw-out-of-flow.
+ */
namespace oof {
class OOFAwareWidget;
diff --git a/dw/table.cc b/dw/table.cc
index 746856c7..a59c0120 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -124,6 +124,9 @@ void Table::sizeRequestImpl (core::Requisition *requisition)
correctRequisition (requisition, core::splitHeightPreserveDescent);
+ // For the order, see similar reasoning for dw::Textblock.
+ correctRequisitionByOOF (requisition);
+
DBG_OBJ_LEAVE ();
}
@@ -152,6 +155,9 @@ void Table::getExtremesImpl (core::Extremes *extremes)
correctExtremes (extremes);
+ // For the order, see similar reasoning for dw::Textblock.
+ correctExtremesByOOF (extremes);
+
DBG_OBJ_LEAVE ();
}
@@ -161,6 +167,8 @@ void Table::sizeAllocateImpl (core::Allocation *allocation)
allocation->x, allocation->y, allocation->width,
allocation->ascent, allocation->descent);
+ sizeAllocateStart (allocation);
+
calcCellSizes (true);
/**
@@ -201,6 +209,8 @@ void Table::sizeAllocateImpl (core::Allocation *allocation)
x += colWidths->get (col) + getStyle()->hBorderSpacing;
}
+ sizeAllocateEnd ();
+
DBG_OBJ_LEAVE ();
}
@@ -306,6 +316,8 @@ void Table::containerSizeChangedForChildren ()
}
}
+ containerSizeChangedForChildrenOOF ();
+
DBG_OBJ_LEAVE ();
}
@@ -371,6 +383,8 @@ void Table::draw (core::View *view, core::Rectangle *area)
child->draw (view, &childArea);
}
}
+
+ drawOOF (view, area);
}
void Table::removeChild (Widget *child)
diff --git a/dw/table.hh b/dw/table.hh
index a8823ca0..dffec1be 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -1,7 +1,7 @@
#ifndef __DW_TABLE_HH__
#define __DW_TABLE_HH__
-#include "core.hh"
+#include "oofawarewidget.hh"
#include "alignedtablecell.hh"
#include "../lout/misc.hh"
@@ -319,7 +319,7 @@ namespace dw {
* Here, \em foo-bar refers to the attribute \em bar of the tag \em foo foo.
* Look at the HTML parser for more details.
*/
-class Table: public core::Widget
+class Table: public oof::OOFAwareWidget
{
private:
struct Child
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 64f5fc23..2706fba4 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -300,18 +300,6 @@ Textblock::~Textblock ()
delete words;
delete anchors;
- for (int i = 0; i < NUM_OOFM; i++) {
- if(outOfFlowMgr[i]) {
- // I feel more comfortable by letting the textblock delete these
- // widgets, instead of doing this in ~OutOfFlowMgr.
-
- for (int j = 0; j < outOfFlowMgr[i]->getNumWidgets (); j++)
- delete outOfFlowMgr[i]->getWidget (j);
-
- delete outOfFlowMgr[i];
- }
- }
-
/* Make sure we don't own widgets anymore. Necessary before call of
parent class destructor. (???) */
words = NULL;
@@ -404,22 +392,7 @@ void Textblock::sizeRequestImpl (core::Requisition *requisition)
// Is this really what we want? An alternative could be that
// OutOfFlowMgr::getSize honours CSS attributes an corrected sizes.
- for (int i = 0; i < NUM_OOFM; i++) {
- if (outOfFlowMgr[i]) {
- int oofWidth, oofHeight;
- DBG_OBJ_MSGF ("resize", 1,
- "before considering widgets by OOFM #%d: %d * (%d + %d)",
- i, requisition->width, requisition->ascent,
- requisition->descent);
-
- outOfFlowMgr[i]->getSize (requisition, &oofWidth, &oofHeight);
-
- if (oofWidth > requisition->width)
- requisition->width = oofWidth;
- if (oofHeight > requisition->ascent + requisition->descent)
- requisition->descent = oofHeight - requisition->ascent;
- }
- }
+ correctRequisitionByOOF (requisition);
DBG_OBJ_MSGF ("resize", 1, "final: %d * (%d + %d)",
requisition->width, requisition->ascent, requisition->descent);
@@ -500,22 +473,7 @@ void Textblock::getExtremesImpl (core::Extremes *extremes)
extremes->minWidth, extremes->minWidthIntrinsic,
extremes->maxWidth, extremes->maxWidthIntrinsic);
- for (int i = 0; i < NUM_OOFM; i++) {
- if (outOfFlowMgr[i]) {
- int oofMinWidth, oofMaxWidth;
- outOfFlowMgr[i]->getExtremes (extremes, &oofMinWidth, &oofMaxWidth);
-
- DBG_OBJ_MSGF ("resize", 1, "OOFM (#%d) correction: %d / %d",
- i, oofMinWidth, oofMaxWidth);
-
- extremes->minWidth = misc::max (extremes->minWidth, oofMinWidth);
- extremes->minWidthIntrinsic =
- misc::max (extremes->minWidthIntrinsic, oofMinWidth);
- extremes->maxWidth = misc::max (extremes->maxWidth, oofMaxWidth);
- extremes->maxWidthIntrinsic =
- misc::max (extremes->maxWidthIntrinsic, oofMinWidth);
- }
- }
+ correctExtremesByOOF (extremes);
DBG_OBJ_MSGF ("resize", 0,
"finally, after considering OOFM: %d (%d) / %d (%d)",
@@ -770,9 +728,7 @@ void Textblock::containerSizeChangedForChildren ()
word->content.widget->containerSizeChanged ();
}
- for (int i = 0; i < NUM_OOFM; i++)
- if (outOfFlowMgr[i])
- outOfFlowMgr[i]->containerSizeChangedForChildren ();
+ containerSizeChangedForChildrenOOF ();
DBG_OBJ_LEAVE ();
}
@@ -782,7 +738,7 @@ bool Textblock::affectsSizeChangeContainerChild (Widget *child)
DBG_OBJ_ENTER ("resize", 0,
"Textblock/affectsSizeChangeContainerChild", "%p", child);
- // See Textblock::getAvailWidthForChild() and Textblock::oofSizeChanged():
+ // See Textblock::getAvailWidthOfChild() and Textblock::oofSizeChanged():
// Extremes changes affect the size of the child, too:
bool ret;
if (!mustBeWidenedToAvailWidth () &&
@@ -836,9 +792,10 @@ void Textblock::markSizeChange (int ref)
now, but addLine(...) will do everything necessary. */
if (ref != -1) {
if (wrapRefLines == -1)
- wrapRefLines = getParentRefLineNo (ref);
+ wrapRefLines = getParentRefInFlowSubRef (ref);
else
- wrapRefLines = misc::min (wrapRefLines, getParentRefLineNo (ref));
+ wrapRefLines = misc::min (wrapRefLines,
+ getParentRefInFlowSubRef (ref));
}
DBG_OBJ_SET_NUM ("wrapRefLines", wrapRefLines);
@@ -869,10 +826,10 @@ void Textblock::markExtremesChange (int ref)
now, but addLine(...) will do everything necessary. */
if (ref != -1) {
if (wrapRefParagraphs == -1)
- wrapRefParagraphs = getParentRefLineNo (ref);
+ wrapRefParagraphs = getParentRefInFlowSubRef (ref);
else
wrapRefParagraphs =
- misc::min (wrapRefParagraphs, getParentRefLineNo (ref));
+ misc::min (wrapRefParagraphs, getParentRefInFlowSubRef (ref));
}
DBG_OBJ_SET_NUM ("wrapRefParagraphs", wrapRefParagraphs);
@@ -1703,9 +1660,7 @@ void Textblock::draw (core::View *view, core::Rectangle *area)
drawLine (line, view, area);
}
- for (int i = 0; i < NUM_OOFM; i++)
- if(outOfFlowMgr[i])
- outOfFlowMgr[i]->draw(view, area);
+ drawOOF (view, area);
DBG_OBJ_LEAVE ();
}
@@ -2550,7 +2505,7 @@ void Textblock::addParbreak (int space, core::style::Style *style)
if (!isfirst) {
/* The text block we searched for has been found. */
Word *word2;
- int lineno = getWidgetLineNo (widget);
+ int lineno = getWidgetInFlowSubRef (widget);
if (lineno > 0 &&
(word2 =
@@ -2664,7 +2619,7 @@ void Textblock::breakAdded ()
* This is an optimized version of the general
* dw::core::Widget::getWidgetAtPoint method.
*/
-core::Widget *Textblock::getWidgetAtPoint(int x, int y, int level)
+core::Widget *Textblock::getWidgetAtPoint (int x, int y, int level)
{
//printf ("%*s-> examining the %s %p (%d, %d, %d x (%d + %d))\n",
// 3 * level, "", getClassName (), this, allocation.x, allocation.y,
@@ -2683,13 +2638,9 @@ core::Widget *Textblock::getWidgetAtPoint(int x, int y, int level)
// First, search for widgets out of flow, notably floats, since
// there are cases where they overlap child textblocks. Should
// later be refined using z-index.
- for (int i = 0; i < NUM_OOFM; i++) {
- Widget *oofWidget =
- outOfFlowMgr[i] ?
- outOfFlowMgr[i]->getWidgetAtPoint (x, y, level) : NULL;
- if (oofWidget)
- return oofWidget;
- }
+ Widget *oofWidget = getWidgetOOFAtPoint (x, y, level);
+ if (oofWidget)
+ return oofWidget;
lineIndex = findLineIndexWhenAllocated (y - allocation.y);
@@ -3012,7 +2963,7 @@ void Textblock::oofSizeChanged (bool extremesChanged)
extremesChanged ? "true" : "false");
queueResize (-1, extremesChanged);
- // See Textblock::getAvailWidthForChild(): Extremes changes may become also
+ // See Textblock::getAvailWidthOfChild(): Extremes changes may become also
// relevant for the children, under certain conditions:
if (extremesChanged && !mustBeWidenedToAvailWidth ())
containerSizeChanged ();
diff --git a/dw/textblock.hh b/dw/textblock.hh
index dc496550..82b62b2a 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -246,38 +246,6 @@ private:
static const char *hyphenDrawChar;
protected:
- inline bool isParentRefOOF (int parentRef)
- { return parentRef != -1 && (parentRef & PARENT_REF_OOFM_MASK); }
-
- inline int makeParentRefInFlow (int lineNo)
- { return (lineNo << PARENT_REF_OOFM_BITS); }
- inline int getParentRefLineNo (int parentRef)
- { assert (!isParentRefOOF (parentRef));
- return parentRef >> PARENT_REF_OOFM_BITS; }
-
- inline int makeParentRefOOF (int oofmIndex, int oofmSubRef)
- { return (oofmSubRef << PARENT_REF_OOFM_BITS) | (oofmIndex + 1); }
- inline int getParentRefOOFSubRef (int parentRef)
- { assert (isParentRefOOF (parentRef));
- return parentRef >> PARENT_REF_OOFM_BITS; }
- inline int getParentRefOOFIndex (int parentRef)
- { assert (isParentRefOOF (parentRef));
- return (parentRef & PARENT_REF_OOFM_MASK) - 1; }
- inline oof::OutOfFlowMgr *getParentRefOutOfFlowMgr (int parentRef)
- { return outOfFlowMgr[getParentRefOOFIndex (parentRef)]; }
-
- inline bool isWidgetOOF (Widget *widget)
- { return isParentRefOOF (widget->parentRef); }
-
- inline int getWidgetLineNo (Widget *widget)
- { return getParentRefLineNo (widget->parentRef); }
-
- inline int getWidgetOOFSubRef (Widget *widget)
- { return getParentRefOOFSubRef (widget->parentRef); }
- inline int getWidgetOOFIndex (Widget *widget)
- { return getParentRefOOFIndex (widget->parentRef); }
- inline oof::OutOfFlowMgr *getWidgetOutOfFlowMgr (Widget *widget)
- { return getParentRefOutOfFlowMgr (widget->parentRef); }
/**
* \brief Implementation used for words.