aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Geerken <devnull@localhost>2014-10-25 12:13:51 +0200
committerSebastian Geerken <devnull@localhost>2014-10-25 12:13:51 +0200
commitdcf6e00e9b790e0868d8863f140567eef5e540c1 (patch)
tree01b4fcdb5b0ddcdd98e90264869974aaa74da7ff
parent607814bdead6d72fb6825a5502e625a216114a1c (diff)
Applied interruption (as used for drawing) also to Widget::getWidgetAtPoint. (Still bugs\!)
-rw-r--r--dw/layout.cc10
-rw-r--r--dw/oofawarewidget.cc307
-rw-r--r--dw/oofawarewidget.hh19
-rw-r--r--dw/ooffloatsmgr.cc62
-rw-r--r--dw/ooffloatsmgr.hh11
-rw-r--r--dw/oofpositionedmgr.cc32
-rw-r--r--dw/oofpositionedmgr.hh5
-rw-r--r--dw/outofflowmgr.hh6
-rw-r--r--dw/stackingcontextmgr.cc69
-rw-r--r--dw/stackingcontextmgr.hh18
-rw-r--r--dw/table.cc58
-rw-r--r--dw/table.hh5
-rw-r--r--dw/textblock.cc148
-rw-r--r--dw/textblock.hh11
-rw-r--r--dw/widget.cc155
-rw-r--r--dw/widget.hh10
16 files changed, 674 insertions, 252 deletions
diff --git a/dw/layout.cc b/dw/layout.cc
index 43c27dd8..df22bb75 100644
--- a/dw/layout.cc
+++ b/dw/layout.cc
@@ -1110,7 +1110,7 @@ Widget *Layout::getWidgetAtPoint (int x, int y)
Widget *widget;
if (topLevel && topLevel->wasAllocated ())
- widget = topLevel->getWidgetAtPoint (x, y);
+ widget = topLevel->getWidgetAtPointToplevel (x, y);
else
widget = NULL;
@@ -1126,12 +1126,16 @@ Widget *Layout::getWidgetAtPoint (int x, int y)
*/
void Layout::moveToWidget (Widget *newWidgetAtPoint, ButtonState state)
{
+ DBG_OBJ_ENTER ("events", 0, "moveToWidget", "%p, %d",
+ newWidgetAtPoint, state);
+
Widget *ancestor, *w;
Widget **track;
int trackLen, i, i_a;
EventCrossing crossingEvent;
- _MSG("moveToWidget: wap=%p nwap=%p\n",widgetAtPoint,newWidgetAtPoint);
+ DBG_OBJ_MSGF ("events", 1, "(old) widgetAtPoint = %p", widgetAtPoint);
+
if (newWidgetAtPoint != widgetAtPoint) {
// The mouse pointer has been moved into another widget.
if (newWidgetAtPoint && widgetAtPoint)
@@ -1201,6 +1205,8 @@ void Layout::moveToWidget (Widget *newWidgetAtPoint, ButtonState state)
widgetAtPoint = newWidgetAtPoint;
updateCursor ();
}
+
+ DBG_OBJ_LEAVE ();
}
/**
diff --git a/dw/oofawarewidget.cc b/dw/oofawarewidget.cc
index 3f9c37c8..c31aa83a 100644
--- a/dw/oofawarewidget.cc
+++ b/dw/oofawarewidget.cc
@@ -33,11 +33,17 @@ namespace dw {
namespace oof {
-OOFAwareWidget::OOFStackingIterator::OOFStackingIterator (bool atEnd)
-{
- // TODO Consider atEnd.
- majorLevel = OOFStackingIterator::BACKGROUND;
- minorLevel = index = 0;
+OOFAwareWidget::OOFStackingIterator::OOFStackingIterator
+ (OOFAwareWidget *widget, bool atEnd)
+{
+ if (atEnd) {
+ majorLevel = OOFStackingIterator::END - 1;
+ minorLevel = widget->getLastMinorLevel (majorLevel);
+ index = widget->getLastLevelIndex (majorLevel, minorLevel);
+ } else {
+ majorLevel = OOFStackingIterator::START + 1;
+ minorLevel = index = 0;
+ }
widgetsDrawnAfterInterruption = NULL;
}
@@ -400,7 +406,6 @@ void OOFAwareWidget::draw (View *view, Rectangle *area,
}
}
-
DBG_OBJ_MSGF ("draw", 1, "=> %p", *interruptedWidget);
DBG_OBJ_LEAVE ();
}
@@ -480,17 +485,240 @@ void OOFAwareWidget::drawOOF (View *view, Rectangle *area,
}
}
-Widget *OOFAwareWidget::getWidgetOOFAtPoint (int x, int y)
+Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y,
+ StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget)
{
- for (int i = 0; i < NUM_OOFM; i++) {
- Widget *oofWidget =
- outOfFlowMgr[i] ?
- outOfFlowMgr[i]->getWidgetAtPoint (x, y) : NULL;
- if (oofWidget)
- return oofWidget;
+ DBG_OBJ_ENTER ("events", 0, "getWidgetAtPoint", "%d, %d", x, y);
+ Widget *widgetAtPoint = NULL;
+
+ if (wasAllocated () && x >= allocation.x && y >= allocation.y &&
+ x <= allocation.x + allocation.width &&
+ y <= allocation.y + getHeight ()) {
+ while (widgetAtPoint == NULL && *interruptedWidget == NULL &&
+ ((OOFStackingIterator*)iteratorStack->getTop())->majorLevel
+ > OOFStackingIterator::START) {
+ widgetAtPoint =
+ getWidgetAtPointLevel (x, y, iteratorStack, interruptedWidget,
+ ((OOFStackingIterator*)iteratorStack
+ ->getTop())->majorLevel);
+
+ if (*interruptedWidget) {
+ assert (widgetAtPoint == NULL); // Not both set.
+
+ if ((*interruptedWidget)->getParent () == this) {
+ DBG_OBJ_MSGF ("events", 1,
+ "interrupted at %p, searching widget seperately",
+ *interruptedWidget);
+ DBG_IF_RTFL {
+ StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("events", 2, "iteratorStack: %s",
+ sb.getChars ());
+ }
+
+ // Similar to Widget::getWidgetAtPointToplevel. Nested
+ // interruptions are not allowed.
+ StackingIteratorStack iteratorStack2;
+ Widget *interruptedWidget2 = NULL;
+ widgetAtPoint = (*interruptedWidget)
+ ->getWidgetAtPointTotal (x, y, &iteratorStack2,
+ &interruptedWidget2);
+ assert (interruptedWidget2 == NULL);
+
+ ((OOFStackingIterator*)iteratorStack->getTop())
+ ->registerWidgetDrawnAfterInterruption (*interruptedWidget);
+
+ // Continue with the current state of "iterator".
+ *interruptedWidget = NULL;
+ DBG_OBJ_MSG ("events", 1, "done with interruption");
+ }
+ } else {
+ OOFStackingIterator* osi =
+ (OOFStackingIterator*)iteratorStack->getTop();
+ osi->majorLevel--;
+ if (osi->majorLevel > OOFStackingIterator::START) {
+ osi->minorLevel = getLastMinorLevel (osi->majorLevel);
+ osi->index =
+ getLastLevelIndex (osi->majorLevel, osi->minorLevel);
+ }
+ }
+ }
+ }
+
+ DBG_OBJ_MSGF ("events", 1, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
+ DBG_OBJ_LEAVE ();
+ return widgetAtPoint;
+}
+
+Widget *OOFAwareWidget::getWidgetAtPointLevel (int x, int y,
+ StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int majorLevel)
+{
+ DBG_OBJ_ENTER ("events", 0, "OOFAwareWidget/getWidgetAtPointLevel",
+ "%d, %d, %s", x, y,
+ OOFStackingIterator::majorLevelText (majorLevel));
+
+ Widget *widgetAtPoint = NULL;
+
+ switch (majorLevel) {
+ case OOFStackingIterator::BACKGROUND:
+ if (wasAllocated () && x >= allocation.x && y >= allocation.y &&
+ x <= allocation.x + allocation.width &&
+ y <= allocation.y + getHeight ())
+ widgetAtPoint = this;
+ break;
+
+ case OOFStackingIterator::SC_BOTTOM:
+ if (stackingContextMgr) {
+ OOFStackingIterator *osi =
+ (OOFStackingIterator*)iteratorStack->getTop ();
+ widgetAtPoint =
+ stackingContextMgr->getBottomWidgetAtPoint (x, y, iteratorStack,
+ interruptedWidget,
+ &osi->minorLevel,
+ &osi->index);
+ }
+ break;
+
+ case OOFStackingIterator::IN_FLOW:
+ // Should be implemented in the sub class.
+ assertNotReached ();
+ break;
+
+ case OOFStackingIterator::OOF_REF:
+ // Should be implemented in the sub class (when references are hold).
+ break;
+
+ case OOFStackingIterator::OOF_CONT:
+ widgetAtPoint =
+ getWidgetOOFAtPoint (x, y, iteratorStack, interruptedWidget);
+ break;
+
+ case OOFStackingIterator::SC_TOP:
+ if (stackingContextMgr) {
+ OOFStackingIterator *osi =
+ (OOFStackingIterator*)iteratorStack->getTop ();
+ widgetAtPoint =
+ stackingContextMgr->getTopWidgetAtPoint (x, y, iteratorStack,
+ interruptedWidget,
+ &osi->minorLevel,
+ &osi->index);
+ }
+ break;
+
+ default:
+ assertNotReached ();
+ }
+
+ DBG_OBJ_MSGF ("events", 1, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
+ DBG_OBJ_LEAVE ();
+ return widgetAtPoint;
+}
+
+Widget *OOFAwareWidget::getWidgetOOFAtPoint (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget)
+{
+ OOFStackingIterator *osi = (OOFStackingIterator*)iteratorStack->getTop ();
+ assert (osi->majorLevel == OOFStackingIterator::OOF_CONT);
+
+ Widget *widgetAtPoint = NULL;
+
+ while (*interruptedWidget == NULL && widgetAtPoint == NULL &&
+ osi->minorLevel >= 0) {
+ if (outOfFlowMgr[osi->minorLevel])
+ widgetAtPoint =
+ outOfFlowMgr[osi->minorLevel]->getWidgetAtPoint (x, y,
+ iteratorStack,
+ interruptedWidget,
+ &(osi->index));
+
+ if (*interruptedWidget == NULL) {
+ osi->minorLevel--;
+ if (osi->minorLevel > 0 && outOfFlowMgr[osi->minorLevel] != NULL)
+ osi->index = outOfFlowMgr[osi->minorLevel]->getNumWidgets () - 1;
+ }
}
- return NULL;
+ return widgetAtPoint;
+}
+
+int OOFAwareWidget::getLastMinorLevel (int majorLevel)
+{
+ switch (majorLevel) {
+ case OOFStackingIterator::BACKGROUND:
+ return 0;
+
+ case OOFStackingIterator::SC_BOTTOM:
+ if (stackingContextMgr)
+ // See StackingContextMgr:
+ // - startZIndexEff = max (minZIndex, INT_MIN) = minZIndex (<= 0)
+ // - endZIndexEff = min (maxZIndex, -1) = -1
+ // So, zIndexOffset runs from 0 to endZIndexEff - startZIndexEff =
+ // - 1 - minZIndex.
+ return max (- stackingContextMgr->getMinZIndex () - 1, 0);
+ else
+ return 0;
+
+ case OOFStackingIterator::IN_FLOW:
+ return 0;
+
+ case OOFStackingIterator::OOF_REF:
+ case OOFStackingIterator::OOF_CONT:
+ return NUM_OOFM - 1;
+
+ case OOFStackingIterator::SC_TOP:
+ // See StackingContextMgr:
+ // - startZIndexEff = max (minZIndex, 0) = 0
+ // - endZIndexEff = min (maxZIndex, INT_MAX) = maxZIndex
+ if (stackingContextMgr)
+ return stackingContextMgr->getMaxZIndex ();
+ else
+ return 0;
+
+ default:
+ assertNotReached ();
+ return 0;
+ }
+}
+
+int OOFAwareWidget::getLastLevelIndex (int majorLevel, int minorLevel)
+{
+ switch (majorLevel) {
+ case OOFStackingIterator::BACKGROUND:
+ return 0;
+
+ case OOFStackingIterator::SC_BOTTOM:
+ case OOFStackingIterator::SC_TOP:
+ if (stackingContextMgr)
+ return stackingContextMgr->getNumChildSCWidgets () - 1;
+ else
+ return 0;
+
+ case OOFStackingIterator::IN_FLOW:
+ // Should be implemented in the sub class.
+ assertNotReached ();
+
+ case OOFStackingIterator::OOF_REF:
+ // Should be implemented in the sub class (when references are hold).
+ return 0;
+
+ case OOFStackingIterator::OOF_CONT:
+ if(outOfFlowMgr[minorLevel])
+ return outOfFlowMgr[minorLevel]->getNumWidgets () - 1;
+ else
+ return 0;
+
+ default:
+ assertNotReached ();
+ return 0;
+ }
}
int OOFAwareWidget::getAvailWidthOfChild (Widget *child, bool forceValue)
@@ -523,58 +751,9 @@ void OOFAwareWidget::removeChild (Widget *child)
assert (isWidgetOOF (child));
}
-Widget *OOFAwareWidget::getWidgetAtPoint (int x, int y)
-{
- if (x >= allocation.x &&
- y >= allocation.y &&
- x <= allocation.x + allocation.width &&
- y <= allocation.y + getHeight ()) {
-
- if (stackingContextMgr) {
- Widget *scmWidget =
- stackingContextMgr->getTopWidgetAtPoint (x, y);
- if (scmWidget)
- return scmWidget;
- }
-
- Widget *oofWidget = getWidgetOOFAtPoint (x, y);
- if (oofWidget)
- return oofWidget;
-
- Widget *childAtPoint = NULL;
- core::Iterator *it =
- iterator ((Content::Type)
- (Content::WIDGET_IN_FLOW | Content::WIDGET_OOF_CONT),
- false);
-
- while (childAtPoint == NULL && it->next ()) {
- Widget *child = it->getContent()->widget;
- if (!StackingContextMgr::handledByStackingContextMgr (child) &&
- child->wasAllocated ())
- childAtPoint = child->getWidgetAtPoint (x, y);
- }
-
- it->unref ();
-
- if (childAtPoint)
- return childAtPoint;
-
- if (stackingContextMgr) {
- Widget *scmWidget =
- stackingContextMgr->getBottomWidgetAtPoint (x, y);
- if (scmWidget)
- return scmWidget;
- }
-
- return this;
- } else
- return NULL;
-}
-
-
Object *OOFAwareWidget::stackingIterator (bool atEnd)
{
- return new OOFStackingIterator (atEnd);
+ return new OOFStackingIterator (this, atEnd);
}
void OOFAwareWidget::borderChanged (int y, Widget *vloat)
diff --git a/dw/oofawarewidget.hh b/dw/oofawarewidget.hh
index f9d88c2b..95af54a0 100644
--- a/dw/oofawarewidget.hh
+++ b/dw/oofawarewidget.hh
@@ -177,7 +177,21 @@ protected:
void drawOOF (core::View *view, core::Rectangle *area,
core::StackingIteratorStack *iteratorStack,
Widget **interruptedWidget);
- Widget *getWidgetOOFAtPoint (int x, int y);
+
+ Widget *getWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget);
+ virtual Widget *getWidgetAtPointLevel (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int majorLevel);
+ Widget *getWidgetOOFAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget);
+
+ virtual int getLastMinorLevel (int majorLevel);
+ virtual int getLastLevelIndex (int majorLevel, int minorLevel);
static bool isOOFContainer (Widget *widget, int oofmIndex);
@@ -189,7 +203,6 @@ protected:
void removeChild (Widget *child);
- core::Widget *getWidgetAtPoint (int x, int y);
public:
static int CLASS_ID;
@@ -207,7 +220,7 @@ public:
static const char *majorLevelText (int majorLevel);
- OOFStackingIterator (bool atEnd);
+ OOFStackingIterator (OOFAwareWidget *widget, bool atEnd);
~OOFStackingIterator ();
void intoStringBuffer(lout::misc::StringBuffer *sb);
diff --git a/dw/ooffloatsmgr.cc b/dw/ooffloatsmgr.cc
index bc426846..6c4f3db8 100644
--- a/dw/ooffloatsmgr.cc
+++ b/dw/ooffloatsmgr.cc
@@ -1284,10 +1284,8 @@ void OOFFloatsMgr::draw (View *view, Rectangle *area,
DBG_OBJ_ENTER ("draw", 0, "draw", "(%d, %d, %d * %d), [%d]",
area->x, area->y, area->width, area->height, *index);
- if (*index < leftFloatsCB->size ())
- drawFloats (leftFloatsCB, view, area, iteratorStack, interruptedWidget,
- index, 0);
-
+ drawFloats (leftFloatsCB, view, area, iteratorStack, interruptedWidget,
+ index, 0);
if (*interruptedWidget == NULL)
drawFloats (rightFloatsCB, view, area, iteratorStack, interruptedWidget,
index, leftFloatsCB->size ());
@@ -1491,29 +1489,51 @@ void OOFFloatsMgr::markExtremesChange (int ref)
// Nothing to do here.
}
-Widget *OOFFloatsMgr::getWidgetAtPoint (int x, int y)
+Widget *OOFFloatsMgr::getWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ core::Widget **interruptedWidget,
+ int *index)
{
- Widget *childAtPoint = getFloatWidgetAtPoint (leftFloatsCB, x, y);
- if (childAtPoint == NULL)
- childAtPoint = getFloatWidgetAtPoint (rightFloatsCB, x, y);
- return childAtPoint;
+ Widget *widgetAtPoint = NULL;
+
+ widgetAtPoint =
+ getFloatWidgetAtPoint (rightFloatsCB, x, y, iteratorStack,
+ interruptedWidget, index,
+ leftFloatsCB->size ());
+ if (widgetAtPoint == NULL && *interruptedWidget == NULL)
+ widgetAtPoint =
+ getFloatWidgetAtPoint (leftFloatsCB, x, y, iteratorStack,
+ interruptedWidget, index, 0);
+ return widgetAtPoint;
}
Widget *OOFFloatsMgr::getFloatWidgetAtPoint (SortedFloatsVector *list, int x,
- int y)
-{
- for (int i = 0; i < list->size(); i++) {
- // Could use binary search to be faster.
- Widget *childWidget = list->get(i)->getWidget ();
- if (!StackingContextMgr::handledByStackingContextMgr (childWidget) &&
- childWidget->wasAllocated ()) {
- Widget *childAtPoint = childWidget->getWidgetAtPoint (x, y);
- if (childAtPoint)
- return childAtPoint;
- }
+ int y,
+ StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int *index, int startIndex)
+{
+ // Could use binary search to be faster (similar to drawing).
+ Widget *widgetAtPoint = NULL;
+ OOFAwareWidget::OOFStackingIterator *osi =
+ (OOFAwareWidget::OOFStackingIterator*)iteratorStack->getTop ();
+
+ while (widgetAtPoint == NULL && *interruptedWidget == NULL &&
+ *index - startIndex >= 0) {
+ Widget *childWidget = list->get(*index)->getWidget ();
+ if (!osi->hasWidgetBeenDrawnAfterInterruption (childWidget) &&
+ !StackingContextMgr::handledByStackingContextMgr (childWidget))
+ widgetAtPoint =
+ childWidget->getWidgetAtPointTotal (x, y, iteratorStack,
+ interruptedWidget);
+
+ if (*interruptedWidget == NULL)
+ (*index)--;
}
- return NULL;
+ return widgetAtPoint;
}
void OOFFloatsMgr::tellPosition (Widget *widget, int x, int y)
diff --git a/dw/ooffloatsmgr.hh b/dw/ooffloatsmgr.hh
index 70c576b4..f847d614 100644
--- a/dw/ooffloatsmgr.hh
+++ b/dw/ooffloatsmgr.hh
@@ -289,7 +289,11 @@ private:
core::StackingIteratorStack *iteratorStack,
core::Widget **interruptedWidget, int *index,
int startIndex);
- core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y);
+ core::Widget *getFloatWidgetAtPoint (SortedFloatsVector *list, int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ core::Widget **interruptedWidget,
+ int *index, int startIndex);
bool collidesV (Float *vloat, Float *other, SFVType type, int *yReal);
bool collidesH (Float *vloat, Float *other, SFVType type);
@@ -349,7 +353,10 @@ public:
void markSizeChange (int ref);
void markExtremesChange (int ref);
- core::Widget *getWidgetAtPoint (int x, int y);
+ core::Widget *getWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ core::Widget **interruptedWidget,
+ int *index);
void addWidgetInFlow (OOFAwareWidget *textblock, OOFAwareWidget *parentBlock,
int externalIndex);
diff --git a/dw/oofpositionedmgr.cc b/dw/oofpositionedmgr.cc
index 24a6622a..bcc7e12d 100644
--- a/dw/oofpositionedmgr.cc
+++ b/dw/oofpositionedmgr.cc
@@ -237,22 +237,34 @@ void OOFPositionedMgr::markExtremesChange (int ref)
{
}
-Widget *OOFPositionedMgr::getWidgetAtPoint (int x, int y)
+Widget *OOFPositionedMgr::getWidgetAtPoint (int x, int y,
+ StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int *index)
{
DBG_OBJ_ENTER ("events", 0, "getWidgetAtPoint", "%d, %d", x, y);
- Widget *childAtPoint = NULL;
- for (int i = 0; i < children->size() && childAtPoint == NULL; i++) {
- Widget *childWidget = children->get(i)->widget;
- if (!StackingContextMgr::handledByStackingContextMgr (childWidget) &&
- childWidget->wasAllocated ()) {
- childAtPoint = childWidget->getWidgetAtPoint (x, y);
- }
+ Widget *widgetAtPoint = NULL;
+ OOFAwareWidget::OOFStackingIterator *osi =
+ (OOFAwareWidget::OOFStackingIterator*)iteratorStack->getTop ();
+
+ while (widgetAtPoint == NULL && *interruptedWidget == NULL && *index >= 0) {
+ Widget *childWidget = children->get(*index)->widget;
+ if (!osi->hasWidgetBeenDrawnAfterInterruption (childWidget) &&
+ !StackingContextMgr::handledByStackingContextMgr (childWidget))
+ widgetAtPoint =
+ childWidget->getWidgetAtPointTotal (x, y, iteratorStack,
+ interruptedWidget);
+
+ if (*interruptedWidget == NULL)
+ (*index)--;
}
- DBG_OBJ_MSGF ("events", 0, "=> %p", childAtPoint);
+ DBG_OBJ_MSGF ("events", 0, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
DBG_OBJ_LEAVE ();
- return childAtPoint;
+ return widgetAtPoint;
}
void OOFPositionedMgr::tellPosition (Widget *widget, int x, int y)
diff --git a/dw/oofpositionedmgr.hh b/dw/oofpositionedmgr.hh
index bf701941..a1b1d68c 100644
--- a/dw/oofpositionedmgr.hh
+++ b/dw/oofpositionedmgr.hh
@@ -71,7 +71,10 @@ public:
void markSizeChange (int ref);
void markExtremesChange (int ref);
- core::Widget *getWidgetAtPoint (int x, int y);
+ core::Widget *getWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ core::Widget **interruptedWidget,
+ int *index);
void addWidgetInFlow (OOFAwareWidget *widget, OOFAwareWidget *parent,
int externalIndex);
diff --git a/dw/outofflowmgr.hh b/dw/outofflowmgr.hh
index b7db0fe3..151c29f5 100644
--- a/dw/outofflowmgr.hh
+++ b/dw/outofflowmgr.hh
@@ -31,7 +31,11 @@ public:
virtual void markSizeChange (int ref) = 0;
virtual void markExtremesChange (int ref) = 0;
- virtual core::Widget *getWidgetAtPoint (int x, int y) = 0;
+ virtual core::Widget *getWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ core::Widget **interruptedWidget,
+ int *index)= 0;
virtual void addWidgetInFlow (OOFAwareWidget *widget,
OOFAwareWidget *parent, int externalIndex) = 0;
diff --git a/dw/stackingcontextmgr.cc b/dw/stackingcontextmgr.cc
index 08fb0e82..9f8747f9 100644
--- a/dw/stackingcontextmgr.cc
+++ b/dw/stackingcontextmgr.cc
@@ -100,8 +100,11 @@ void StackingContextMgr::draw (View *view, Rectangle *area,
int startZIndexEff = max (minZIndex, startZIndex),
endZIndexEff = min (maxZIndex, endZIndex);
+ // Make sure *zIndexOffset starts at 0, for zIndex = startZIndexEff,
+ // so *zIndexOffset = zIndex - startZIndexEff, and
+ // zIndex = *zIndexOffset + startZIndexEff.
while (*interruptedWidget == NULL &&
- *zIndexOffset + startZIndexEff <= endZIndexEff) {
+ *zIndexOffset <= endZIndexEff - startZIndexEff) {
DBG_OBJ_MSGF ("draw", 1, "drawing zIndex = %d + %d",
*zIndexOffset, startZIndexEff);
DBG_OBJ_MSG_START ();
@@ -132,50 +135,78 @@ void StackingContextMgr::draw (View *view, Rectangle *area,
DBG_OBJ_LEAVE ();
}
-Widget *StackingContextMgr::getTopWidgetAtPoint (int x, int y)
+Widget *StackingContextMgr::getTopWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int *zIndexOffset, int *index)
{
DBG_OBJ_ENTER ("events", 0, "getWidgetAtPointTop", "%d, %d", x, y);
- Widget *widget = getWidgetAtPoint (x, y, 0, INT_MAX);
- DBG_OBJ_MSGF ("events", 0, "=> %p", widget);
+ Widget *widget = getWidgetAtPoint (x, y, iteratorStack, interruptedWidget,
+ zIndexOffset, 0, INT_MAX, index);
+ DBG_OBJ_MSGF ("events", 0, "=> %p (i: %p)", widget, *interruptedWidget);
DBG_OBJ_LEAVE ();
return widget;
}
-Widget *StackingContextMgr::getBottomWidgetAtPoint (int x, int y)
+Widget *StackingContextMgr::getBottomWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int *zIndexOffset,
+ int *index)
{
DBG_OBJ_ENTER ("events", 0, "getWidgetAtPointBottom", "%d, %d", x, y);
- Widget *widget = getWidgetAtPoint (x, y, INT_MIN, -1);
- DBG_OBJ_MSGF ("events", 0, "=> %p", widget);
+ Widget *widget = getWidgetAtPoint (x, y, iteratorStack, interruptedWidget,
+ zIndexOffset, INT_MIN, -1, index);
+ DBG_OBJ_MSGF ("events", 0, "=> %p (i: %p)", widget, *interruptedWidget);
DBG_OBJ_LEAVE ();
return widget;
}
-Widget *StackingContextMgr::getWidgetAtPoint (int x, int y, int startZIndex,
- int endZIndex)
+Widget *StackingContextMgr::getWidgetAtPoint (int x, int y,
+ StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int *zIndexOffset,
+ int startZIndex, int endZIndex,
+ int *index)
{
DBG_OBJ_ENTER ("events", 0, "getWidgetAtPointBottom", "%d, %d", x, y);
Widget *widgetAtPoint = NULL;
- for (int zIndex = min (maxZIndex, endZIndex);
- zIndex >= max (minZIndex, startZIndex) && widgetAtPoint == NULL;
- zIndex--) {
- DBG_OBJ_MSGF ("events", 1, "searching zIndex = %d", zIndex);
+ // For *zIndexOffset, see draw(). Actually, we start at the end and iterate
+ // to the start (naming is somewhat confusing).
+ int startZIndexEff = max (minZIndex, startZIndex);
+ while (*interruptedWidget == NULL && widgetAtPoint == NULL &&
+ *zIndexOffset >= 0) {
+ DBG_OBJ_MSGF ("events", 1, "searching zIndex = %d + %d",
+ *zIndexOffset, startZIndexEff);
DBG_OBJ_MSG_START ();
- for (int i = 0; i < childSCWidgets->size () && widgetAtPoint == NULL;
- i++) {
- Widget *child = childSCWidgets->get (i);
+ while (*interruptedWidget == NULL && widgetAtPoint == NULL &&
+ *index >= 0) {
+ Widget *child = childSCWidgets->get (*index);
DBG_OBJ_MSGF ("events", 2, "widget %p has zIndex = %d",
child, child->getStyle()->zIndex);
- if (child->getStyle()->zIndex == zIndex && child->wasAllocated ())
- widgetAtPoint = childSCWidgets->get(i)->getWidgetAtPoint (x, y);
+ if (child->getStyle()->zIndex == *zIndexOffset + startZIndexEff)
+ widgetAtPoint =
+ child->getWidgetAtPointTotal (x, y, iteratorStack,
+ interruptedWidget);
+
+ if (*interruptedWidget == NULL)
+ (*index)--;
}
+ if (*interruptedWidget == NULL)
+ (*zIndexOffset)--;
+
DBG_OBJ_MSG_END ();
}
- DBG_OBJ_MSGF ("events", 0, "=> %p", widgetAtPoint);
+ DBG_OBJ_MSGF ("events", 0, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
DBG_OBJ_LEAVE ();
return widgetAtPoint;
}
diff --git a/dw/stackingcontextmgr.hh b/dw/stackingcontextmgr.hh
index 28cdd2f9..3866c68a 100644
--- a/dw/stackingcontextmgr.hh
+++ b/dw/stackingcontextmgr.hh
@@ -26,7 +26,9 @@ private:
void draw (View *view, Rectangle *area,
StackingIteratorStack *iteratorStack, Widget **interruptedWidget,
int *zIndexOffset, int startZIndex, int endZIndex, int *index);
- Widget *getWidgetAtPoint (int x, int y, int startZIndex, int endZIndex);
+ Widget *getWidgetAtPoint (int x, int y, StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget, int *zIndexOffset,
+ int startZIndex, int endZIndex, int *index);
public:
StackingContextMgr (Widget *widget);
@@ -47,6 +49,10 @@ public:
void addChildSCWidget (Widget *widget);
+ inline int getMinZIndex () { return minZIndex; }
+ inline int getMaxZIndex () { return maxZIndex; }
+ inline int getNumChildSCWidgets () { return childSCWidgets->size (); }
+
void drawBottom (View *view, Rectangle *area,
StackingIteratorStack *iteratorStack,
Widget **interruptedWidget, int *zIndexOffset, int *index);
@@ -54,8 +60,14 @@ public:
StackingIteratorStack *iteratorStack,
Widget **interruptedWidget, int *zIndexOffset, int *index);
- Widget *getTopWidgetAtPoint (int x, int y);
- Widget *getBottomWidgetAtPoint (int x, int y);
+ Widget *getTopWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget,
+ int *zIndexOffset, int *index);
+ Widget *getBottomWidgetAtPoint (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget,
+ int *zIndexOffset, int *index);
};
} // namespace core
diff --git a/dw/table.cc b/dw/table.cc
index c65f2d75..c14ebf97 100644
--- a/dw/table.cc
+++ b/dw/table.cc
@@ -415,6 +415,64 @@ void Table::drawLevel (core::View *view, core::Rectangle *area,
DBG_OBJ_LEAVE ();
}
+core::Widget *Table::getWidgetAtPointLevel (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int majorLevel)
+{
+ DBG_OBJ_ENTER ("events", 0, "Table/getWidgetAtPointLevel", "%d, %d, %s",
+ x, y, OOFStackingIterator::majorLevelText (majorLevel));
+
+ Widget *widgetAtPoint = NULL;
+
+ switch (majorLevel) {
+ case OOFStackingIterator::IN_FLOW:
+ {
+ OOFStackingIterator *osi =
+ (OOFStackingIterator*)iteratorStack->getTop ();
+
+ while (widgetAtPoint == NULL && *interruptedWidget == NULL &&
+ osi->index >= 0) {
+ if (childDefined (osi->index)) {
+ Widget *child = children->get(osi->index)->cell.widget;
+ if (!core::StackingContextMgr::handledByStackingContextMgr
+ (child))
+ widgetAtPoint =
+ child->getWidgetAtPointTotal (x, y, iteratorStack,
+ interruptedWidget);
+ }
+
+ if (*interruptedWidget == NULL)
+ osi->index--;
+ }
+ }
+ break;
+
+ default:
+ widgetAtPoint =
+ OOFAwareWidget::getWidgetAtPointLevel (x, y, iteratorStack,
+ interruptedWidget, majorLevel);
+ break;
+ }
+
+ DBG_OBJ_MSGF ("events", 1, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
+ DBG_OBJ_LEAVE ();
+ return widgetAtPoint;
+}
+
+int Table::getLastLevelIndex (int majorLevel, int minorLevel)
+{
+ switch (majorLevel) {
+ case OOFStackingIterator::IN_FLOW:
+ return children->size () - 1;
+
+ default:
+ return OOFAwareWidget::getLastLevelIndex (majorLevel, minorLevel);
+ }
+}
+
void Table::removeChild (Widget *child)
{
/** \bug Not implemented. */
diff --git a/dw/table.hh b/dw/table.hh
index db546f2a..44abc42f 100644
--- a/dw/table.hh
+++ b/dw/table.hh
@@ -475,6 +475,11 @@ protected:
core::StackingIteratorStack *iteratorStack,
Widget **interruptedWidget, int majorLevel);
+ Widget *getWidgetAtPointLevel (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget, int majorLevel);
+ int getLastLevelIndex (int majorLevel, int minorLevel);
+
//bool buttonPressImpl (core::EventButton *event);
//bool buttonReleaseImpl (core::EventButton *event);
//bool motionNotifyImpl (core::EventMotion *event);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index 9812572f..18303951 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -1718,7 +1718,7 @@ void Textblock::drawLevel (core::View *view, core::Rectangle *area,
break;
case OOFStackingIterator::OOF_REF:
- drawOOFReferences (view, area, iteratorStack, interruptedWidget);
+ handleOOFReferences (iteratorStack, interruptedWidget, false);
break;
default:
@@ -1731,20 +1731,34 @@ void Textblock::drawLevel (core::View *view, core::Rectangle *area,
DBG_OBJ_LEAVE ();
}
-void Textblock::drawOOFReferences (core::View *view, core::Rectangle *area,
- core::StackingIteratorStack *iteratorStack,
- Widget **interruptedWidget)
+/**
+ * \brief Used both for drawing and getting the widget at a point,
+ * since this method only interrupts, but does not do actual
+ * drawing or searching, respectively.
+ */
+void Textblock::handleOOFReferences (core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget, bool backwards)
{
- 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?
+ DBG_OBJ_ENTER ("common", 0, "Textblock/handleOOFReferences", "..., %s",
+ backwards ? "true [backwards]" : "false [forwards]");
+
OOFStackingIterator *osi = (OOFStackingIterator*)iteratorStack->getTop ();
assert (osi->majorLevel == OOFStackingIterator::OOF_REF);
- while (*interruptedWidget == NULL && osi->minorLevel < NUM_OOFM) {
- while (*interruptedWidget == NULL && osi->index < words->size ()) {
+ while (*interruptedWidget == NULL &&
+ (backwards ? (osi->minorLevel >= 0) : (osi->minorLevel < NUM_OOFM))) {
+ while (*interruptedWidget == NULL &&
+ (backwards ? (osi->index >= 0) : (osi->index < words->size ()))) {
+
+ //DBG_IF_RTFL {
+ // misc::StringBuffer sb;
+ // osi->intoStringBuffer (&sb);
+ // DBG_OBJ_MSGF ("common", 2, "osi = %s",
+ // sb.getChars ());
+ //}
+
Word *word = words->getRef (osi->index);
if (word->content.type == core::Content::WIDGET_OOF_REF &&
getOOFMIndex (word->content.widget) == osi->minorLevel &&
@@ -1753,16 +1767,24 @@ void Textblock::drawOOFReferences (core::View *view, core::Rectangle *area,
// The index is increased in any case: the iterator must
// point to the next element.
- osi->index++;
+ if (backwards)
+ osi->index--;
+ else
+ osi->index++;
}
if (*interruptedWidget == NULL) {
- osi->minorLevel++;
- osi->index = 0;
+ if (backwards) {
+ osi->minorLevel--;
+ osi->index = words->size () - 1;
+ } else {
+ osi->minorLevel++;
+ osi->index = 0;
+ }
}
}
- DBG_OBJ_MSGF ("draw", 1, "=> %p", *interruptedWidget);
+ DBG_OBJ_MSGF ("common", 1, "=> %p", *interruptedWidget);
DBG_OBJ_LEAVE ();
}
@@ -2713,66 +2735,74 @@ void Textblock::breakAdded ()
words->getRef(words->size () - 2)->effSpace = 0;
}
-/**
- * \brief Search recursively through widget.
- *
- * This is an optimized version of the general
- * dw::core::Widget::getWidgetAtPoint method.
- */
-core::Widget *Textblock::getWidgetAtPoint (int x, int y)
+core::Widget *Textblock::getWidgetAtPointLevel (int x, int y,
+ core::StackingIteratorStack
+ *iteratorStack,
+ Widget **interruptedWidget,
+ int majorLevel)
{
- DBG_OBJ_ENTER ("events", 0, "getWidgetAtPoint", "%d, %d", x, y);
- Widget *childAtPoint = NULL;
+ DBG_OBJ_ENTER ("events", 0, "Textblock/getWidgetAtPointLevel", "%d, %d, %s",
+ x, y, OOFStackingIterator::majorLevelText (majorLevel));
- if (x < allocation.x ||
- y < allocation.y ||
- x > allocation.x + allocation.width ||
- y > allocation.y + getHeight ()) {
- DBG_OBJ_MSG ("events", 1, "outside allocation");
- } else {
- // First, ...
- if (childAtPoint == NULL && stackingContextMgr)
- childAtPoint = stackingContextMgr->getTopWidgetAtPoint (x, y);
-
- // Then, search for widgets out of flow, notably floats, since
- // there are cases where they overlap child textblocks.
- if (childAtPoint == NULL)
- childAtPoint = getWidgetOOFAtPoint (x, y);
+ Widget *widgetAtPoint = NULL;
+
+ switch (majorLevel) {
+ case OOFStackingIterator::IN_FLOW:
+ {
+ OOFStackingIterator *osi =
+ (OOFStackingIterator*)iteratorStack->getTop ();
- if (childAtPoint == NULL) {
int lineIndex = findLineIndexWhenAllocated (y - allocation.y);
- if (lineIndex < 0 || lineIndex >= lines->size ())
- childAtPoint = this;
- else {
+ if (lineIndex >= 0 || lineIndex < lines->size ()) {
Line *line = lines->getRef (lineIndex);
-
- for (int wordIndex = line->firstWord;
- wordIndex <= line->lastWord && childAtPoint == NULL;
- wordIndex++) {
- Word *word = words->getRef (wordIndex);
- if (word->content.type == core::Content::WIDGET_IN_FLOW) {
- core::Widget * child = word->content.widget;
- if (!core::StackingContextMgr::handledByStackingContextMgr
- (child) &&
- child->wasAllocated ()) {
- childAtPoint = child->getWidgetAtPoint (x, y);
- }
- }
+ if (osi->index > line->lastWord)
+ osi->index = line->lastWord;
+
+ while (widgetAtPoint == NULL && *interruptedWidget == NULL &&
+ osi->index >= 0) {
+ Word *word = words->getRef (osi->index);
+ if (word->content.type == core::Content::WIDGET_IN_FLOW &&
+ !core::StackingContextMgr::handledByStackingContextMgr
+ (word->content.widget))
+ widgetAtPoint = word->content.widget
+ ->getWidgetAtPointTotal (x, y, iteratorStack,
+ interruptedWidget);
+ if (*interruptedWidget == NULL)
+ osi->index--;
}
}
}
+ break;
- if (childAtPoint == NULL && stackingContextMgr)
- childAtPoint = stackingContextMgr->getBottomWidgetAtPoint (x, y);
+ case OOFStackingIterator::OOF_REF:
+ handleOOFReferences (iteratorStack, interruptedWidget, true);
+ // No searching, only interruption.
+ break;
- if (childAtPoint == NULL)
- childAtPoint = this;
+ default:
+ widgetAtPoint =
+ OOFAwareWidget::getWidgetAtPointLevel (x, y, iteratorStack,
+ interruptedWidget, majorLevel);
+ break;
}
- DBG_OBJ_MSGF ("events", 0, "=> %p", childAtPoint);
+ DBG_OBJ_MSGF ("events", 1, "=> %p (i: %p)",
+ widgetAtPoint, *interruptedWidget);
DBG_OBJ_LEAVE ();
- return childAtPoint;
+ return widgetAtPoint;
+}
+
+int Textblock::getLastLevelIndex (int majorLevel, int minorLevel)
+{
+ switch (majorLevel) {
+ case OOFStackingIterator::IN_FLOW:
+ case OOFStackingIterator::OOF_REF:
+ return words->size () - 1;
+
+ default:
+ return OOFAwareWidget::getLastLevelIndex (majorLevel, minorLevel);
+ }
}
diff --git a/dw/textblock.hh b/dw/textblock.hh
index c96b2bc6..aaab0e1a 100644
--- a/dw/textblock.hh
+++ b/dw/textblock.hh
@@ -645,9 +645,8 @@ protected:
void drawLine (Line *line, core::View *view, core::Rectangle *area,
core::StackingIteratorStack *iteratorStack,
Widget **interruptedWidget);
- void drawOOFReferences (core::View *view, core::Rectangle *area,
- core::StackingIteratorStack *iteratorStack,
- Widget **interruptedWidget);
+ void handleOOFReferences (core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget, bool backwards);
int findLineIndex (int y);
int findLineIndexWhenNotAllocated (int y);
@@ -807,6 +806,11 @@ protected:
core::StackingIteratorStack *iteratorStack,
Widget **interruptedWidget, int majorLevel);
+ Widget *getWidgetAtPointLevel (int x, int y,
+ core::StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget, int majorLevel);
+ int getLastLevelIndex (int majorLevel, int minorLevel);
+
void sizeRequestImpl (core::Requisition *requisition);
void getExtremesImpl (core::Extremes *extremes);
void sizeAllocateImpl (core::Allocation *allocation);
@@ -890,7 +894,6 @@ public:
void addParbreak (int space, core::style::Style *style);
void addLinebreak (core::style::Style *style);
- core::Widget *getWidgetAtPoint (int x, int y);
void handOverBreak (core::style::Style *style);
void changeLinkColor (int link, int newColor);
void changeWordStyle (int from, int to, core::style::Style *style,
diff --git a/dw/widget.cc b/dw/widget.cc
index 3c58d0a1..4c1fb896 100644
--- a/dw/widget.cc
+++ b/dw/widget.cc
@@ -205,7 +205,7 @@ void Widget::drawTotal (View *view, Rectangle *area,
DBG_IF_RTFL {
misc::StringBuffer sb;
iteratorStack->intoStringBuffer (&sb);
- DBG_OBJ_MSGF ("draw", 2, "iteratorStack before drawing: %s",
+ DBG_OBJ_MSGF ("draw", 2, "iteratorStack before: %s",
sb.getChars ());
}
@@ -215,15 +215,15 @@ void Widget::drawTotal (View *view, Rectangle *area,
DBG_IF_RTFL {
misc::StringBuffer sb;
iteratorStack->intoStringBuffer (&sb);
- DBG_OBJ_MSGF ("draw", 2, "iteratorStack after drawing: %s",
+ DBG_OBJ_MSGF ("draw", 2, "iteratorStack after: %s",
sb.getChars ());
}
// A value for *interruptedWidget 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. (TODO: Not quite correct when
- // forward() was called instead of push().)
+ // widget with a complex drawing process, for which
+ // stackingIterator() must return something non-NULL, so that the
+ // interrupted drawing process can be continued. (TODO: Not quite
+ // correct when forward() was called instead of push().)
// assert (*interruptedWidget == NULL || si != NULL);
@@ -254,6 +254,94 @@ void Widget::drawToplevel (View *view, Rectangle *area)
assert (interruptedWidget == NULL);
}
+Widget *Widget::getWidgetAtPoint (int x, int y,
+ StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget)
+{
+ // Suitable for simple widgets, without children.
+
+ if (wasAllocated () && x >= allocation.x && y >= allocation.y &&
+ x <= allocation.x + allocation.width && y <= allocation.y + getHeight ())
+ return this;
+ else
+ return NULL;
+}
+
+Widget *Widget::getWidgetAtPointTotal (int x, int y,
+ StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget)
+{
+ DBG_OBJ_ENTER ("events", 0, "getWidgetAtPointTotal", "%d, %d", x, y);
+
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("events", 2, "initial iteratorStack: %s", sb.getChars ());
+ }
+
+ Object *si = NULL;
+
+ if (iteratorStack->atRealTop ()) {
+ si = stackingIterator (true);
+ if (si) {
+ iteratorStack->push (si);
+ }
+ } else
+ iteratorStack->forward ();
+
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("events", 2, "iteratorStack before: %s",
+ sb.getChars ());
+ }
+
+ Widget *widget = getWidgetAtPoint (x, y, iteratorStack, interruptedWidget);
+ DBG_OBJ_MSGF ("events", 1, "=> %p (i: %p)", widget, *interruptedWidget);
+
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("events", 2, "iteratorStack after: %s",
+ sb.getChars ());
+ }
+
+ // See comment in drawTotal().
+
+ // assert (*interruptedWidget == NULL || si != NULL);
+
+ if (*interruptedWidget == NULL) {
+ if (si)
+ iteratorStack->pop ();
+ } else
+ iteratorStack->backward ();
+
+ DBG_IF_RTFL {
+ misc::StringBuffer sb;
+ iteratorStack->intoStringBuffer (&sb);
+ DBG_OBJ_MSGF ("events", 2, "final iteratorStack: %s", sb.getChars ());
+ }
+
+ DBG_OBJ_LEAVE ();
+ return widget;
+}
+
+Widget *Widget::getWidgetAtPointToplevel (int x, int y)
+{
+ assert (parent == NULL);
+
+ StackingIteratorStack iteratorStack;
+ Widget *interruptedWidget = NULL;
+ Widget *widget =
+ getWidgetAtPointTotal (x, y, &iteratorStack, &interruptedWidget);
+
+ // Everything should be finished at this point.
+ assert (interruptedWidget == NULL);
+
+ return widget;
+}
+
+
void Widget::setParent (Widget *parent)
{
this->parent = parent;
@@ -1484,61 +1572,6 @@ Widget *Widget::getNearestCommonAncestor (Widget *otherWidget)
return widget1;
}
-
-/**
- * \brief Search recursively through widget.
- *
- * Used by dw::core::Layout:getWidgetAtPoint.
- */
-Widget *Widget::getWidgetAtPoint (int x, int y)
-{
- if (x >= allocation.x &&
- y >= allocation.y &&
- x <= allocation.x + allocation.width &&
- y <= allocation.y + getHeight ()) {
-
- if (stackingContextMgr) {
- Widget *scmWidget =
- stackingContextMgr->getTopWidgetAtPoint (x, y);
- if (scmWidget)
- return scmWidget;
- }
-
- // Iterate over the children of this widget. Test recursively, whether
- // the point is within the child (or one of its children...). If there
- // is such a child, it is returned. Otherwise, this widget is returned.
-
- Widget *childAtPoint = NULL;
- Iterator *it =
- iterator ((Content::Type)
- (Content::WIDGET_IN_FLOW | Content::WIDGET_OOF_CONT),
- false);
-
- while (childAtPoint == NULL && it->next ()) {
- Widget *child = it->getContent()->widget;
- if (!StackingContextMgr::handledByStackingContextMgr (child) &&
- child->wasAllocated ())
- childAtPoint = child->getWidgetAtPoint (x, y);
- }
-
- it->unref ();
-
- if (childAtPoint)
- return childAtPoint;
-
- if (stackingContextMgr) {
- Widget *scmWidget =
- stackingContextMgr->getBottomWidgetAtPoint (x, y);
- if (scmWidget)
- return scmWidget;
- }
-
- return this;
- } else
- return NULL;
-}
-
-
void Widget::scrollTo (HPosition hpos, VPosition vpos,
int x, int y, int width, int height)
{
diff --git a/dw/widget.hh b/dw/widget.hh
index c284e172..1a1bf41e 100644
--- a/dw/widget.hh
+++ b/dw/widget.hh
@@ -477,6 +477,14 @@ public:
Widget **interruptedWidget);
void drawToplevel (View *view, Rectangle *area);
+ virtual Widget *getWidgetAtPoint (int x, int y,
+ StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget);
+ Widget *getWidgetAtPointTotal (int x, int y,
+ StackingIteratorStack *iteratorStack,
+ Widget **interruptedWidget);
+ Widget *getWidgetAtPointToplevel (int x, int y);
+
bool buttonPress (EventButton *event);
bool buttonRelease (EventButton *event);
bool motionNotify (EventMotion *event);
@@ -506,8 +514,6 @@ public:
inline Layout *getLayout () { return layout; }
- virtual Widget *getWidgetAtPoint (int x, int y);
-
void scrollTo (HPosition hpos, VPosition vpos,
int x, int y, int width, int height);