From f85ee98763d336bd114ac820890af32440e4cf66 Mon Sep 17 00:00:00 2001 From: "joki%netscape.com" Date: Mon, 1 Feb 1999 22:45:59 +0000 Subject: [PATCH] Modifying view event flow to always start processing from top view, not enter at children git-svn-id: svn://10.0.0.236/trunk@19215 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/view/public/nsIView.h | 11 +++++ mozilla/view/src/nsScrollingView.cpp | 4 +- mozilla/view/src/nsView.cpp | 15 +++++-- mozilla/view/src/nsView.h | 2 + mozilla/view/src/nsViewManager.cpp | 64 ++++++++++++++++++++++++---- 5 files changed, 82 insertions(+), 14 deletions(-) diff --git a/mozilla/view/public/nsIView.h b/mozilla/view/public/nsIView.h index 0e371c2496a..20d2ccd21ff 100644 --- a/mozilla/view/public/nsIView.h +++ b/mozilla/view/public/nsIView.h @@ -421,6 +421,13 @@ public: */ virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const = 0; + /** + * Set flags on view to allow customization of view behavior during + * event handling + * @param aFlags flags to be added to view + */ + NS_IMETHOD SetViewFlags(PRInt32 aFlags) = 0; + private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; NS_IMETHOD_(nsrefcnt) Release(void) = 0; @@ -455,4 +462,8 @@ private: //while in the front to back pass #define NS_VIEW_FLAG_FRONT_TO_BACK 0x0040 +//Flag to determine whether the view will check if events can be handled +//by its children or just handle the events itself +#define NS_VIEW_FLAG_DONT_CHECK_CHILDREN 0x0001 + #endif diff --git a/mozilla/view/src/nsScrollingView.cpp b/mozilla/view/src/nsScrollingView.cpp index c6784506208..f48d1723348 100644 --- a/mozilla/view/src/nsScrollingView.cpp +++ b/mozilla/view/src/nsScrollingView.cpp @@ -711,9 +711,9 @@ NS_IMETHODIMP nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent } // switch } break; +#if 0 case NS_MOUSE_MOVE: { -#if 0 nsRect brect; nscoord lx, ly; @@ -751,7 +751,6 @@ NS_IMETHODIMP nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent mScrollingTimer->Cancel(); NS_RELEASE(mScrollingTimer); } -#endif break; } @@ -799,6 +798,7 @@ NS_IMETHODIMP nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent } break; } +#endif default: break; diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index 39f086c8a3a..8bf79719f52 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -72,6 +72,7 @@ nsView :: nsView() mVis = nsViewVisibility_kShow; mXForm = nsnull; mVFlags = ~ALL_VIEW_FLAGS; + mEventFlags = 0; mOpacity = 1.0f; } @@ -740,9 +741,10 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags, //printf(" %d %d %d %d (%d,%d) \n", this, event->widget, event->widgetSupports, // event->message, event->point.x, event->point.y); aStatus = nsEventStatus_eIgnore; + PRBool handledByChild = PR_FALSE; //see if any of this view's children can process the event - if (aStatus == nsEventStatus_eIgnore) { + if (aStatus == nsEventStatus_eIgnore && !(mEventFlags & NS_VIEW_FLAG_DONT_CHECK_CHILDREN)) { PRInt32 numkids; nsRect trect; nscoord x, y; @@ -760,6 +762,7 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags, if (trect.Contains(x, y)) { + handledByChild = PR_TRUE; //the x, y position of the event in question //is inside this child view, so give it the //opportunity to handle the event @@ -778,8 +781,8 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags, } } - //if the view's children didn't take the event, check the view itself. - if ((aStatus == nsEventStatus_eIgnore) && (nsnull != mClientData)) + //if no child's bounds matched the event, check the view itself. + if (!handledByChild && nsnull != mClientData) { nsIViewObserver *obs; @@ -1252,6 +1255,12 @@ void nsView :: List(FILE* out, PRInt32 aIndent) const fputs(">\n", out); } +NS_IMETHODIMP nsView :: SetViewFlags(PRInt32 aFlags) +{ + mVFlags &= aFlags; + return NS_OK; +} + NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget *&aWidget) { nsIView *ancestor; diff --git a/mozilla/view/src/nsView.h b/mozilla/view/src/nsView.h index bde76b400ca..1fed6ac41e0 100644 --- a/mozilla/view/src/nsView.h +++ b/mozilla/view/src/nsView.h @@ -98,6 +98,7 @@ public: NS_IMETHOD SetWidget(nsIWidget *aWidget); NS_IMETHOD GetWidget(nsIWidget *&aWidget); virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; + NS_IMETHOD SetViewFlags(PRInt32 aFlags); // Helper function to get the view that's associated with a widget static nsIView* GetViewFor(nsIWidget* aWidget); @@ -125,6 +126,7 @@ protected: float mOpacity; PRInt32 mVFlags; nsIRegion* mDirtyRegion; + PRInt32 mEventFlags; private: NS_IMETHOD_(nsrefcnt) AddRef(void); diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 754f6b3caa5..d04c4f7592b 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -25,8 +25,10 @@ #include "nsIScrollableView.h" #include "nsIRegion.h" #include "nsView.h" +#include "nsIScrollbar.h" static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID); +static NS_DEFINE_IID(kIScrollbarIID, NS_ISCROLLBAR_IID); static const PRBool gsDebug = PR_FALSE; @@ -793,33 +795,77 @@ NS_IMETHODIMP nsViewManager :: DispatchEvent(nsGUIEvent *aEvent, nsEventStatus & default: { + nsIView* baseView; nsIView* view; + nsPoint offset; + nsIScrollbar* sb; + + //Find the view whose coordinates system we're in. + baseView = nsView::GetViewFor(aEvent->widget); - if (nsnull != mMouseGrabber && NS_IS_MOUSE_EVENT(aEvent)) + //Find the view to which we're initially going to send the event + //for hittesting. + if (nsnull != mMouseGrabber && NS_IS_MOUSE_EVENT(aEvent)) { view = mMouseGrabber; - else if (nsnull != mKeyGrabber && NS_IS_KEY_EVENT(aEvent)) + } + else if (nsnull != mKeyGrabber && NS_IS_KEY_EVENT(aEvent)) { view = mKeyGrabber; - else - view = nsView::GetViewFor(aEvent->widget); + } + else if (NS_OK == aEvent->widget->QueryInterface(kIScrollbarIID, (void**)&sb)) { + view = baseView; + NS_RELEASE(sb); + } + else { + view = mRootView; + } - if (nsnull != view) - { + if (nsnull != view) { + //Calculate the proper offset for the view we're going to + offset.x = offset.y = 0; + if (baseView != view) { + //Get offset from root of baseView + nsIView *parent; + nsRect bounds; + + parent = baseView; + while (nsnull != parent) { + parent->GetBounds(bounds); + offset.x += bounds.x; + offset.y += bounds.y; + parent->GetParent(parent); + } + + //Subtract back offset from root of view + parent = view; + while (nsnull != parent) { + parent->GetBounds(bounds); + offset.x -= bounds.x; + offset.y -= bounds.y; + parent->GetParent(parent); + } + + } + + //Dispatch the event float p2t, t2p; - // pass on to view somewhere else to deal with - mContext->GetDevUnitsToAppUnits(p2t); mContext->GetAppUnitsToDevUnits(t2p); aEvent->point.x = NSIntPixelsToTwips(aEvent->point.x, p2t); aEvent->point.y = NSIntPixelsToTwips(aEvent->point.y, p2t); - + aEvent->point.x += offset.x; + aEvent->point.y += offset.y; + view->HandleEvent(aEvent, NS_VIEW_FLAG_CHECK_CHILDREN | NS_VIEW_FLAG_CHECK_PARENT | NS_VIEW_FLAG_CHECK_SIBLINGS, aStatus); + aEvent->point.x -= offset.x; + aEvent->point.y -= offset.y; + aEvent->point.x = NSTwipsToIntPixels(aEvent->point.x, t2p); aEvent->point.y = NSTwipsToIntPixels(aEvent->point.y, t2p); }