зеркало из https://github.com/mozilla/pjs.git
Modifying view event flow to always start processing from top view, not enter at children
This commit is contained in:
Родитель
d6d7406cae
Коммит
66e96113d0
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче