mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 489127 - nodesFromRect required for better usability on mobile devices (part 1+2) [r=roc]
This commit is contained in:
parent
a437509342
commit
960464193b
@ -885,8 +885,9 @@ void nsDisplayList::DeleteAll() {
|
||||
}
|
||||
}
|
||||
|
||||
nsIFrame* nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
nsDisplayItem::HitTestState* aState) const {
|
||||
void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
nsDisplayItem::HitTestState* aState,
|
||||
nsTArray<nsIFrame*> *aOutFrames) const {
|
||||
PRInt32 itemBufferStart = aState->mItemBuffer.Length();
|
||||
nsDisplayItem* item;
|
||||
for (item = GetBottom(); item; item = item->GetAbove()) {
|
||||
@ -898,21 +899,23 @@ nsIFrame* nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
item = aState->mItemBuffer[i];
|
||||
aState->mItemBuffer.SetLength(i);
|
||||
|
||||
if (item->GetBounds(aBuilder).Contains(aPt)) {
|
||||
nsIFrame* f = item->HitTest(aBuilder, aPt, aState);
|
||||
// Handle the XUL 'mousethrough' feature and 'pointer-events'.
|
||||
if (f) {
|
||||
if (aRect.Intersects(item->GetBounds(aBuilder))) {
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
item->HitTest(aBuilder, aRect, aState, &outFrames);
|
||||
|
||||
for (PRUint32 j = 0; j < outFrames.Length(); j++) {
|
||||
nsIFrame *f = outFrames.ElementAt(j);
|
||||
// Handle the XUL 'mousethrough' feature and 'pointer-events'.
|
||||
if (!f->GetMouseThrough() &&
|
||||
f->GetStyleVisibility()->mPointerEvents != NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
aState->mItemBuffer.SetLength(itemBufferStart);
|
||||
return f;
|
||||
aOutFrames->AppendElement(f);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
NS_ASSERTION(aState->mItemBuffer.Length() == PRUint32(itemBufferStart),
|
||||
"How did we forget to pop some elements?");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
static void Sort(nsDisplayList* aList, PRInt32 aCount, nsDisplayList::SortLEQ aCmp,
|
||||
@ -1386,10 +1389,10 @@ nsDisplayWrapList::~nsDisplayWrapList() {
|
||||
mList.DeleteAll();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) {
|
||||
return mList.HitTest(aBuilder, aPt, aState);
|
||||
void
|
||||
nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
mList.HitTest(aBuilder, aRect, aState, aOutFrames);
|
||||
}
|
||||
|
||||
nsRect
|
||||
@ -1885,23 +1888,24 @@ PRBool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
|
||||
#endif
|
||||
|
||||
/* HitTest does some fun stuff with matrix transforms to obtain the answer. */
|
||||
nsIFrame *nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
||||
nsPoint aPt,
|
||||
HitTestState *aState)
|
||||
void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
||||
const nsRect& aRect,
|
||||
HitTestState *aState,
|
||||
nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
/* Here's how this works:
|
||||
* 1. Get the matrix. If it's singular, abort (clearly we didn't hit
|
||||
* anything).
|
||||
* 2. Invert the matrix.
|
||||
* 3. Use it to transform the point into the correct space.
|
||||
* 4. Pass that point down through to the list's version of HitTest.
|
||||
* 3. Use it to transform the rect into the correct space.
|
||||
* 4. Pass that rect down through to the list's version of HitTest.
|
||||
*/
|
||||
float factor = nsPresContext::AppUnitsPerCSSPixel();
|
||||
gfxMatrix matrix =
|
||||
GetResultingTransformMatrix(mFrame, aBuilder->ToReferenceFrame(mFrame),
|
||||
factor, nsnull);
|
||||
if (matrix.IsSingular())
|
||||
return nsnull;
|
||||
return;
|
||||
|
||||
/* We want to go from transformed-space to regular space.
|
||||
* Thus we have to invert the matrix, which normally does
|
||||
@ -1910,27 +1914,45 @@ nsIFrame *nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
||||
matrix.Invert();
|
||||
|
||||
/* Now, apply the transform and pass it down the channel. */
|
||||
gfxPoint result = matrix.Transform(gfxPoint(NSAppUnitsToFloatPixels(aPt.x, factor),
|
||||
NSAppUnitsToFloatPixels(aPt.y, factor)));
|
||||
nsRect resultingRect;
|
||||
if (aRect.width == 1 && aRect.height == 1) {
|
||||
gfxPoint point = matrix.Transform(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.y, factor)));
|
||||
|
||||
resultingRect = nsRect(NSFloatPixelsToAppUnits(float(point.x), factor),
|
||||
NSFloatPixelsToAppUnits(float(point.y), factor),
|
||||
1, 1);
|
||||
|
||||
} else {
|
||||
gfxRect originalRect(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.y, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.width, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.height, factor));
|
||||
|
||||
gfxRect rect = matrix.TransformBounds(originalRect);
|
||||
|
||||
resultingRect = nsRect(NSFloatPixelsToAppUnits(float(rect.X()), factor),
|
||||
NSFloatPixelsToAppUnits(float(rect.Y()), factor),
|
||||
NSFloatPixelsToAppUnits(float(rect.Width()), factor),
|
||||
NSFloatPixelsToAppUnits(float(rect.Height()), factor));
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG_HIT
|
||||
printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
|
||||
printf(" Untransformed point: (%f, %f)\n", result.x, result.y);
|
||||
printf(" Untransformed point: (%f, %f)\n", resultingRect.X(), resultingRect.Y());
|
||||
PRUint32 originalFrameCount = aOutFrames.Length();
|
||||
#endif
|
||||
|
||||
nsIFrame* resultFrame =
|
||||
mStoredList.HitTest(aBuilder,
|
||||
nsPoint(NSFloatPixelsToAppUnits(float(result.x), factor),
|
||||
NSFloatPixelsToAppUnits(float(result.y), factor)), aState);
|
||||
|
||||
mStoredList.HitTest(aBuilder, resultingRect, aState, aOutFrames);
|
||||
|
||||
#ifdef DEBUG_HIT
|
||||
if (resultFrame)
|
||||
printf(" Hit! Time: %f, frame: %p\n", static_cast<double>(clock()),
|
||||
dynamic_cast<void *>(resultFrame));
|
||||
if (originalFrameCount != aOutFrames.Length())
|
||||
printf(" Hit! Time: %f, first frame: %p\n", static_cast<double>(clock()),
|
||||
dynamic_cast<void *>(aOutFrames.ElementAt(0)));
|
||||
printf("=== end of hit test ===\n");
|
||||
#endif
|
||||
|
||||
return resultFrame;
|
||||
}
|
||||
|
||||
/* The bounding rectangle for the object is the overflow rectangle translated
|
||||
@ -2085,14 +2107,15 @@ PRBool nsDisplaySVGEffects::IsOpaque(nsDisplayListBuilder* aBuilder)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsDisplaySVGEffects::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState)
|
||||
void
|
||||
nsDisplaySVGEffects::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
if (!nsSVGIntegrationUtils::HitTestFrameForEffects(mEffectsFrame,
|
||||
aPt - aBuilder->ToReferenceFrame(mEffectsFrame)))
|
||||
return nsnull;
|
||||
return mList.HitTest(aBuilder, aPt, aState);
|
||||
nsPoint rectCenter(aRect.x + aRect.width / 2, aRect.y + aRect.height / 2);
|
||||
if (nsSVGIntegrationUtils::HitTestFrameForEffects(mEffectsFrame,
|
||||
rectCenter - aBuilder->ToReferenceFrame(mEffectsFrame))) {
|
||||
mList.HitTest(aBuilder, aRect, aState, aOutFrames);
|
||||
}
|
||||
}
|
||||
|
||||
void nsDisplaySVGEffects::Paint(nsDisplayListBuilder* aBuilder,
|
||||
|
@ -515,8 +515,8 @@ public:
|
||||
* @return the frame that the point is considered over, or nsnull if
|
||||
* this is not over any frame
|
||||
*/
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return nsnull; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {}
|
||||
/**
|
||||
* @return the frame that this display item is based on. This is used to sort
|
||||
* items by z-index and content order and for some other uses. For some items
|
||||
@ -871,8 +871,9 @@ public:
|
||||
* Find the topmost display item that returns a non-null frame, and return
|
||||
* the frame.
|
||||
*/
|
||||
nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
nsDisplayItem::HitTestState* aState) const;
|
||||
void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
nsDisplayItem::HitTestState* aState,
|
||||
nsTArray<nsIFrame*> *aOutFrames) const;
|
||||
|
||||
/**
|
||||
* This class represents a sublist of consecutive items in an nsDisplayList.
|
||||
@ -1310,8 +1311,11 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
|
||||
virtual PRBool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder);
|
||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder);
|
||||
@ -1409,8 +1413,11 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
NS_DISPLAY_DECL_NAME("EventReceiver")
|
||||
};
|
||||
|
||||
@ -1440,8 +1447,8 @@ public:
|
||||
nsDisplayWrapList(nsIFrame* aFrame, nsDisplayItem* aItem);
|
||||
virtual ~nsDisplayWrapList();
|
||||
virtual Type GetType() { return TYPE_WRAPLIST; }
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
|
||||
virtual PRBool IsUniform(nsDisplayListBuilder* aBuilder);
|
||||
@ -1587,8 +1594,8 @@ public:
|
||||
|
||||
virtual Type GetType() { return TYPE_SVG_EFFECTS; }
|
||||
virtual PRBool IsOpaque(nsDisplayListBuilder* aBuilder);
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
||||
return mBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
|
||||
}
|
||||
@ -1644,8 +1651,8 @@ public:
|
||||
nsDisplayWrapList* GetStoredList() { return &mStoredList; }
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder *aBuilder, nsPoint aPt,
|
||||
HitTestState *aState);
|
||||
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
|
||||
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
|
||||
virtual PRBool IsOpaque(nsDisplayListBuilder *aBuilder);
|
||||
virtual PRBool IsUniform(nsDisplayListBuilder *aBuilder);
|
||||
|
@ -140,9 +140,9 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) {
|
||||
return mFrame;
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
|
@ -186,20 +186,20 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("FieldSetBorderBackground")
|
||||
};
|
||||
|
||||
nsIFrame* nsDisplayFieldSetBorderBackground::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
nsPoint aPt, HitTestState* aState)
|
||||
void nsDisplayFieldSetBorderBackground::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
// aPt is guaranteed to be in this item's bounds. We do the hit test based on the
|
||||
// frame bounds even though our background doesn't cover the whole frame.
|
||||
// It's not clear whether this is correct.
|
||||
return mFrame;
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -96,32 +96,34 @@ public:
|
||||
: nsDisplayWrapList(aFrame, aItem) {}
|
||||
nsDisplayOptionEventGrabber(nsIFrame* aFrame, nsDisplayList* aList)
|
||||
: nsDisplayWrapList(aFrame, aList) {}
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
NS_DISPLAY_DECL_NAME("OptionEventGrabber")
|
||||
|
||||
virtual nsDisplayWrapList* WrapWithClone(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem);
|
||||
};
|
||||
|
||||
nsIFrame* nsDisplayOptionEventGrabber::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
nsPoint aPt, HitTestState* aState)
|
||||
void nsDisplayOptionEventGrabber::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
nsIFrame* frame = mList.HitTest(aBuilder, aPt, aState);
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
mList.HitTest(aBuilder, aRect, aState, &outFrames);
|
||||
|
||||
if (frame) {
|
||||
nsIFrame* selectedFrame = frame;
|
||||
for (PRUint32 i = 0; i < outFrames.Length(); i++) {
|
||||
nsIFrame* selectedFrame = outFrames.ElementAt(i);
|
||||
while (selectedFrame &&
|
||||
!nsSelectsAreaFrame::IsOptionElementFrame(selectedFrame)) {
|
||||
selectedFrame = selectedFrame->GetParent();
|
||||
}
|
||||
if (selectedFrame) {
|
||||
return selectedFrame;
|
||||
aOutFrames->AppendElement(selectedFrame);
|
||||
} else {
|
||||
// keep the original result, which could be this frame
|
||||
aOutFrames->AppendElement(outFrames.ElementAt(i));
|
||||
}
|
||||
// else, keep the original result, which could be this frame
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
nsDisplayWrapList* nsDisplayOptionEventGrabber::WrapWithClone(
|
||||
|
@ -194,8 +194,10 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("Bullet")
|
||||
|
@ -1625,8 +1625,10 @@ public:
|
||||
|
||||
// REVIEW: see old GetFrameForPoint
|
||||
// Receives events in its bounds
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("FramesetBorder")
|
||||
|
@ -3879,9 +3879,11 @@ public:
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
|
||||
return mFrame->GetOverflowRect() + aBuilder->ToReferenceFrame(mFrame);
|
||||
}
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) {
|
||||
return nsRect(aBuilder->ToReferenceFrame(mFrame), mFrame->GetSize()).Contains(aPt) ? mFrame : nsnull;
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
if (nsRect(aBuilder->ToReferenceFrame(mFrame), mFrame->GetSize()).Intersects(aRect)) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
|
@ -430,19 +430,30 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("SVGEventReceiver")
|
||||
};
|
||||
|
||||
nsIFrame*
|
||||
nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState)
|
||||
void
|
||||
nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
return static_cast<nsSVGOuterSVGFrame*>(mFrame)->
|
||||
GetFrameForPoint(aPt - aBuilder->ToReferenceFrame(mFrame));
|
||||
nsRect rectAtOrigin = aRect - aBuilder->ToReferenceFrame(mFrame);
|
||||
nsRect thisRect(nsPoint(0,0), static_cast<nsSVGOuterSVGFrame*>(mFrame)->GetSize());
|
||||
if (!thisRect.Intersects(rectAtOrigin))
|
||||
return;
|
||||
|
||||
nsPoint rectCenter(rectAtOrigin.x + rectAtOrigin.width / 2,
|
||||
rectAtOrigin.y + rectAtOrigin.height / 2);
|
||||
|
||||
nsIFrame* frame = nsSVGUtils::HitTestChildren(static_cast<nsSVGOuterSVGFrame*>(mFrame),
|
||||
rectCenter);
|
||||
if (frame) {
|
||||
aOutFrames->AppendElement(frame);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -394,8 +394,10 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
|
||||
|
@ -1264,11 +1264,12 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) {
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, nsRect aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
nsPoint rectCenter(aRect.x + aRect.width / 2, aRect.y + aRect.height / 2);
|
||||
static_cast<nsBoxFrame*>(mFrame)->
|
||||
DisplayDebugInfoFor(this, aPt - aBuilder->ToReferenceFrame(mFrame));
|
||||
return PR_TRUE;
|
||||
DisplayDebugInfoFor(this, rectCenter - aBuilder->ToReferenceFrame(mFrame));
|
||||
aOutFrames->AppendElement(this);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder
|
||||
nsIRenderingContext* aCtx);
|
||||
@ -2136,31 +2137,38 @@ public:
|
||||
nsDisplayXULEventRedirector(nsIFrame* aFrame, nsDisplayList* aList,
|
||||
nsIFrame* aTargetFrame)
|
||||
: nsDisplayWrapList(aFrame, aList), mTargetFrame(aTargetFrame) {}
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
NS_DISPLAY_DECL_NAME("XULEventRedirector")
|
||||
private:
|
||||
nsIFrame* mTargetFrame;
|
||||
};
|
||||
|
||||
nsIFrame* nsDisplayXULEventRedirector::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
nsPoint aPt, HitTestState* aState)
|
||||
void nsDisplayXULEventRedirector::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aRect, HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
nsIFrame* frame = mList.HitTest(aBuilder, aPt, aState);
|
||||
if (!frame)
|
||||
return nsnull;
|
||||
nsTArray<nsIFrame*> outFrames;
|
||||
mList.HitTest(aBuilder, aRect, aState, &outFrames);
|
||||
|
||||
for (nsIContent* content = frame->GetContent();
|
||||
content && content != mTargetFrame->GetContent();
|
||||
content = content->GetParent()) {
|
||||
if (content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
|
||||
nsGkAtoms::_true, eCaseMatters)) {
|
||||
// Events are allowed on 'frame', so let it go.
|
||||
return frame;
|
||||
PRInt32 originalLength = aOutFrames->Length();
|
||||
|
||||
for (PRUint32 i = 0; i < originalLength; i++) {
|
||||
|
||||
for (nsIContent* content = outFrames.ElementAt(i)->GetContent();
|
||||
content && content != mTargetFrame->GetContent();
|
||||
content = content->GetParent()) {
|
||||
if (content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
|
||||
nsGkAtoms::_true, eCaseMatters)) {
|
||||
// Events are allowed on 'frame', so let it go.
|
||||
aOutFrames->AppendElement(outFrames.ElementAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// If no hits were found, treat it as a hit on the target frame itself
|
||||
if (aOutFrames->Length() == originalLength) {
|
||||
aOutFrames->AppendElement(mTargetFrame);
|
||||
}
|
||||
// Treat it as a hit on the target frame itself.
|
||||
return mTargetFrame;
|
||||
}
|
||||
|
||||
class nsXULEventRedirectorWrapper : public nsDisplayWrapper
|
||||
|
@ -116,8 +116,10 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState) { return mFrame; }
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) {
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsIRenderingContext* aCtx);
|
||||
NS_DISPLAY_DECL_NAME("XULGroupBackground")
|
||||
|
@ -99,24 +99,25 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
|
||||
HitTestState* aState);
|
||||
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
|
||||
NS_DISPLAY_DECL_NAME("XULTreeColSplitterTarget")
|
||||
};
|
||||
|
||||
nsIFrame*
|
||||
nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
nsPoint aPt, HitTestState* aState)
|
||||
void
|
||||
nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
||||
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
|
||||
{
|
||||
nsPoint pt = aPt - aBuilder->ToReferenceFrame(mFrame);
|
||||
// If we are in either the first 4 pixels or the last 4 pixels, we're going to
|
||||
nsRect rect = aRect - aBuilder->ToReferenceFrame(mFrame);
|
||||
// If we are in either in the first 4 pixels or the last 4 pixels, we're going to
|
||||
// do something really strange. Check for an adjacent splitter.
|
||||
PRBool left = PR_FALSE;
|
||||
PRBool right = PR_FALSE;
|
||||
if (mFrame->GetSize().width - nsPresContext::CSSPixelsToAppUnits(4) <= pt.x)
|
||||
if (mFrame->GetSize().width - nsPresContext::CSSPixelsToAppUnits(4) <= rect.XMost()) {
|
||||
right = PR_TRUE;
|
||||
else if (nsPresContext::CSSPixelsToAppUnits(4) > pt.x)
|
||||
} else if (nsPresContext::CSSPixelsToAppUnits(4) > rect.x) {
|
||||
left = PR_TRUE;
|
||||
}
|
||||
|
||||
// Swap left and right for RTL trees in order to find the correct splitter
|
||||
if (mFrame->GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) {
|
||||
@ -135,11 +136,10 @@ nsDisplayXULTreeColSplitterTarget::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
if (child && child->GetContent()->NodeInfo()->Equals(nsGkAtoms::splitter,
|
||||
kNameSpaceID_XUL)) {
|
||||
return child;
|
||||
aOutFrames->AppendElement(child);
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
Loading…
Reference in New Issue
Block a user