diff options
author | Sebastian Geerken <devnull@localhost> | 2014-10-23 12:29:38 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2014-10-23 12:29:38 +0200 |
commit | d39956a7b0a38ebeda147d52aa734e992c425d9f (patch) | |
tree | aa66d82bb61a4c38ff0de04bec8dad62d69f6294 | |
parent | 3afc8db366cdfed92f5c53a606cfc82e551c9084 (diff) |
More work on drawing: interruptions work now halfway.
-rw-r--r-- | dw/iterator.cc | 57 | ||||
-rw-r--r-- | dw/iterator.hh | 24 | ||||
-rw-r--r-- | dw/oofawarewidget.cc | 119 | ||||
-rw-r--r-- | dw/oofawarewidget.hh | 16 | ||||
-rw-r--r-- | dw/ooffloatsmgr.cc | 31 | ||||
-rw-r--r-- | dw/ooffloatsmgr.hh | 4 | ||||
-rw-r--r-- | dw/oofpositionedmgr.cc | 22 | ||||
-rw-r--r-- | dw/oofpositionedmgr.hh | 7 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 2 | ||||
-rw-r--r-- | dw/stackingcontextmgr.cc | 26 | ||||
-rw-r--r-- | dw/stackingcontextmgr.hh | 12 | ||||
-rw-r--r-- | dw/table.cc | 28 | ||||
-rw-r--r-- | dw/table.hh | 2 | ||||
-rw-r--r-- | dw/textblock.cc | 75 | ||||
-rw-r--r-- | dw/textblock.hh | 7 | ||||
-rw-r--r-- | dw/widget.cc | 66 | ||||
-rw-r--r-- | dw/widget.hh | 4 | ||||
-rw-r--r-- | test/dw_simple_container.cc | 4 | ||||
-rw-r--r-- | test/dw_simple_container.hh | 2 |
19 files changed, 391 insertions, 117 deletions
diff --git a/dw/iterator.cc b/dw/iterator.cc index dbb779f6..92a028d0 100644 --- a/dw/iterator.cc +++ b/dw/iterator.cc @@ -898,5 +898,62 @@ void CharIterator::unhighlight (CharIterator *it1, CharIterator *it2, } } +// --------------------------- +// StackingIteratorStack +// --------------------------- + +StackingIteratorStack::StackingIteratorStack () +{ + vector = new lout::container::untyped::Vector (1, true); + topPos = -1; +} + +StackingIteratorStack::~StackingIteratorStack () +{ + delete vector; +} + +void StackingIteratorStack::intoStringBuffer(lout::misc::StringBuffer *sb) +{ + sb->append ("[ "); + + for (int i = 0; i < vector->size (); i++) { + if (i != 0) + sb->append (" "); + if (i == topPos) + sb->append ("<b>"); + vector->get(i)->intoStringBuffer (sb); + if (i == topPos) + sb->append ("</b>"); + } + + sb->append (" ]"); +} + +void StackingIteratorStack::push (lout::object::Object *object) +{ + assert (atRealTop ()); + vector->put (object); + topPos++; +} + +void StackingIteratorStack::pop () +{ + assert (atRealTop ()); + vector->remove (vector->size () - 1); + topPos--; +} + +void StackingIteratorStack::forward () +{ + assert (!atRealTop ()); + topPos++; +} + +void StackingIteratorStack::backward () +{ + topPos--; +} + } // namespace core } // namespace dw diff --git a/dw/iterator.hh b/dw/iterator.hh index 9460adc4..773cf303 100644 --- a/dw/iterator.hh +++ b/dw/iterator.hh @@ -263,6 +263,30 @@ public: hpos, vpos); } }; +/** + * \brief Some completely different kind of iterator: ... + */ +class StackingIteratorStack +{ +private: + lout::container::untyped::Vector *vector; + int topPos; + +public: + StackingIteratorStack (); + ~StackingIteratorStack (); + + void intoStringBuffer(lout::misc::StringBuffer *sb); + + inline bool atRealTop () { return topPos == vector->size () - 1; } + inline lout::object::Object *getTop () { return vector->get (topPos); } + + void push (lout::object::Object *object); + void pop (); + void forward (); + void backward (); +}; + } // namespace core } // namespace dw diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc index f26591ce..e7efc204 100644 --- a/dw/oofawarewidget.cc +++ b/dw/oofawarewidget.cc @@ -26,7 +26,6 @@ using namespace dw; using namespace dw::core; using namespace dw::core::style; using namespace lout::object; -using namespace lout::container::untyped; using namespace lout::misc; namespace dw { @@ -48,6 +47,17 @@ const char *OOFAwareWidget::OOFStackIterator::majorLevelText (int majorLevel) } } +void OOFAwareWidget::OOFStackIterator::intoStringBuffer(StringBuffer *sb) +{ + sb->append ("("); + sb->append (majorLevelText (majorLevel)); + sb->append (", "); + sb->appendInt (minorLevel); + sb->append (", "); + sb->appendInt (index); + sb->append (")"); +} + int OOFAwareWidget::CLASS_ID = -1; OOFAwareWidget::OOFAwareWidget () @@ -83,6 +93,20 @@ void OOFAwareWidget::notifySetAsTopLevel () = oofContainer[OOFM_FIXED] = this; } +bool OOFAwareWidget::getOOFMIndex (Widget *widget) +{ + if (testWidgetFloat (widget)) + return OOFM_FLOATS; + else if (testWidgetAbsolutelyPositioned (widget)) + return OOFM_ABSOLUTE; + else if (testWidgetFixedlyPositioned (widget)) + return OOFM_FIXED; + else { + lout::misc::assertNotReached (); + return -1; + } +} + bool OOFAwareWidget::isOOFContainer (Widget *widget, int oofmIndex) { // TODO The methods isPossibleContainer() and isPossibleContainerParent() @@ -270,18 +294,75 @@ void OOFAwareWidget::containerSizeChangedForChildrenOOF () outOfFlowMgr[i]->containerSizeChangedForChildren (); } -Widget *OOFAwareWidget::draw (View *view, Rectangle *area, Stack *iterator) +bool OOFAwareWidget::doesWidgetOOFInterruptDrawing (Widget *widget, + OOFAwareWidget *generator, + OOFAwareWidget *container) +{ + DBG_OBJ_ENTER_O ("draw", 0, (void*)NULL, "doesWidgetOOFInterruptDrawing", + "%p, %p, %p", widget, generator, container); + + int cl = container->stackingContextWidget->getLevel (), + gl = generator->stackingContextWidget->getLevel (); + + DBG_OBJ_MSGF_O ("draw", 1, (void*)NULL, "%d < %d => %s", + cl, gl, cl < gl ? "true" : "false"); + + DBG_OBJ_LEAVE_O ((void*)NULL); + return cl < gl; +} + +bool OOFAwareWidget::doesWidgetOOFInterruptDrawing (Widget *widget) +{ + DBG_OBJ_ENTER ("draw", 0, "doesWidgetOOFInterruptDrawing", "%p", widget); + + // This is the generator of the widget. + int oofmIndex = getOOFMIndex (widget); + DBG_OBJ_MSGF ("draw", 1, "oofmIndex = %d", oofmIndex); + + bool b = + doesWidgetOOFInterruptDrawing (widget, this, oofContainer[oofmIndex]); + DBG_OBJ_MSGF ("draw", 1, "=> %s", b ? "true" : "false"); + + DBG_OBJ_LEAVE (); + return b; +} + +Widget *OOFAwareWidget::draw (View *view, Rectangle *area, + StackingIteratorStack *iteratorStack) { DBG_OBJ_ENTER ("draw", 0, "draw", "%d, %d, %d * %d", area->x, area->y, area->width, area->height); - OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop (); + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); Widget *retWidget = NULL; while (retWidget == NULL && osi->majorLevel < OOFStackIterator::END) { - retWidget = drawLevel (view, area, iterator, osi->majorLevel); + retWidget = drawLevel (view, area, iteratorStack, osi->majorLevel); + + if (retWidget) { + if (retWidget->getParent () == this) { + DBG_OBJ_MSGF ("draw", 1, "interrupted at %p, drawing seperately", + retWidget); + DBG_IF_RTFL { + StringBuffer sb; + iteratorStack->intoStringBuffer (&sb); + DBG_OBJ_MSGF ("draw", 2, "iteratorStack: %s", sb.getChars ()); + } - if (retWidget == NULL) { + core::Rectangle retWidgetArea; + if (retWidget->intersects (area, &retWidgetArea)) { + // Similar to Widget::drawToplevel. Nested + // interruptions are not allowed. + StackingIteratorStack iteratorStack2; + Widget *retWidget2 = + retWidget->drawTotal (view, &retWidgetArea, &iteratorStack2); + assert (retWidget2 == NULL); + } + + retWidget = NULL; // Continue with the current state of "iterator". + DBG_OBJ_MSG ("draw", 1, "done with interruption"); + } + } else { osi->majorLevel++; osi->minorLevel = osi->index = 0; } @@ -293,7 +374,8 @@ Widget *OOFAwareWidget::draw (View *view, Rectangle *area, Stack *iterator) return retWidget; } -Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator, +Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, + StackingIteratorStack *iteratorStack, int majorLevel) { DBG_OBJ_ENTER ("draw", 0, "OOFAwareWidget/drawLevel", @@ -313,9 +395,9 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator, case OOFStackIterator::SC_BOTTOM: if (stackingContextMgr) { - OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop (); + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); retWidget = - stackingContextMgr->drawBottom (view, area, iterator, + stackingContextMgr->drawBottom (view, area, iteratorStack, &osi->minorLevel, &osi->index); } break; @@ -329,14 +411,14 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator, break; case OOFStackIterator::OOF_CONT: - retWidget = drawOOF (view, area, iterator); + retWidget = drawOOF (view, area, iteratorStack); break; case OOFStackIterator::SC_TOP: if (stackingContextMgr) { - OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop (); + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); retWidget = - stackingContextMgr->drawTop (view, area, iterator, + stackingContextMgr->drawTop (view, area, iteratorStack, &osi->minorLevel, &osi->index); } break; @@ -351,19 +433,22 @@ Widget *OOFAwareWidget::drawLevel (View *view, Rectangle *area, Stack *iterator, } Widget *OOFAwareWidget::drawOOF (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator) + StackingIteratorStack *iteratorStack) { - OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop (); + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); assert (osi->majorLevel == OOFStackIterator::OOF_CONT); Widget *retWidget = NULL; - for (; retWidget == NULL && osi->minorLevel < NUM_OOFM; osi->minorLevel++) { + while (retWidget == NULL && osi->minorLevel < NUM_OOFM) { if(outOfFlowMgr[osi->minorLevel]) - retWidget = outOfFlowMgr[osi->minorLevel]->draw (view, area, iterator, - &(osi->index)); - if (retWidget == NULL) + retWidget = + outOfFlowMgr[osi->minorLevel]->draw (view, area, iteratorStack, + &(osi->index)); + if (retWidget == NULL) { + osi->minorLevel++; osi->index = 0; + } } return retWidget; diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh index bef075a3..362069dc 100644 --- a/dw/oofawarewidget.hh +++ b/dw/oofawarewidget.hh @@ -111,6 +111,8 @@ protected: END } ; int majorLevel, minorLevel, index; + void intoStringBuffer(lout::misc::StringBuffer *sb); + static const char *majorLevelText (int majorLevel4); }; @@ -171,6 +173,8 @@ protected: static inline bool testWidgetRelativelyPositioned (Widget *widget) { return widget->getStyle()->position == core::style::POSITION_RELATIVE; } + static bool getOOFMIndex (Widget *widget); + void initOutOfFlowMgrs (); void correctRequisitionByOOF (core::Requisition *requisition, void (*splitHeightFun) (int, int*, int*)); @@ -178,11 +182,12 @@ protected: void sizeAllocateStart (core::Allocation *allocation); void sizeAllocateEnd (); void containerSizeChangedForChildrenOOF (); + virtual Widget *drawLevel (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int majorLevel); Widget *drawOOF (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator); + core::StackingIteratorStack *iteratorStack); Widget *getWidgetOOFAtPoint (int x, int y); static bool isOOFContainer (Widget *widget, int oofmIndex); @@ -203,8 +208,13 @@ public: OOFAwareWidget (); ~OOFAwareWidget (); + static bool doesWidgetOOFInterruptDrawing (Widget *widget, + OOFAwareWidget *generator, + OOFAwareWidget *container); + bool doesWidgetOOFInterruptDrawing (Widget *widget); + Widget *draw (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator); + core::StackingIteratorStack *iteratorStack); lout::object::Object *stackingIterator (bool atEnd); virtual void borderChanged (int y, core::Widget *vloat); diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc index f6f488f2..5373d84c 100644 --- a/dw/ooffloatsmgr.cc +++ b/dw/ooffloatsmgr.cc @@ -1278,8 +1278,7 @@ int OOFFloatsMgr::calcFloatX (Float *vloat, Side side, int gbX, int gbWidth, } Widget *OOFFloatsMgr::draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, - int *index) + StackingIteratorStack *iteratorStack, int *index) { DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]", area->x, area->y, area->width, area->height, *index); @@ -1287,10 +1286,11 @@ Widget *OOFFloatsMgr::draw (View *view, Rectangle *area, Widget *retWidget = NULL; if (*index < leftFloatsCB->size ()) - retWidget = drawFloats (leftFloatsCB, view, area, iterator, index, 0); + retWidget = + drawFloats (leftFloatsCB, view, area, iteratorStack, index, 0); if (retWidget == NULL) - retWidget = drawFloats (rightFloatsCB, view, area, iterator, index, + retWidget = drawFloats (rightFloatsCB, view, area, iteratorStack, index, leftFloatsCB->size ()); DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); @@ -1300,7 +1300,7 @@ Widget *OOFFloatsMgr::draw (View *view, Rectangle *area, Widget *OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, + StackingIteratorStack *iteratorStack, int *index, int startIndex) { // This could be improved, since the list is sorted: search the @@ -1309,12 +1309,21 @@ Widget *OOFFloatsMgr::drawFloats (SortedFloatsVector *list, View *view, Widget *retWidget = NULL; - for (; retWidget == NULL && *index - startIndex < list->size(); (*index)++) { - Widget *childWidget = list->get(*index - startIndex)->getWidget (); - Rectangle childArea; - if (!StackingContextMgr::handledByStackingContextMgr (childWidget) && - childWidget->intersects (area, &childArea)) - retWidget = childWidget->drawTotal (view, &childArea, iterator); + while (retWidget == NULL && *index - startIndex < list->size()) { + Float *vloat = list->get(*index - startIndex); + Widget *childWidget = vloat->getWidget (); + + if (!OOFAwareWidget:: doesWidgetOOFInterruptDrawing + (childWidget, vloat->generatingBlock, container)) { + Rectangle childArea; + if (!StackingContextMgr::handledByStackingContextMgr (childWidget) && + childWidget->intersects (area, &childArea)) + retWidget = + childWidget->drawTotal (view, &childArea, iteratorStack); + } + + if (retWidget == NULL) + (*index)++; } return retWidget; diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh index e90a72be..f7f994d7 100644 --- a/dw/ooffloatsmgr.hh +++ b/dw/ooffloatsmgr.hh @@ -286,7 +286,7 @@ private: core::Widget *drawFloats (SortedFloatsVector *list, core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int *index, int startIndex); core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y); @@ -343,7 +343,7 @@ public: void sizeAllocateEnd (OOFAwareWidget *caller); void containerSizeChangedForChildren (); core::Widget *draw (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, int *index); + core::StackingIteratorStack *iteratorStack, int *index); void markSizeChange (int ref); void markExtremesChange (int ref); diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc index 07bc45aa..c0c31417 100644 --- a/dw/oofpositionedmgr.cc +++ b/dw/oofpositionedmgr.cc @@ -169,7 +169,7 @@ bool OOFPositionedMgr::haveExtremesChanged () Widget *OOFPositionedMgr::draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, + StackingIteratorStack *iteratorStack, int *index) { DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]", @@ -177,12 +177,20 @@ Widget *OOFPositionedMgr::draw (View *view, Rectangle *area, Widget *retWidget = NULL; - for (; retWidget == NULL && *index < children->size(); (*index)++) { - Widget *childWidget = children->get(*index)->widget; - Rectangle childArea; - if (!StackingContextMgr::handledByStackingContextMgr (childWidget) && - childWidget->intersects (area, &childArea)) - retWidget = childWidget->drawTotal (view, &childArea, iterator); + while (retWidget == NULL && *index < children->size()) { + Child *child = children->get(*index); + + if (!OOFAwareWidget:: doesWidgetOOFInterruptDrawing + (child->widget, child->generator, container)) { + Rectangle childArea; + if (!StackingContextMgr::handledByStackingContextMgr (child->widget) && + child->widget->intersects (area, &childArea)) + retWidget = + child->widget->drawTotal (view, &childArea, iteratorStack); + } + + if (retWidget == NULL) + (*index)++; } DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh index c7f55262..819c4558 100644 --- a/dw/oofpositionedmgr.hh +++ b/dw/oofpositionedmgr.hh @@ -13,10 +13,11 @@ protected: class Child: public lout::object::Object { public: - core::Widget *widget, *generator; + core::Widget *widget; + OOFAwareWidget *generator; int x, y; - inline Child (core::Widget *widget, core::Widget *generator) + inline Child (core::Widget *widget, OOFAwareWidget *generator) { this->widget = widget; this->generator = generator; x = y = 0; } }; @@ -65,7 +66,7 @@ public: void sizeAllocateEnd (OOFAwareWidget *caller); void containerSizeChangedForChildren (); core::Widget *draw (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, int *index); + core::StackingIteratorStack *iteratorStack, int *index); void markSizeChange (int ref); void markExtremesChange (int ref); diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh index 5b74e513..15a94081 100644 --- a/dw/outofflowmgr.hh +++ b/dw/outofflowmgr.hh @@ -26,7 +26,7 @@ public: virtual void sizeAllocateEnd (OOFAwareWidget *caller) = 0; virtual void containerSizeChangedForChildren () = 0; virtual core::Widget *draw (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int *index) = 0; virtual void markSizeChange (int ref) = 0; diff --git a/dw/stackingcontextmgr.cc b/dw/stackingcontextmgr.cc index c104f5ee..70b4dd75 100644 --- a/dw/stackingcontextmgr.cc +++ b/dw/stackingcontextmgr.cc @@ -61,34 +61,33 @@ void StackingContextMgr::addChildSCWidget (Widget *widget) } Widget *StackingContextMgr::drawBottom (View *view, Rectangle *area, - lout::container::untyped::Stack - *iterator, + StackingIteratorStack *iteratorStack, int *zIndexOffset, int *index) { DBG_OBJ_ENTER ("draw", 0, "drawBottom", "(%d, %d, %d * %d), [%d], [%d]", area->x, area->y, area->width, area->height, *zIndexOffset, *index); Widget *retWidget = - draw (view, area, iterator, index, INT_MIN, -1, zIndexOffset); + draw (view, area, iteratorStack, index, INT_MIN, -1, zIndexOffset); DBG_OBJ_LEAVE (); return retWidget; } Widget *StackingContextMgr::drawTop (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, + StackingIteratorStack *iteratorStack, int *zIndexOffset, int *index) { DBG_OBJ_ENTER ("draw", 0, "drawTop", "(%d, %d, %d * %d), [%d], [%d]", area->x, area->y, area->width, area->height, *zIndexOffset, *index); Widget *retWidget = - draw (view, area, iterator, index, 0, INT_MAX, zIndexOffset); + draw (view, area, iteratorStack, index, 0, INT_MAX, zIndexOffset); DBG_OBJ_LEAVE (); return retWidget; } Widget *StackingContextMgr::draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, + StackingIteratorStack *iteratorStack, int *zIndexOffset, int startZIndex, int endZIndex, int *index) { @@ -102,24 +101,27 @@ Widget *StackingContextMgr::draw (View *view, Rectangle *area, Widget *retWidget = NULL; int startZIndexEff = max (minZIndex, startZIndex), endZIndexEff = min (maxZIndex, endZIndex); - for (; retWidget == NULL && *zIndexOffset + startZIndexEff <= endZIndexEff; - (*zIndexOffset)++) { + while (retWidget == NULL && *zIndexOffset + startZIndexEff <= endZIndexEff) { DBG_OBJ_MSGF ("draw", 1, "drawing zIndex = %d + %d", *zIndexOffset, startZIndexEff); DBG_OBJ_MSG_START (); - // TODO This is wrong. - for (; retWidget == NULL && *index < childSCWidgets->size (); - (*index)++) { + while (retWidget == NULL && *index < childSCWidgets->size ()) { Widget *child = childSCWidgets->get (*index); DBG_OBJ_MSGF ("draw", 2, "widget %p has zIndex = %d", child, child->getStyle()->zIndex); Rectangle childArea; if (child->getStyle()->zIndex == *zIndexOffset + startZIndexEff && child->intersects (area, &childArea)) - retWidget = child->drawTotal (view, &childArea, iterator); + retWidget = child->drawTotal (view, &childArea, iteratorStack); + + if (retWidget == NULL) + (*index)++; } + if (retWidget == NULL) + (*zIndexOffset)++; + DBG_OBJ_MSG_END (); } diff --git a/dw/stackingcontextmgr.hh b/dw/stackingcontextmgr.hh index 7f86c22c..10a929cf 100644 --- a/dw/stackingcontextmgr.hh +++ b/dw/stackingcontextmgr.hh @@ -24,8 +24,8 @@ private: int minZIndex, maxZIndex; Widget *draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, - int *zIndexOffset, int startZIndex, int endZIndex, int *index); + StackingIteratorStack *iteratorStack, int *zIndexOffset, + int startZIndex, int endZIndex, int *index); Widget *getWidgetAtPoint (int x, int y, int startZIndex, int endZIndex); public: @@ -48,11 +48,11 @@ public: void addChildSCWidget (Widget *widget); Widget *drawBottom (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, - int *zIndexOffset, int *index); + StackingIteratorStack *iteratorStack, int *zIndexOffset, + int *index); Widget *drawTop (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator, - int *zIndexOffset, int *index); + StackingIteratorStack *iteratorStack, int *zIndexOffset, + int *index); Widget *getTopWidgetAtPoint (int x, int y); Widget *getBottomWidgetAtPoint (int x, int y); diff --git a/dw/table.cc b/dw/table.cc index f9858ddd..3e53ec58 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -357,7 +357,7 @@ bool Table::isBlockLevel () } core::Widget *Table::drawLevel (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int majorLevel) { DBG_OBJ_ENTER ("draw", 0, "Table/drawLevel", "(%d, %d, %d * %d), %s", @@ -386,19 +386,29 @@ core::Widget *Table::drawLevel (core::View *view, core::Rectangle *area, switch (majorLevel) { case OOFStackIterator::IN_FLOW: - for (int i = 0; retWidget == NULL && i < children->size (); i++) { - if (childDefined (i)) { - Widget *child = children->get(i)->cell.widget; - core::Rectangle childArea; - if (!core::StackingContextMgr::handledByStackingContextMgr (child) - && child->intersects (area, &childArea)) - retWidget = child->drawTotal (view, &childArea, iterator); + { + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); + + while (retWidget == NULL && osi->index < children->size ()) { + if (childDefined (osi->index)) { + Widget *child = children->get(osi->index)->cell.widget; + core::Rectangle childArea; + if (!core::StackingContextMgr::handledByStackingContextMgr + (child) + && child->intersects (area, &childArea)) + retWidget = + child->drawTotal (view, &childArea, iteratorStack); + } + + if (retWidget == NULL) + osi->index++; } } break; default: - retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel); + retWidget = + OOFAwareWidget::drawLevel (view, area, iteratorStack, majorLevel); break; } diff --git a/dw/table.hh b/dw/table.hh index 502b1332..c6f23259 100644 --- a/dw/table.hh +++ b/dw/table.hh @@ -472,7 +472,7 @@ protected: bool isBlockLevel (); Widget *drawLevel (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int majorLevel); //bool buttonPressImpl (core::EventButton *event); diff --git a/dw/textblock.cc b/dw/textblock.cc index 4b915f2e..9ededeff 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -1449,12 +1449,12 @@ void Textblock::drawSpace(int wordIndex, core::View *view, */ core::Widget *Textblock::drawLine (Line *line, core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator) + core::StackingIteratorStack *iteratorStack) { DBG_OBJ_ENTER ("draw", 0, "drawLine", "..., %d, %d, %d * %d", area->x, area->y, area->width, area->height); - OOFStackIterator *osi = (OOFStackIterator*)iterator->getTop (); + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); Widget *retWidget = NULL; @@ -1470,9 +1470,8 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view, if (osi->index < line->firstWord) osi->index = line->firstWord; - for (; retWidget == NULL && osi->index <= line->lastWord - && xWidget < area->x + area->width; - osi->index++) { + while (retWidget == NULL && osi->index <= line->lastWord + && xWidget < area->x + area->width) { Word *word = words->getRef (osi->index); int wordSize = word->size.width; @@ -1487,7 +1486,8 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view, if (!core::StackingContextMgr::handledByStackingContextMgr (child) && child->intersects (area, &childArea)) - retWidget = child->drawTotal (view, &childArea, iterator); + retWidget = + child->drawTotal (view, &childArea, iteratorStack); } else { int wordIndex2 = osi->index; while (wordIndex2 < line->lastWord && @@ -1522,6 +1522,9 @@ core::Widget *Textblock::drawLine (Line *line, core::View *view, } } xWidget += wordSize + word->effSpace; + + if (retWidget == NULL) + osi->index++; } DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); @@ -1695,7 +1698,7 @@ Textblock::Word *Textblock::findWord (int x, int y, bool *inSpace) } core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int majorLevel) { DBG_OBJ_ENTER ("draw", 0, "Textblock/drawLevel", "(%d, %d, %d * %d), %s", @@ -1714,16 +1717,17 @@ core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area, break; DBG_OBJ_MSGF ("draw", 0, "line %d (of %d)", lineIndex, lines->size ()); - retWidget = drawLine (line, view, area, iterator); + retWidget = drawLine (line, view, area, iteratorStack); } break; case OOFStackIterator::OOF_REF: - // TODO + retWidget = drawOOFReferences (view, area, iteratorStack); break; default: - retWidget = OOFAwareWidget::drawLevel (view, area, iterator, majorLevel); + retWidget = + OOFAwareWidget::drawLevel (view, area, iteratorStack, majorLevel); break; } @@ -1732,6 +1736,45 @@ core::Widget *Textblock::drawLevel (core::View *view, core::Rectangle *area, return retWidget; } +core::Widget *Textblock::drawOOFReferences (core::View *view, + core::Rectangle *area, + core::StackingIteratorStack + *iteratorStack) +{ + DBG_OBJ_ENTER ("draw", 0, "Textblock/drawOOFReferences", "%d, %d, %d * %d", + area->x, area->y, area->width, area->height); + + // TODO Inefficient. Store Widgets OOF references in seperate list? + + OOFStackIterator *osi = (OOFStackIterator*)iteratorStack->getTop (); + assert (osi->majorLevel == OOFStackIterator::OOF_REF); + + Widget *retWidget = NULL; + + while (retWidget == NULL && osi->minorLevel < NUM_OOFM) { + while (retWidget == NULL && osi->index < words->size ()) { + Word *word = words->getRef (osi->index); + if (word->content.type == core::Content::WIDGET_OOF_REF && + getOOFMIndex (word->content.widget) == osi->minorLevel && + doesWidgetOOFInterruptDrawing (word->content.widget)) + retWidget = word->content.widget; + + // The index is increased in any case: the iterator must + // point to the next element. + osi->index++; + } + + if (retWidget == NULL) { + osi->minorLevel++; + osi->index = 0; + } + } + + DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); + DBG_OBJ_LEAVE (); + return retWidget; +} + /** * Add a new word (text, widget etc.) to a page. */ @@ -2291,18 +2334,10 @@ void Textblock::addWidget (core::Widget *widget, core::style::Style *style) initOutOfFlowMgrs (); if (testWidgetOutOfFlow (widget)) { - int oofmIndex = -1; - if (testWidgetFloat (widget)) - oofmIndex = OOFM_FLOATS; - else if (testWidgetAbsolutelyPositioned (widget)) - oofmIndex = OOFM_ABSOLUTE; - else if (testWidgetFixedlyPositioned (widget)) - oofmIndex = OOFM_FIXED; - else - lout::misc::assertNotReached (); - + int oofmIndex = getOOFMIndex (widget); widget->setParent (oofContainer[oofmIndex]); widget->setGenerator (this); + int oofmSubRef = searchOutOfFlowMgr(oofmIndex)->addWidgetOOF (widget, this, words->size ()); diff --git a/dw/textblock.hh b/dw/textblock.hh index c9f86fa5..4a5681e6 100644 --- a/dw/textblock.hh +++ b/dw/textblock.hh @@ -643,7 +643,10 @@ protected: void drawSpace (int wordIndex, core::View *view, core::Rectangle *area, int xWidget, int yWidgetBase); Widget *drawLine (Line *line, core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator); + core::StackingIteratorStack *iteratorStack); + Widget *drawOOFReferences (core::View *view, core::Rectangle *area, + core::StackingIteratorStack *iteratorStack); + int findLineIndex (int y); int findLineIndexWhenNotAllocated (int y); int findLineIndexWhenAllocated (int y); @@ -799,7 +802,7 @@ protected: void calcTextOffset (int lineIndex, int totalWidth); Widget *drawLevel (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator, + core::StackingIteratorStack *iteratorStack, int majorLevel); void sizeRequestImpl (core::Requisition *requisition); diff --git a/dw/widget.cc b/dw/widget.cc index cf955dec..e312ee6f 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -188,7 +188,7 @@ void Widget::draw (View *view, Rectangle *area) /** Area is given in widget coordinates. */ Widget *Widget::draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator) + StackingIteratorStack *iteratorStack) { // Suitable for widgets without children. draw (view, area); @@ -196,34 +196,64 @@ Widget *Widget::draw (View *view, Rectangle *area, } Widget *Widget::drawTotal (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator) + StackingIteratorStack *iteratorStack) { DBG_OBJ_ENTER ("draw", 0, "drawTotal", "%d, %d, %d * %d", area->x, area->y, area->width, area->height); - Object *si = stackingIterator (false); - if (si) { - iterator->push (si); - DBG_OBJ_MSGF ("draw", 1, "pushing on iterator; now %d element(s)", - iterator->size ()); + DBG_IF_RTFL { + misc::StringBuffer sb; + iteratorStack->intoStringBuffer (&sb); + DBG_OBJ_MSGF ("draw", 2, "initial iteratorStack: %s", sb.getChars ()); + } + + Object *si = NULL; + + if (iteratorStack->atRealTop ()) { + si = stackingIterator (false); + if (si) { + iteratorStack->push (si); + } } else - DBG_OBJ_MSGF ("draw", 1, "nothing on iterator; %d element(s)", - iterator->size ()); - + iteratorStack->forward (); - Widget *retWidget = draw (view, area, iterator); + DBG_IF_RTFL { + misc::StringBuffer sb; + iteratorStack->intoStringBuffer (&sb); + DBG_OBJ_MSGF ("draw", 2, "iteratorStack before drawing: %s", + sb.getChars ()); + } + + Widget *retWidget = draw (view, area, iteratorStack); + DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); + + DBG_IF_RTFL { + misc::StringBuffer sb; + iteratorStack->intoStringBuffer (&sb); + DBG_OBJ_MSGF ("draw", 2, "iteratorStack after drawing: %s", + sb.getChars ()); + } // A return value other than NULL indicates a widget with a complex // drawing process, for which stackIterator() must return something // non-NULL, so that the interrupted drawing process can be - // continued. + // continued. (TODO: Not quite correct when forward() was called + // instead of push().) + + // assert (retWidget == NULL || si != NULL); - assert (retWidget == NULL || si != NULL); + if (retWidget == NULL) { + if (si) + iteratorStack->pop (); + } else + iteratorStack->backward (); - if (retWidget == NULL && si != NULL) - iterator->pop (); + DBG_IF_RTFL { + misc::StringBuffer sb; + iteratorStack->intoStringBuffer (&sb); + DBG_OBJ_MSGF ("draw", 2, "final iteratorStack: %s", sb.getChars ()); + } - DBG_OBJ_MSGF ("draw", 1, "=> %p", retWidget); DBG_OBJ_LEAVE (); return retWidget; } @@ -232,8 +262,8 @@ void Widget::drawToplevel (View *view, Rectangle *area) { assert (parent == NULL); - lout::container::untyped::Stack iterator (true); - Widget *retWidget = drawTotal (view, area, &iterator); + StackingIteratorStack iteratorStack; + Widget *retWidget = drawTotal (view, area, &iteratorStack); // Everything should be finished at this point. assert (retWidget == NULL); diff --git a/dw/widget.hh b/dw/widget.hh index d44454bc..a4a84cac 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -471,9 +471,9 @@ public: bool intersects (Rectangle *area, Rectangle *intersection); virtual Widget *draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator); + StackingIteratorStack *iteratorStack); Widget *drawTotal (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator); + StackingIteratorStack *iteratorStack); void drawToplevel (View *view, Rectangle *area); bool buttonPress (EventButton *event); diff --git a/test/dw_simple_container.cc b/test/dw_simple_container.cc index cdc7df5f..9507e233 100644 --- a/test/dw_simple_container.cc +++ b/test/dw_simple_container.cc @@ -206,14 +206,14 @@ namespace dw { } core::Widget *SimpleContainer::draw (View *view, Rectangle *area, - lout::container::untyped::Stack *iterator) + StackingIteratorStack *iteratorStack) { Widget *retWidget = NULL; drawWidgetBox (view, area, false); Rectangle childArea; if (child && child->intersects (area, &childArea)) - retWidget = child->drawTotal (view, &childArea, iterator); + retWidget = child->drawTotal (view, &childArea, iteratorStack); return retWidget; } diff --git a/test/dw_simple_container.hh b/test/dw_simple_container.hh index 0aa19ad6..251df8fb 100644 --- a/test/dw_simple_container.hh +++ b/test/dw_simple_container.hh @@ -45,7 +45,7 @@ public: ~SimpleContainer (); Widget *draw (core::View *view, core::Rectangle *area, - lout::container::untyped::Stack *iterator); + core::StackingIteratorStack *iteratorStack); core::Iterator *iterator (core::Content::Type mask, bool atEnd); void removeChild (Widget *child); |