diff options
Diffstat (limited to 'dw/layout.cc')
-rw-r--r-- | dw/layout.cc | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/dw/layout.cc b/dw/layout.cc index 6f2e8d8b..58b30fb3 100644 --- a/dw/layout.cc +++ b/dw/layout.cc @@ -245,6 +245,9 @@ Layout::Layout (Platform *platform) topLevel = NULL; widgetAtPoint = NULL; + queueQueueResizeList = new typed::Vector<QueueResizeItem> (4, true); + queueResizeList = new typed::Vector<Widget> (4, false); + DBG_OBJ_CREATE ("dw::core::Layout"); bgColor = NULL; @@ -277,7 +280,13 @@ Layout::Layout (Platform *platform) selectionState.setLayout(this); + queueResizeCounter = sizeAllocateCounter = sizeRequestCounter = + getExtremesCounter = 0; + layoutImgRenderer = NULL; + + resizeIdleCounter = queueResizeCounter = sizeAllocateCounter + = sizeRequestCounter = getExtremesCounter = 0; } Layout::~Layout () @@ -303,6 +312,9 @@ Layout::~Layout () topLevel = NULL; delete w; } + + delete queueQueueResizeList; + delete queueResizeList; delete platform; delete view; delete anchorsTable; @@ -320,12 +332,18 @@ void Layout::addWidget (Widget *widget) topLevel = widget; widget->layout = this; + queueResizeList->clear (); + widget->notifySetAsTopLevel(); findtextState.setWidget (widget); canvasHeightGreater = false; setSizeHints (); - queueResize (); + + // Do not directly call Layout::queueResize(), but + // Widget::queueResize(), so that all flags are set properly, + // queueResizeList is filled, etc. + topLevel->queueResize (-1, false); } void Layout::removeWidget () @@ -334,6 +352,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; @@ -776,11 +795,41 @@ void Layout::setBgImage (style::StyleImage *bgImage, void Layout::resizeIdle () { + DBG_OBJ_MSG ("resize", 0, "<b>resizeIdle</b>"); + DBG_OBJ_MSG_START (); + + enterResizeIdle (); + //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"); + + if (widget->resizeQueued ()) { + widget->setFlags (Widget::NEEDS_RESIZE); + widget->unsetFlags (Widget::RESIZE_QUEUED); + } + + if (widget->allocateQueued ()) { + widget->setFlags (Widget::NEEDS_ALLOCATE); + widget->unsetFlags (Widget::ALLOCATE_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; @@ -790,7 +839,15 @@ void Layout::resizeIdle () Allocation allocation; topLevel->sizeRequest (&requisition); - + DBG_OBJ_MSGF ("resize", 1, "toplevel size: %d * (%d + %d)", + requisition.width, requisition.ascent, requisition.descent); + + // This method is triggered by Widget::queueResize, which will, + // in any case, set NEEDS_ALLOCATE (indirectly, as + // ALLOCATE_QUEUED). This assertion helps to find + // inconsistences. + assert (topLevel->needsAllocate ()); + allocation.x = allocation.y = 0; allocation.width = requisition.width; allocation.ascent = requisition.ascent; @@ -825,10 +882,14 @@ void Layout::resizeIdle () } // views are redrawn via Widget::resizeDrawImpl () - } updateAnchor (); + + DBG_OBJ_MSGF ("resize", 1, "resizeIdleId = %d", resizeIdleId); + DBG_OBJ_MSG_END (); + + leaveResizeIdle (); } void Layout::setSizeHints () @@ -1164,8 +1225,13 @@ void Layout::viewportSizeChanged (View *view, int width, int height) /* if size changes, redraw this view. * TODO: this is a resize call (redraw/resize code needs a review). */ - if (viewportWidth != width || viewportHeight != height) - queueResize(); + if (viewportWidth != width || viewportHeight != height) { + if (topLevel) + // similar to addWidget() + topLevel->queueResize (-1, false); + else + queueResize (); + } viewportWidth = width; viewportHeight = height; |