diff options
author | Sebastian Geerken <devnull@localhost> | 2013-07-30 13:50:22 +0200 |
---|---|---|
committer | Sebastian Geerken <devnull@localhost> | 2013-07-30 13:50:22 +0200 |
commit | 97b54265687beaddd0b588b18994c68fe770a7d5 (patch) | |
tree | 514d5726a984f738a932afedc77ebad707bd7c75 /dw | |
parent | bc18e4cf0873bd191ea561e9825a156e1d28d131 (diff) |
Two bug fixes: (i) queueResize within sizeRequest should work now; (ii) resizes floats lead to correct rewrapping. (Unfortunately very unstable now again.)
Diffstat (limited to 'dw')
-rw-r--r-- | dw/layout.cc | 27 | ||||
-rw-r--r-- | dw/layout.hh | 1 | ||||
-rw-r--r-- | dw/outofflowmgr.cc | 94 | ||||
-rw-r--r-- | dw/outofflowmgr.hh | 5 | ||||
-rw-r--r-- | dw/table.cc | 4 | ||||
-rw-r--r-- | dw/table.hh | 2 | ||||
-rw-r--r-- | dw/textblock.cc | 8 | ||||
-rw-r--r-- | dw/ui.cc | 2 | ||||
-rw-r--r-- | dw/widget.cc | 48 | ||||
-rw-r--r-- | dw/widget.hh | 30 |
10 files changed, 165 insertions, 56 deletions
diff --git a/dw/layout.cc b/dw/layout.cc index 521f4f76..5285dfea 100644 --- a/dw/layout.cc +++ b/dw/layout.cc @@ -186,6 +186,8 @@ Layout::Layout (Platform *platform) topLevel = NULL; widgetAtPoint = NULL; + queueResizeList = new typed::Vector<Widget> (4, false); + DBG_OBJ_CREATE (this, "DwRenderLayout"); bgColor = NULL; @@ -233,6 +235,7 @@ Layout::~Layout () topLevel = NULL; delete w; } + delete queueResizeList; delete platform; delete view; delete anchorsTable; @@ -248,6 +251,7 @@ void Layout::addWidget (Widget *widget) topLevel = widget; widget->layout = this; + queueResizeList->clear (); widget->notifySetAsTopLevel(); findtextState.setWidget (widget); @@ -263,6 +267,7 @@ void Layout::removeWidget () * \bug Some more attributes must be reset here. */ topLevel = NULL; + queueResizeList->clear (); widgetAtPoint = NULL; canvasWidth = canvasAscent = canvasDescent = 0; scrollX = scrollY = 0; @@ -654,10 +659,28 @@ void Layout::setBgColor (style::Color *color) void Layout::resizeIdle () { //static int calls = 0; - //MSG(" Layout::resizeIdle calls = %d\n", ++calls); + //printf ("Layout::resizeIdle calls = %d\n", ++calls); assert (resizeIdleId != -1); + for (typed::Iterator <Widget> it = queueResizeList->iterator(); + it.hasNext (); ) { + Widget *widget = it.getNext (); + + //printf (" the %stop-level %s %p was queued (extremes changed: %s)\n", + // widget->parent ? "non-" : "", widget->getClassName(), widget, + // widget->extremesQueued () ? "yes" : "no"); + + widget->setFlags (Widget::NEEDS_RESIZE); + widget->unsetFlags (Widget::RESIZE_QUEUED); + + if (widget->extremesQueued ()) { + widget->setFlags (Widget::EXTREMES_CHANGED); + widget->unsetFlags (Widget::EXTREMES_QUEUED); + } + } + queueResizeList->clear (); + // Reset already here, since in this function, queueResize() may be // called again. resizeIdleId = -1; @@ -706,6 +729,8 @@ void Layout::resizeIdle () } updateAnchor (); + + //printf ("Layout::resizeIdle end\n"); } void Layout::setSizeHints () diff --git a/dw/layout.hh b/dw/layout.hh index 51d764a4..46fc9ffe 100644 --- a/dw/layout.hh +++ b/dw/layout.hh @@ -132,6 +132,7 @@ private: Platform *platform; View *view; Widget *topLevel, *widgetAtPoint; + lout::container::typed::Vector<Widget> *queueResizeList; /* The state, which must be projected into the view. */ style::Color *bgColor; diff --git a/dw/outofflowmgr.cc b/dw/outofflowmgr.cc index c6d87d44..fe1156b8 100644 --- a/dw/outofflowmgr.cc +++ b/dw/outofflowmgr.cc @@ -373,8 +373,9 @@ void OutOfFlowMgr::sizeAllocateEnd () sizeAllocateFloats (RIGHT); sizeAllocateAbsolutelyPositioned (); - // 3. Textblocks have already been allocated, but we store some - // information for later use. TODO: Update this comment! + // 3. Textblocks have already been allocated, but we (i) check + // allocation change of textblocks, and (ii) store some information + // for later use. for (lout::container::typed::Iterator<TypedPointer <Textblock> > it = tbInfosByTextblock->iterator (); it.hasNext (); ) { @@ -388,8 +389,10 @@ void OutOfFlowMgr::sizeAllocateEnd () int width = tbAllocation->width; int height = tbAllocation->ascent + tbAllocation->descent; + // (i) Check allocation change of textblocks. if ((!tbInfo->wasAllocated || tbInfo->xCB != xCB || tbInfo->yCB != yCB || tbInfo->width != width || tbInfo->height != height)) { + // Changed: change borders when covered by floats. int oldPos, newPos; Widget *oldFloat, *newFloat; // To calculate the minimum, both allocations, old and new, @@ -420,7 +423,8 @@ void OutOfFlowMgr::sizeAllocateEnd () } } } - + + // (ii) store some information for later use. tbInfo->wasAllocated = true; tbInfo->xCB = xCB; tbInfo->yCB = yCB; @@ -474,31 +478,42 @@ bool OutOfFlowMgr::isTextblockCoveredByFloats (SortedFloatsVector *list, // TODO binary search Float *v = list->get(i); - assert (wasAllocated (v->generatingBlock)); - - if (tb != v->generatingBlock) { - int flh = v->dirty ? 0 : v->size.ascent + v->size.descent; - int y1 = getAllocation(v->generatingBlock)->y + v->yReal; - int y2 = y1 + flh; - - // TODO: Also regard horizontal dimension (same for tellPositionOrNot). - if (y2 > tby && y1 < tby + tbHeight) { - covered = true; - if (y1 - tby < *floatPos) { - *floatPos = y1 - tby; - *vloat = v->widget; - } - } + // TODO Clarify the old condition: tb != v->generatingBlock. Neccessary? + if (tb != v->generatingBlock && + isTextblockCoveredByFloat (v, tb, tbx, tby, tbWidth, tbHeight, + floatPos)) { + covered = true; + *vloat = v->widget; } // All floarts are searched, to find the minimum. TODO: Are - // floats sorted, so this can be shortene? (The first is the + // floats sorted, so this can be shortened? (The first is the // minimum?) } return covered; } +bool OutOfFlowMgr::isTextblockCoveredByFloat (Float *vloat, Textblock *tb, + int tbx, int tby, + int tbWidth, int tbHeight, + int *floatPos) +{ + assert (wasAllocated (vloat->generatingBlock)); + + int flh = vloat->dirty ? 0 : vloat->size.ascent + vloat->size.descent; + int y1 = getAllocation(vloat->generatingBlock)->y + vloat->yReal; + int y2 = y1 + flh; + + // TODO: Also regard horizontal dimension (same for tellPositionOrNot)? + if (y2 > tby && y1 < tby + tbHeight) { + if (floatPos != NULL && y1 - tby < *floatPos) + *floatPos = y1 - tby; + return true; + } else + return false; +} + void OutOfFlowMgr::moveFromGBToCB (Side side) { SortedFloatsVector *dest = side == LEFT ? leftFloatsCB : rightFloatsCB; @@ -578,8 +593,8 @@ void OutOfFlowMgr::sizeAllocateFloats (Side side) vloat->widget->sizeAllocate (&childAllocation); - //printf ("allocate %s #%d -> (%d, %d), %d x (%d + %d)\n", - // right ? "right" : "left", i, childAllocation.x, + //printf (" allocate %s float #%d -> (%d, %d), %d x (%d + %d)\n", + // side == LEFT ? "left" : "right", i, childAllocation.x, // childAllocation.y, childAllocation.width, // childAllocation.ascent, childAllocation.descent); } @@ -790,9 +805,8 @@ void OutOfFlowMgr::markSizeChange (int ref) } vloat->dirty = true; - // TODO May cause problems (endless resizing?) when float has no - // defined position. - vloat->generatingBlock->borderChanged (vloat->yReal, vloat->widget); + + // Effects take place in ensureFloatSize. } else if (isRefAbsolutelyPositioned (ref)) { int i = getAbsolutelyPositionedIndexFromRef (ref); absolutelyPositioned->get(i)->dirty = true; @@ -1358,7 +1372,37 @@ void OutOfFlowMgr::ensureFloatSize (Float *vloat) // vloat->size.width, vloat->size.ascent, vloat->size.descent); vloat->cbAvailWidth = containingBlock->getAvailWidth (); - vloat->dirty = false; + vloat->dirty = false; + + // TODO (i) Comment (ii) linear search? + if (wasAllocated (vloat->generatingBlock)) { + //printf ("=== start checking textblocks ===\n"); + + for (lout::container::typed::Iterator<TypedPointer <Textblock> > it = + tbInfosByTextblock->iterator (); + it.hasNext (); ) { + Textblock *tb = it.getNext()->getTypedValue(); + if (wasAllocated (tb)) { + Allocation *tba = getAllocation (tb); + int floatPos; + + if (isTextblockCoveredByFloat + (vloat, tb, tba->x - containingBlockAllocation.x, + tba->y - containingBlockAllocation.y, + tba->width, tba->ascent + tba->descent, &floatPos)) { + //printf (" ---> yes: %p (parent: %p)\n", tb, + // tb->getParent()); + tb->borderChanged (floatPos, vloat->widget); + } //else + // printf (" ---> not covered: %p (parent: %p)\n", tb, + // tb->getParent()); + } //else + // printf (" ---> not allocated: %p (parent: %p)\n", tb, + // tb->getParent()); + } + + //printf ("=== end checking textblocks ===\n"); + } } } diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh index c373a50c..23b8134c 100644 --- a/dw/outofflowmgr.hh +++ b/dw/outofflowmgr.hh @@ -205,7 +205,10 @@ private: bool isTextblockCoveredByFloats (SortedFloatsVector *list, Textblock *tb, int tbx, int tby, int tbWidth, int tbHeight, int *floatPos, core::Widget **vloat); - + bool isTextblockCoveredByFloat (Float *vloat, Textblock *tb, + int tbx, int tby, int tbWidth, int tbHeight, + int *floatPos); + void drawFloats (SortedFloatsVector *list, core::View *view, core::Rectangle *area); void drawAbsolutelyPositioned (core::View *view, core::Rectangle *area); diff --git a/dw/table.cc b/dw/table.cc index 5587f469..be910a63 100644 --- a/dw/table.cc +++ b/dw/table.cc @@ -480,7 +480,7 @@ void Table::reallocChildren (int newNumCols, int newNumRows) void Table::calcCellSizes () { - if (needsResize ()) + if (needsResize () || resizeQueued ()) forceCalcCellSizes (); } @@ -638,7 +638,7 @@ void Table::apportionRowSpan () */ void Table::calcColumnExtremes () { - if (extremesChanged ()) + if (extremesChanged () || extremesQueued ()) forceCalcColumnExtremes (); } diff --git a/dw/table.hh b/dw/table.hh index b8feb835..4a14cfb6 100644 --- a/dw/table.hh +++ b/dw/table.hh @@ -71,7 +71,7 @@ namespace dw { * is the case. * * [C] Whether this function is called, depends on NEEDS_RESIZE / - * EXTREMES_CHANGED. + * RESIZE_QUEUED / EXTREMES_CHANGED / EXTREMES_QUEUED. * * * <h4>Apportionment</h4> diff --git a/dw/textblock.cc b/dw/textblock.cc index 35c9bb07..dc9fc484 100644 --- a/dw/textblock.cc +++ b/dw/textblock.cc @@ -2354,10 +2354,12 @@ void Textblock::queueDrawRange (int index1, int index2) void Textblock::borderChanged (int y, Widget *vloat) { - PRINTF ("[%p] Border has changed: %d (float %s %p, with generator %p)\n", + PRINTF ("[%p] BORDER_CHANGED: %d (float %s %p, with generator %p)\n", this, y, vloat->getClassName(), vloat, vloat->getGenerator()); int lineIndex = findLineIndex (y); + PRINTF (" Line index: %d (of %d).\n", lineIndex, lines->size ()); + // Nothing to do at all, when lineIndex >= lines->size (), // i. e. the change is below the bottom of this widget. if (lineIndex < lines->size ()) { @@ -2368,8 +2370,8 @@ void Textblock::borderChanged (int y, Widget *vloat) else wrapLineIndex = lineIndex; - PRINTF ("[%p] Rewrapping from line %d (of %d).\n", - this, wrapLineIndex, lines->size ()); + PRINTF (" Rewrapping from line %d (of %d).\n", + wrapLineIndex, lines->size ()); if (vloat->getGenerator() == this) { bool found = false; @@ -268,7 +268,7 @@ void ComplexButtonResource::LayoutReceiver::canvasSizeChanged (int width, /** * \todo Verify that this is correct. */ - resource->queueResize (resource->childWidget->extremesChanged ()); + resource->queueResize (resource->childWidget->extremesQueued ()); } ComplexButtonResource::ComplexButtonResource () diff --git a/dw/widget.cc b/dw/widget.cc index 12430f01..42566a17 100644 --- a/dw/widget.cc +++ b/dw/widget.cc @@ -130,32 +130,50 @@ void Widget::queueResize (int ref, bool extremesChanged) { Widget *widget2, *child; - //printf("The %stop-level %s %p with parentRef = %d has changed its size.\n", - // parent ? "non-" : "", getClassName(), this, parentRef); + //printf("The %stop-level %s %p with parentRef = %d has changed its size. " + // "Layout = %p.\n", + // parent ? "non-" : "", getClassName(), this, parentRef, layout); + + Flags resizeFlag, extremesFlag; + + if (layout) { + // If RESIZE_QUEUED is set, this widget is already in the list. + if (!resizeQueued ()) + layout->queueResizeList->put (this); + + resizeFlag = RESIZE_QUEUED; + extremesFlag = EXTREMES_QUEUED; + } else { + resizeFlag = NEEDS_RESIZE; + extremesFlag = EXTREMES_CHANGED; + } - setFlags (NEEDS_RESIZE); + setFlags (resizeFlag); setFlags (NEEDS_ALLOCATE); markSizeChange (ref); - + if (extremesChanged) { - setFlags (EXTREMES_CHANGED); + setFlags (extremesFlag); markExtremesChange (ref); } - - for (widget2 = parent, child = this; - widget2; - child = widget2, widget2 = widget2->parent) { - widget2->setFlags (NEEDS_RESIZE); - widget2->markSizeChange (child->parentRef); - widget2->setFlags (NEEDS_ALLOCATE); - - //printf (" Setting DW_NEEDS_RESIZE and NEEDS_ALLOCATE for the " + + for (widget2 = parent, child = this; widget2; + child = widget2, widget2 = widget2->parent) { + //printf (" Setting %s and NEEDS_ALLOCATE for the " // "%stop-level %s %p with parentRef = %d\n", + // resizeFlag == RESIZE_QUEUED ? "RESIZE_QUEUED" : "NEEDS_RESIZE", // widget2->parent ? "non-" : "", widget2->getClassName(), widget2, // widget2->parentRef); + if (layout && !widget2->resizeQueued ()) + layout->queueResizeList->put (widget2); + + widget2->setFlags (resizeFlag); + widget2->markSizeChange (child->parentRef); + widget2->setFlags (NEEDS_ALLOCATE); + if (extremesChanged) { - widget2->setFlags (EXTREMES_CHANGED); + widget2->setFlags (extremesFlag); widget2->markExtremesChange (child->parentRef); } } diff --git a/dw/widget.hh b/dw/widget.hh index 58306c92..a99e12ab 100644 --- a/dw/widget.hh +++ b/dw/widget.hh @@ -27,23 +27,37 @@ class Widget: public lout::identity::IdentifiableObject protected: enum Flags { /** + * \todo Comment this. + */ + RESIZE_QUEUED = 1 << 0, + + /** + * \todo Comment this. + */ + EXTREMES_QUEUED = 1 << 1, + + /** * \brief Set, when dw::core::Widget::requisition is not up to date * anymore. + * + * \todo Update, see RESIZE_QUEUED. */ - NEEDS_RESIZE = 1 << 0, + NEEDS_RESIZE = 1 << 2, /** * \brief Only used internally, set to enforce size allocation. * * (I've forgotten the case, for which this is necessary.) */ - NEEDS_ALLOCATE = 1 << 1, + NEEDS_ALLOCATE = 1 << 3, /** * \brief Set, when dw::core::Widget::extremes is not up to date * anymore. + * + * \todo Update, see RESIZE_QUEUED. */ - EXTREMES_CHANGED = 1 << 2, + EXTREMES_CHANGED = 1 << 4, /** * \brief Set by the widget itself (in the constructor), when set... @@ -51,7 +65,7 @@ protected: * * Will hopefully be removed, after redesigning the size model. */ - USES_HINTS = 1 << 3, + USES_HINTS = 1 << 5, /** * \brief Set by the widget itself (in the constructor), when it contains @@ -59,19 +73,19 @@ protected: * * Will hopefully be removed, after redesigning the size model. */ - HAS_CONTENTS = 1 << 4, + HAS_CONTENTS = 1 << 6, /** * \brief Set, when a widget was already once allocated, * * The dw::Image widget uses this flag, see dw::Image::setBuffer. */ - WAS_ALLOCATED = 1 << 5, + WAS_ALLOCATED = 1 << 7, /** * \brief Set for block-level widgets (as opposed to inline widgets) */ - BLOCK_LEVEL = 1 << 6, + BLOCK_LEVEL = 1 << 8, }; private: @@ -244,6 +258,8 @@ public: Widget (); ~Widget (); + inline bool resizeQueued () { return flags & RESIZE_QUEUED; } + inline bool extremesQueued () { return flags & EXTREMES_QUEUED; } inline bool needsResize () { return flags & NEEDS_RESIZE; } inline bool needsAllocate () { return flags & NEEDS_ALLOCATE; } inline bool extremesChanged () { return flags & EXTREMES_CHANGED; } |