Bug 979692 - Calculate hit detection and fill in region parameter to mouse events. r=roc

This commit is contained in:
Rik Cabanier 2014-05-12 15:52:00 +02:00
parent fc3446eebe
commit 1ceeb9ec46
6 changed files with 58 additions and 1 deletions

View File

@ -1110,6 +1110,17 @@ CanvasRenderingContext2D::GetImageBuffer(uint8_t** aImageBuffer,
*aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB; *aFormat = imgIEncoder::INPUT_FORMAT_HOSTARGB;
} }
nsString CanvasRenderingContext2D::GetHitRegion(const mozilla::gfx::Point& aPoint)
{
for (unsigned int x = 0 ; x < mHitRegionsOptions.Length(); x++) {
RegionInfo& info = mHitRegionsOptions[x];
if (info.mPath->ContainsPoint(aPoint, Matrix())) {
return info.mId;
}
}
return nsString();
}
NS_IMETHODIMP NS_IMETHODIMP
CanvasRenderingContext2D::GetInputStream(const char *aMimeType, CanvasRenderingContext2D::GetInputStream(const char *aMimeType,
const char16_t *aEncoderOptions, const char16_t *aEncoderOptions,

View File

@ -537,6 +537,11 @@ public:
virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat); virtual void GetImageBuffer(uint8_t** aImageBuffer, int32_t* aFormat);
// Given a point, return hit region ID if it exists
nsString GetHitRegion(const mozilla::gfx::Point& aPoint);
// return true and fills in the bound rect if element has a hit region. // return true and fills in the bound rect if element has a hit region.
bool GetHitRegionRect(Element* aElement, nsRect& aRect); bool GetHitRegionRect(Element* aElement, nsRect& aRect);

View File

@ -185,6 +185,8 @@ public:
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
nsresult CopyInnerTo(mozilla::dom::Element* aDest); nsresult CopyInnerTo(mozilla::dom::Element* aDest);
virtual nsresult PreHandleEvent(mozilla::EventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
/* /*
* Helpers called by various users of Canvas * Helpers called by various users of Canvas
*/ */

View File

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -14,7 +14,10 @@
#include "mozilla/dom/CanvasRenderingContext2D.h" #include "mozilla/dom/CanvasRenderingContext2D.h"
#include "mozilla/dom/HTMLCanvasElementBinding.h" #include "mozilla/dom/HTMLCanvasElementBinding.h"
#include "mozilla/dom/UnionTypes.h" #include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/MouseEvent.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/gfx/Rect.h" #include "mozilla/gfx/Rect.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
#include "mozilla/Telemetry.h" #include "mozilla/Telemetry.h"
#include "nsAttrValueInlines.h" #include "nsAttrValueInlines.h"
@ -28,6 +31,7 @@
#include "nsIWritablePropertyBag2.h" #include "nsIWritablePropertyBag2.h"
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsJSUtils.h" #include "nsJSUtils.h"
#include "nsLayoutUtils.h"
#include "nsMathUtils.h" #include "nsMathUtils.h"
#include "nsNetUtil.h" #include "nsNetUtil.h"
#include "nsStreamUtils.h" #include "nsStreamUtils.h"
@ -288,6 +292,34 @@ HTMLCanvasElement::CopyInnerTo(Element* aDest)
return rv; return rv;
} }
nsresult HTMLCanvasElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
{
if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT) {
WidgetMouseEventBase* evt = (WidgetMouseEventBase*)aVisitor.mEvent;
if (evt) {
nsCOMPtr<nsISupports> cxt;
GetContext(NS_LITERAL_STRING("2d"), getter_AddRefs(cxt));
nsRefPtr<CanvasRenderingContext2D> context2d =
static_cast<CanvasRenderingContext2D*>(cxt.get());
if (context2d) {
nsIFrame *frame = GetPrimaryFrame();
if (!frame)
return NS_OK;
nsPoint ptInRoot = nsLayoutUtils::GetEventCoordinatesRelativeTo(evt, frame);
nsRect paddingRect = frame->GetContentRectRelativeToSelf();
Point hitpoint;
hitpoint.x = (ptInRoot.x - paddingRect.x) / AppUnitsPerCSSPixel();
hitpoint.y = (ptInRoot.y - paddingRect.y) / AppUnitsPerCSSPixel();
evt->region = context2d->GetHitRegion(hitpoint);
aVisitor.mCanHandle = true;
}
}
}
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
}
nsChangeHint nsChangeHint
HTMLCanvasElement::GetAttributeChangeHint(const nsIAtom* aAttribute, HTMLCanvasElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
int32_t aModType) const int32_t aModType) const

View File

@ -299,6 +299,10 @@ void
MouseEvent::GetRegion(nsAString& aRegion) MouseEvent::GetRegion(nsAString& aRegion)
{ {
SetDOMStringToNull(aRegion); SetDOMStringToNull(aRegion);
WidgetMouseEventBase* mouseEventBase = mEvent->AsMouseEventBase();
if (mouseEventBase) {
aRegion = mouseEventBase->region;
}
} }
NS_IMETHODIMP NS_IMETHODIMP

View File

@ -126,6 +126,9 @@ public:
// Possible values at nsIDOMMouseEvent // Possible values at nsIDOMMouseEvent
uint16_t inputSource; uint16_t inputSource;
// ID of the canvas HitRegion
nsString region;
void AssignMouseEventBaseData(const WidgetMouseEventBase& aEvent, void AssignMouseEventBaseData(const WidgetMouseEventBase& aEvent,
bool aCopyTargets) bool aCopyTargets)
{ {