!37068 onAccessibilityHover ability add

Merge pull request !37068 from zhouchaobo/0704
This commit is contained in:
openharmony_ci 2024-07-11 16:23:12 +00:00 committed by Gitee
commit 4129e49084
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
25 changed files with 464 additions and 3 deletions

View File

@ -798,10 +798,15 @@ void AceContainer::InitializeCallback()
ContainerScope scope(id);
context->CheckAndLogLastReceivedTouchEventInfo(event.touchEventId, event.type);
auto touchTask = [context, event, markProcess, node]() {
if (node) {
context->OnTouchEvent(event, node);
if (event.type == TouchType::HOVER_ENTER || event.type == TouchType::HOVER_MOVE ||
event.type == TouchType::HOVER_EXIT || event.type == TouchType::HOVER_CANCEL) {
context->OnAccessibilityHoverEvent(event, node);
} else {
context->OnTouchEvent(event);
if (node) {
context->OnTouchEvent(event, node);
} else {
context->OnTouchEvent(event);
}
}
CHECK_NULL_VOID(markProcess);
markProcess();

View File

@ -211,6 +211,9 @@ void SetTouchEventType(int32_t orgAction, TouchEvent& event)
case OHOS::MMI::PointerEvent::POINTER_ACTION_HOVER_EXIT:
event.type = TouchType::HOVER_EXIT;
return;
case OHOS::MMI::PointerEvent::POINTER_ACTION_HOVER_CANCEL:
event.type = TouchType::HOVER_CANCEL;
return;
default:
LOGW("unknown type");
return;

View File

@ -44,4 +44,41 @@ void JsHoverFunction::HoverExecute(bool isHover, HoverInfo& hoverInfo)
JsFunction::ExecuteJS((sizeof(params) / sizeof(params[0])), params);
}
void JsHoverFunction::AccessibilityHoverExecute(bool isHover, AccessibilityHoverInfo& hoverInfo)
{
JSRef<JSVal> isHoverParam = JSRef<JSVal>::Make(ToJSValue(isHover));
JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
objectTemplate->SetInternalFieldCount(1);
JSRef<JSObject> hoverObj = objectTemplate->NewInstance();
hoverObj->SetPropertyObject(
"getModifierKeyState", JSRef<JSFunc>::New<FunctionCallback>(NG::ArkTSUtils::JsGetModifierKeyState));
hoverObj->SetProperty<double>(
"timestamp", static_cast<double>(hoverInfo.GetTimeStamp().time_since_epoch().count()));
hoverObj->SetProperty<double>("source", static_cast<int32_t>(hoverInfo.GetSourceDevice()));
auto target = CreateEventTargetObject(hoverInfo);
hoverObj->SetPropertyObject("target", target);
hoverObj->SetProperty<double>("sourceTool", static_cast<int32_t>(hoverInfo.GetSourceTool()));
hoverObj->SetProperty<double>("axisVertical", 0.0f);
hoverObj->SetProperty<double>("axisHorizontal", 0.0f);
hoverObj->SetProperty<double>("tiltX", 0.0f);
hoverObj->SetProperty<double>("tiltY", 0.0f);
const OHOS::Ace::Offset& globalLocation = hoverInfo.GetGlobalLocation();
const OHOS::Ace::Offset& localLocation = hoverInfo.GetLocalLocation();
const OHOS::Ace::Offset& screenLocation = hoverInfo.GetScreenLocation();
hoverObj->SetProperty<int32_t>("type", static_cast<int32_t>(hoverInfo.GetActionType()));
hoverObj->SetProperty<double>("displayX", PipelineBase::Px2VpWithCurrentDensity(screenLocation.GetX()));
hoverObj->SetProperty<double>("displayY", PipelineBase::Px2VpWithCurrentDensity(screenLocation.GetY()));
hoverObj->SetProperty<double>("windowX", PipelineBase::Px2VpWithCurrentDensity(globalLocation.GetX()));
hoverObj->SetProperty<double>("windowY", PipelineBase::Px2VpWithCurrentDensity(globalLocation.GetY()));
hoverObj->SetProperty<double>("x", PipelineBase::Px2VpWithCurrentDensity(localLocation.GetX()));
hoverObj->SetProperty<double>("y", PipelineBase::Px2VpWithCurrentDensity(localLocation.GetY()));
hoverObj->Wrap<AccessibilityHoverInfo>(&hoverInfo);
JSRef<JSVal> hoverVal = JSRef<JSObject>::Cast(hoverObj);
JSRef<JSVal> params[] = { isHoverParam, hoverVal };
JsFunction::ExecuteJS((sizeof(params) / sizeof(params[0])), params);
}
} // namespace OHOS::Ace::Framework

View File

@ -27,6 +27,7 @@ public:
explicit JsHoverFunction(const JSRef<JSFunc>& jsFunction) : JsFunction(JSRef<JSObject>(), jsFunction) {}
~JsHoverFunction() override = default;
void HoverExecute(bool isHover, HoverInfo& hoverInfo);
void AccessibilityHoverExecute(bool isHover, AccessibilityHoverInfo& hoverInfo);
};
} // namespace OHOS::Ace::Framework

View File

@ -8451,6 +8451,7 @@ void JSViewAbstract::JSBind(BindingTarget globalObj)
JSClass<JSViewAbstract>::StaticMethod("hoverEffect", &JSViewAbstract::JsHoverEffect);
JSClass<JSViewAbstract>::StaticMethod("onMouse", &JSViewAbstract::JsOnMouse);
JSClass<JSViewAbstract>::StaticMethod("onHover", &JSViewAbstract::JsOnHover);
JSClass<JSViewAbstract>::StaticMethod("onAccessibilityHover", &JSViewAbstract::JsOnAccessibilityHover);
JSClass<JSViewAbstract>::StaticMethod("onClick", &JSViewAbstract::JsOnClick);
JSClass<JSViewAbstract>::StaticMethod("onGestureJudgeBegin", &JSViewAbstract::JsOnGestureJudgeBegin);
JSClass<JSViewAbstract>::StaticMethod("onTouchIntercept", &JSViewAbstract::JsOnTouchIntercept);
@ -9421,6 +9422,28 @@ void JSViewAbstract::JsOnHover(const JSCallbackInfo& info)
ViewAbstractModel::GetInstance()->SetOnHover(std::move(onHover));
}
void JSViewAbstract::JsOnAccessibilityHover(const JSCallbackInfo& info)
{
if (info[0]->IsUndefined()) {
ViewAbstractModel::GetInstance()->DisableOnAccessibilityHover();
return;
}
if (!info[0]->IsFunction()) {
return;
}
RefPtr<JsHoverFunction> jsOnHoverFunc = AceType::MakeRefPtr<JsHoverFunction>(JSRef<JSFunc>::Cast(info[0]));
WeakPtr<NG::FrameNode> frameNode = AceType::WeakClaim(NG::ViewStackProcessor::GetInstance()->GetMainFrameNode());
auto onAccessibilityHover = [execCtx = info.GetExecutionContext(), func = std::move(jsOnHoverFunc),
node = frameNode](bool isHover, AccessibilityHoverInfo& hoverInfo) {
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
ACE_SCORING_EVENT("onAccessibilityHover");
PipelineContext::SetCallBackNode(node);
func->AccessibilityHoverExecute(isHover, hoverInfo);
};
ViewAbstractModel::GetInstance()->SetOnAccessibilityHover(std::move(onAccessibilityHover));
}
void JSViewAbstract::JsOnClick(const JSCallbackInfo& info)
{
auto arg = info[0];

View File

@ -248,6 +248,7 @@ public:
static void JsHoverEffect(const JSCallbackInfo& info);
static void JsOnMouse(const JSCallbackInfo& info);
static void JsOnHover(const JSCallbackInfo& info);
static void JsOnAccessibilityHover(const JSCallbackInfo& info);
static void JsOnClick(const JSCallbackInfo& info);
static void JsOnGestureJudgeBegin(const JSCallbackInfo& args);
static void JsOnTouchIntercept(const JSCallbackInfo& info);

View File

@ -182,6 +182,7 @@ public:
void SetOnKeyEvent(OnKeyCallbackFunc&& onKeyCallback) override;
void SetOnMouse(OnMouseEventFunc&& onMouseEventFunc) override;
void SetOnHover(OnHoverFunc&& onHoverEventFunc) override;
void SetOnAccessibilityHover(OnAccessibilityHoverFunc&& onAccessibilityHoverEventFunc) override {};
void SetOnDelete(std::function<void()>&& onDeleteCallback) override;
void SetOnAppear(std::function<void()>&& onAppearCallback) override;
void SetOnAttach(std::function<void()>&& onAttachCallback) override {}
@ -235,6 +236,7 @@ public:
void DisableOnTouch() override {};
void DisableOnKeyEvent() override {};
void DisableOnHover() override {};
void DisableOnAccessibilityHover() override {};
void DisableOnMouse() override {};
void DisableOnAppear() override {};
void DisableOnDisAppear() override {};

View File

@ -84,6 +84,9 @@ void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::Fram
ACE_FUNCTION_TRACE();
CHECK_NULL_VOID(frameNode);
if (!curAccessibilityHoverResults_.empty()) {
MockHoverCancelEventAndDispatch(touchPoint);
}
// collect
TouchTestResult hitTestResult;
const NG::PointF point { touchPoint.x, touchPoint.y };
@ -1048,6 +1051,25 @@ void EventManager::LogPrintMouseTest()
currNode ? currNode->GetTag().c_str() : "NULL", currNode ? currNode->GetId() : -1);
}
void EventManager::AccessibilityHoverTest(
const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
{
CHECK_NULL_VOID(frameNode);
if (downFingerIds_.empty()) {
MockCancelEventAndDispatch(event);
refereeNG_->CleanAll();
touchTestResults_.clear();
downFingerIds_.clear();
}
const NG::PointF point { event.x, event.y };
TouchTestResult testResult;
TouchTestResult responseLinkResult;
frameNode->TouchTest(
point, point, point, touchRestrict, testResult, event.id, responseLinkResult);
SetResponseLinkRecognizers(testResult, responseLinkResult);
UpdateAccessibilityHoverNode(event, testResult);
}
void EventManager::MouseTest(
const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict)
{
@ -1088,6 +1110,33 @@ void EventManager::MouseTest(
LogPrintMouseTest();
}
void EventManager::UpdateAccessibilityHoverNode(const TouchEvent& event, const TouchTestResult& testResult)
{
HoverTestResult hoverTestResult;
for (const auto& result : testResult) {
auto hoverResult = AceType::DynamicCast<HoverEventTarget>(result);
if (hoverResult && hoverResult->IsAccessibilityHoverTarget()) {
hoverTestResult.emplace_back(hoverResult);
}
}
if (event.type == TouchType::HOVER_EXIT) {
TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Exit hover by HOVER_EXIT event.");
lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
curAccessibilityHoverResults_.clear();
} else if (event.type == TouchType::HOVER_CANCEL) {
TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Cancel hover by HOVER_CANCEL event.");
lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
curAccessibilityHoverResults_.clear();
} else if (event.type == TouchType::HOVER_ENTER) {
TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY, "Enter hover by HOVER_ENTER event.");
lastAccessibilityHoverResults_.clear();
curAccessibilityHoverResults_ = std::move(hoverTestResult);
} else {
lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
curAccessibilityHoverResults_ = std::move(hoverTestResult);
}
}
void EventManager::UpdateHoverNode(const MouseEvent& event, const TouchTestResult& testResult)
{
currMouseTestResults_.clear();
@ -1266,6 +1315,55 @@ bool EventManager::DispatchMouseHoverEventNG(const MouseEvent& event)
return true;
}
void EventManager::DispatchAccessibilityHoverEventNG(const TouchEvent& event)
{
auto lastHoverEndNode = lastAccessibilityHoverResults_.begin();
auto currHoverEndNode = curAccessibilityHoverResults_.begin();
RefPtr<HoverEventTarget> lastHoverEndNodeTarget;
uint32_t iterCountLast = 0;
uint32_t iterCountCurr = 0;
for (const auto& hoverResult : lastAccessibilityHoverResults_) {
// get valid part of previous hover nodes while it's not in current hover nodes. Those nodes exit hover
// there may have some nodes in curAccessibilityHoverResults_ but intercepted
iterCountLast++;
if (lastHoverEndNode != curAccessibilityHoverResults_.end()) {
lastHoverEndNode++;
}
if (std::find(curAccessibilityHoverResults_.begin(), curAccessibilityHoverResults_.end(), hoverResult) ==
curAccessibilityHoverResults_.end()) {
hoverResult->HandleAccessibilityHoverEvent(false, event);
}
if ((iterCountLast >= lastAccessibilityHoverDispatchLength_) && (lastAccessibilityHoverDispatchLength_ != 0)) {
lastHoverEndNodeTarget = hoverResult;
break;
}
}
lastAccessibilityHoverDispatchLength_ = 0;
for (const auto& hoverResult : curAccessibilityHoverResults_) {
// get valid part of current hover nodes while it's not in previous hover nodes. Those nodes are new hover
// the valid part stops at first interception
iterCountCurr++;
if (currHoverEndNode != curAccessibilityHoverResults_.end()) {
currHoverEndNode++;
}
if (std::find(lastAccessibilityHoverResults_.begin(), lastHoverEndNode, hoverResult) == lastHoverEndNode) {
hoverResult->HandleAccessibilityHoverEvent(true, event);
}
if (hoverResult == lastHoverEndNodeTarget) {
lastAccessibilityHoverDispatchLength_ = iterCountCurr;
break;
}
}
for (auto hoverResultIt = lastAccessibilityHoverResults_.begin(); hoverResultIt != lastHoverEndNode;
++hoverResultIt) {
// there may have previous hover nodes in the invalid part of current hover nodes. Those nodes exit hover also
if (std::find(currHoverEndNode, curAccessibilityHoverResults_.end(), *hoverResultIt) !=
curAccessibilityHoverResults_.end()) {
(*hoverResultIt)->HandleAccessibilityHoverEvent(false, event);
}
}
}
void EventManager::AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode)
{
CHECK_NULL_VOID(renderNode);
@ -1964,4 +2062,14 @@ void EventManager::MockCancelEventAndDispatch(const AxisEvent& axisEvent)
mockedEvent.id = static_cast<int32_t>(axisTouchTestResults_.begin()->first);
DispatchTouchEvent(mockedEvent);
}
void EventManager::MockHoverCancelEventAndDispatch(const TouchEvent& touchPoint)
{
lastAccessibilityHoverResults_ = std::move(curAccessibilityHoverResults_);
curAccessibilityHoverResults_.clear();
TouchEvent mockedEvent = touchPoint;
mockedEvent.isMocked = true;
mockedEvent.type = TouchType::HOVER_CANCEL;
DispatchAccessibilityHoverEventNG(mockedEvent);
}
} // namespace OHOS::Ace

View File

@ -123,11 +123,15 @@ public:
void LogPrintMouseTest();
void MouseTest(const MouseEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict);
void AccessibilityHoverTest(
const TouchEvent& event, const RefPtr<NG::FrameNode>& frameNode, TouchRestrict& touchRestrict);
void UpdateAccessibilityHoverNode(const TouchEvent& event, const TouchTestResult& testResult);
void UpdateHoverNode(const MouseEvent& event, const TouchTestResult& testResult);
bool DispatchMouseEventNG(const MouseEvent& event);
void DispatchMouseHoverAnimationNG(const MouseEvent& event);
bool DispatchMouseHoverEventNG(const MouseEvent& event);
void DispatchHoverEffectEvent(const MouseEvent& event);
void DispatchAccessibilityHoverEventNG(const TouchEvent& event);
void AxisTest(const AxisEvent& event, const RefPtr<RenderNode>& renderNode);
bool DispatchAxisEvent(const AxisEvent& event);
@ -286,12 +290,15 @@ private:
void SetResponseLinkRecognizers(const TouchTestResult& result, const TouchTestResult& responseLinkRecognizers);
void MockCancelEventAndDispatch(const TouchEvent& touchPoint);
void MockCancelEventAndDispatch(const AxisEvent& axisEvent);
void MockHoverCancelEventAndDispatch(const TouchEvent& touchPoint);
bool innerEventWin_ = false;
std::unordered_map<size_t, TouchTestResult> mouseTestResults_;
MouseTestResult currMouseTestResults_;
MouseTestResult pressMouseTestResults_;
HoverTestResult currHoverTestResults_;
HoverTestResult lastHoverTestResults_;
HoverTestResult curAccessibilityHoverResults_;
HoverTestResult lastAccessibilityHoverResults_;
AxisTestResult axisTestResults_;
WeakPtr<NG::FrameNode> lastHoverNode_;
WeakPtr<NG::FrameNode> currHoverNode_;
@ -303,6 +310,7 @@ private:
WeakPtr<RenderNode> axisNode_;
int32_t instanceId_ = 0;
uint32_t lastHoverDispatchLength_ = 0;
uint32_t lastAccessibilityHoverDispatchLength_ = 0;
bool inSelectedRect_ = false;
bool isDragging_ = false;
bool isLastMoveBeforeUp_ = false;

View File

@ -893,6 +893,13 @@ void ViewAbstract::DisableOnHover()
eventHub->ClearUserOnHover();
}
void ViewAbstract::DisableOnAccessibilityHover()
{
auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeInputEventHub();
CHECK_NULL_VOID(eventHub);
eventHub->ClearUserOnAccessibilityHover();
}
void ViewAbstract::DisableOnMouse()
{
auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeInputEventHub();
@ -1097,6 +1104,13 @@ void ViewAbstract::SetOnHover(OnHoverFunc&& onHoverEventFunc)
eventHub->SetHoverEvent(std::move(onHoverEventFunc));
}
void ViewAbstract::SetOnAccessibilityHover(OnAccessibilityHoverFunc &&onAccessibilityHoverEventFunc)
{
auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeInputEventHub();
CHECK_NULL_VOID(eventHub);
eventHub->SetAccessibilityHoverEvent(std::move(onAccessibilityHoverEventFunc));
}
void ViewAbstract::SetHoverEffect(HoverEffectType hoverEffect)
{
auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeInputEventHub();

View File

@ -266,6 +266,7 @@ public:
static void SetOnTouch(TouchEventFunc &&touchEventFunc);
static void SetOnMouse(OnMouseEventFunc &&onMouseEventFunc);
static void SetOnHover(OnHoverFunc &&onHoverEventFunc);
static void SetOnAccessibilityHover(OnAccessibilityHoverFunc &&onAccessibilityHoverEventFunc);
static void SetHoverEffect(HoverEffectType hoverEffect);
static void SetHoverEffectAuto(HoverEffectType hoverEffect);
static void SetEnabled(bool enabled);
@ -376,6 +377,7 @@ public:
static void DisableOnTouch();
static void DisableOnKeyEvent();
static void DisableOnHover();
static void DisableOnAccessibilityHover();
static void DisableOnMouse();
static void DisableOnAppear();
static void DisableOnDisAppear();

View File

@ -256,6 +256,7 @@ public:
virtual void SetOnKeyPreIme(OnKeyPreImeFunc&& onKeyCallback) {}
virtual void SetOnMouse(OnMouseEventFunc&& onMouseEventFunc) = 0;
virtual void SetOnHover(OnHoverFunc&& onHoverEventFunc) = 0;
virtual void SetOnAccessibilityHover(OnAccessibilityHoverFunc&& onAccessibilityHoverEventFunc) = 0;
virtual void SetOnDelete(std::function<void()>&& onDeleteCallback) = 0;
virtual void SetOnAppear(std::function<void()>&& onAppearCallback) = 0;
virtual void SetOnAttach(std::function<void()>&& onAttachCallback) = 0;
@ -293,6 +294,7 @@ public:
virtual void DisableOnKeyEvent() = 0;
virtual void DisableOnKeyPreIme() {}
virtual void DisableOnHover() = 0;
virtual void DisableOnAccessibilityHover() = 0;
virtual void DisableOnMouse() = 0;
virtual void DisableOnAppear() = 0;
virtual void DisableOnDisAppear() = 0;

View File

@ -916,6 +916,11 @@ public:
ViewAbstract::SetOnHover(std::move(onHoverEventFunc));
}
void SetOnAccessibilityHover(OnAccessibilityHoverFunc&& onAccessibilityHoverEventFunc) override
{
ViewAbstract::SetOnAccessibilityHover(std::move(onAccessibilityHoverEventFunc));
}
void SetOnDelete(std::function<void()>&& onDeleteCallback) override {}
void SetOnAppear(std::function<void()>&& onAppearCallback) override
@ -1264,6 +1269,11 @@ public:
ViewAbstract::DisableOnHover();
}
void DisableOnAccessibilityHover() override
{
ViewAbstract::DisableOnAccessibilityHover();
}
void DisableOnMouse() override
{
ViewAbstract::DisableOnMouse();

View File

@ -28,6 +28,7 @@ InputEventActuator::InputEventActuator(const WeakPtr<InputEventHub>& inputEventH
mouseEventTarget_ = MakeRefPtr<MouseEventTarget>(frameNode->GetTag(), frameNode->GetId());
hoverEventTarget_ = MakeRefPtr<HoverEventTarget>(frameNode->GetTag(), frameNode->GetId());
hoverEffectTarget_ = MakeRefPtr<HoverEffectTarget>(frameNode->GetTag(), frameNode->GetId());
accessibilityHoverEventTarget_ = MakeRefPtr<HoverEventTarget>(frameNode->GetTag(), frameNode->GetId());
axisEventTarget_ = MakeRefPtr<AxisEventTarget>(frameNode->GetTag());
}
@ -108,6 +109,29 @@ void InputEventActuator::OnCollectHoverEffect(
result.emplace_back(hoverEffectTarget_);
}
void InputEventActuator::OnCollectAccessibilityHoverEvent(const OffsetF& coordinateOffset,
const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, const RefPtr<FrameNode>& host)
{
if (inputEvents_.empty() && !userCallback_ && !userJSFrameNodeCallback_) {
return;
}
auto onAccessibilityHoverCallback = [weak = WeakClaim(this)](
bool info, AccessibilityHoverInfo& accessibilityHoverInfo) {
auto actuator = weak.Upgrade();
CHECK_NULL_VOID(actuator);
auto userEvent = actuator->userCallback_;
if (userEvent) {
(*userEvent)(info, accessibilityHoverInfo);
}
};
accessibilityHoverEventTarget_->AttachFrameNode(host);
accessibilityHoverEventTarget_->SetAccessibilityHoverCallback(onAccessibilityHoverCallback);
accessibilityHoverEventTarget_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
accessibilityHoverEventTarget_->SetGetEventTargetImpl(getEventTargetImpl);
result.emplace_back(accessibilityHoverEventTarget_);
}
void InputEventActuator::OnCollectAxisEvent(
const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, AxisTestResult& onAxisResult)
{

View File

@ -34,6 +34,8 @@ public:
explicit InputEvent(OnAxisEventFunc&& callback) : onAxisCallback_(std::move(callback)) {}
explicit InputEvent(OnAccessibilityHoverFunc&& callback) : onAccessibilityHoverFunc_(std::move(callback)) {}
~InputEvent() override = default;
const OnMouseEventFunc& GetOnMouseEventFunc() const
@ -56,6 +58,11 @@ public:
return onAxisCallback_;
}
const OnAccessibilityHoverFunc& GetOnAccessibilityHoverFunc() const
{
return onAccessibilityHoverFunc_;
}
void operator()(MouseInfo& info) const
{
if (onMouseCallback_) {
@ -83,11 +90,19 @@ public:
}
}
void operator()(bool state, AccessibilityHoverInfo& info) const
{
if (onAccessibilityHoverFunc_) {
onAccessibilityHoverFunc_(state, info);
}
}
private:
OnMouseEventFunc onMouseCallback_;
OnHoverEventFunc onHoverCallback_;
OnHoverFunc onHoverEventCallback_;
OnAxisEventFunc onAxisCallback_;
OnAccessibilityHoverFunc onAccessibilityHoverFunc_;
};
class ACE_EXPORT InputEventActuator : public virtual AceType {
@ -148,6 +163,14 @@ public:
userCallback_ = MakeRefPtr<InputEvent>(std::move(callback));
}
void ReplaceInputEvent(OnAccessibilityHoverFunc&& callback)
{
if (userCallback_) {
userCallback_.Reset();
}
userCallback_ = MakeRefPtr<InputEvent>(std::move(callback));
}
void AddInputEvent(const RefPtr<InputEvent>& inputEvent)
{
if (inputEvents_.empty()) {
@ -173,6 +196,9 @@ public:
void OnCollectHoverEffect(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
TouchTestResult& result);
void OnCollectAccessibilityHoverEvent(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl,
TouchTestResult& result, const RefPtr<FrameNode>& host);
void OnCollectAxisEvent(
const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, AxisTestResult& onAxisResult);
@ -181,6 +207,7 @@ private:
RefPtr<MouseEventTarget> mouseEventTarget_;
RefPtr<HoverEventTarget> hoverEventTarget_;
RefPtr<HoverEffectTarget> hoverEffectTarget_;
RefPtr<HoverEventTarget> accessibilityHoverEventTarget_;
RefPtr<AxisEventTarget> axisEventTarget_;
std::list<RefPtr<InputEvent>> inputEvents_;
RefPtr<InputEvent> userCallback_;

View File

@ -15,6 +15,7 @@
#include "core/components_ng/event/input_event_hub.h"
#include "base/utils/utils.h"
#include "core/components_ng/event/event_hub.h"
#include "core/components_ng/event/input_event.h"
#include "core/pipeline_ng/pipeline_context.h"
@ -43,6 +44,12 @@ bool InputEventHub::ProcessMouseTestHit(const OffsetF& coordinateOffset, TouchTe
if (hoverEffectActuator_) {
hoverEffectActuator_->OnCollectHoverEffect(coordinateOffset, getEventTargetImpl, result);
}
auto host = GetFrameNode();
CHECK_NULL_RETURN(host, false);
if (accessibilityHoverEventActuator_) {
accessibilityHoverEventActuator_->OnCollectAccessibilityHoverEvent(
coordinateOffset, getEventTargetImpl, result, host);
}
return false;
}

View File

@ -96,6 +96,14 @@ public:
hoverEventActuator_->ReplaceInputEvent(std::move(onHoverEventFunc));
}
void SetAccessibilityHoverEvent(OnAccessibilityHoverFunc&& onAccessibilityHoverEventFunc)
{
if (!accessibilityHoverEventActuator_) {
accessibilityHoverEventActuator_ = MakeRefPtr<InputEventActuator>(WeakClaim(this));
}
accessibilityHoverEventActuator_->ReplaceInputEvent(std::move(onAccessibilityHoverEventFunc));
}
void SetJSFrameNodeOnHoverEvent(OnHoverFunc&& onHoverEventFunc)
{
if (!hoverEventActuator_) {
@ -155,6 +163,13 @@ public:
}
}
void ClearUserOnAccessibilityHover()
{
if (accessibilityHoverEventActuator_) {
accessibilityHoverEventActuator_->ClearUserCallback();
}
}
void ClearJSFrameNodeOnHover()
{
if (hoverEventActuator_) {
@ -182,6 +197,7 @@ private:
RefPtr<InputEventActuator> hoverEventActuator_;
RefPtr<InputEventActuator> hoverEffectActuator_;
RefPtr<InputEventActuator> axisEventActuator_;
RefPtr<InputEventActuator> accessibilityHoverEventActuator_;
RefPtr<InputEvent> showMenu_;

View File

@ -119,6 +119,7 @@ Render3D::PointerEvent ModelTouchHandler::CreateSceneTouchEvent(const TouchEvent
case TouchType::HOVER_ENTER:
case TouchType::HOVER_MOVE:
case TouchType::HOVER_EXIT:
case TouchType::HOVER_CANCEL:
case TouchType::UNKNOWN:
break;
}

View File

@ -36,4 +36,53 @@ bool HoverEventTarget::HandleHoverEvent(bool isHovered, const MouseEvent& event)
onHoverEventCallback_(isHovered, hoverInfo);
return !hoverInfo.IsStopPropagation();
}
void HoverEventTarget::HandleAccessibilityHoverEvent(bool isHovered, const TouchEvent& event)
{
if (!onAccessibilityHoverCallback_) {
return;
}
AccessibilityHoverInfo hoverInfo;
hoverInfo.SetTimeStamp(event.time);
hoverInfo.SetDeviceId(event.deviceId);
hoverInfo.SetSourceDevice(event.sourceType);
hoverInfo.SetSourceTool(event.sourceTool);
hoverInfo.SetPressedKeyCodes(event.pressedKeyCodes_);
NG::PointF lastLocalPoint(event.x, event.y);
NG::NGGestureRecognizer::Transform(lastLocalPoint, GetAttachedNode(), false,
isPostEventResult_, event.postEventNodeId);
auto localX = static_cast<float>(lastLocalPoint.GetX());
auto localY = static_cast<float>(lastLocalPoint.GetY());
hoverInfo.SetLocalLocation(Offset(localX, localY));
hoverInfo.SetGlobalLocation(Offset(event.x, event.y));
hoverInfo.SetScreenLocation(Offset(event.screenX, event.screenY));
hoverInfo.SetActionType(ConvertAccessibilityHoverAction(event.type));
hoverInfo.SetTarget(GetEventTarget().value_or(EventTarget()));
onAccessibilityHoverCallback_(isHovered, hoverInfo);
}
AccessibilityHoverAction HoverEventTarget::ConvertAccessibilityHoverAction(TouchType type)
{
switch (type) {
case TouchType::HOVER_ENTER:
return AccessibilityHoverAction::HOVER_ENTER;
case TouchType::HOVER_MOVE:
return AccessibilityHoverAction::HOVER_MOVE;
case TouchType::HOVER_EXIT:
return AccessibilityHoverAction::HOVER_EXIT;
case TouchType::HOVER_CANCEL:
return AccessibilityHoverAction::HOVER_CANCEL;
case TouchType::DOWN:
case TouchType::UP:
case TouchType::MOVE:
case TouchType::CANCEL:
case TouchType::PULL_DOWN:
case TouchType::PULL_UP:
case TouchType::PULL_MOVE:
case TouchType::PULL_IN_WINDOW:
case TouchType::PULL_OUT_WINDOW:
case TouchType::UNKNOWN:
return AccessibilityHoverAction::UNKNOWN;
}
}
} // namespace OHOS::Ace

View File

@ -51,6 +51,14 @@ enum class MouseAction : int32_t {
PULL_UP
};
enum class AccessibilityHoverAction : int32_t {
UNKNOWN = -1,
HOVER_ENTER,
HOVER_MOVE,
HOVER_EXIT,
HOVER_CANCEL
};
enum class MouseState : int32_t {
NONE = 0,
HOVER = 1,
@ -350,9 +358,73 @@ public:
~HoverInfo() override = default;
};
class AccessibilityHoverInfo : public BaseEventInfo {
DECLARE_RELATIONSHIP_OF_CLASSES(AccessibilityHoverInfo, BaseEventInfo);
public:
AccessibilityHoverInfo() : BaseEventInfo("onAccessibilityHover") {}
~AccessibilityHoverInfo() override = default;
AccessibilityHoverInfo& SetGlobalLocation(const Offset& globalLocation)
{
globalLocation_ = globalLocation;
return *this;
}
AccessibilityHoverInfo& SetLocalLocation(const Offset& localLocation)
{
localLocation_ = localLocation;
return *this;
}
AccessibilityHoverInfo& SetScreenLocation(const Offset& screenLocation)
{
screenLocation_ = screenLocation;
return *this;
}
const Offset& GetScreenLocation() const
{
return screenLocation_;
}
const Offset& GetLocalLocation() const
{
return localLocation_;
}
const Offset& GetGlobalLocation() const
{
return globalLocation_;
}
AccessibilityHoverAction GetActionType() const
{
return actionType_;
}
void SetActionType(AccessibilityHoverAction type)
{
actionType_ = type;
}
private:
// global position at which the touch point contacts the screen.
Offset globalLocation_;
// Different from global location, The local location refers to the location of the contact point relative to the
// current node which has the recognizer.
Offset localLocation_;
Offset screenLocation_;
// touch type
AccessibilityHoverAction actionType_ = AccessibilityHoverAction::UNKNOWN;
};
using OnHoverFunc = std::function<void(bool, HoverInfo& info)>;
using OnHoverEventFunc = std::function<void(bool)>;
using OnAccessibilityHoverFunc = std::function<void(bool, AccessibilityHoverInfo& info)>;
class MouseEventTarget : public virtual TouchEventTarget {
DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget);
@ -421,8 +493,20 @@ public:
onHoverEventCallback_ = onHoverEventCallback;
}
void SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc& onAccessibilityHoverCallback)
{
onAccessibilityHoverCallback_ = onAccessibilityHoverCallback;
}
bool HandleHoverEvent(bool isHovered, const MouseEvent& event);
void HandleAccessibilityHoverEvent(bool isHovered, const TouchEvent& event);
bool IsAccessibilityHoverTarget()
{
return onAccessibilityHoverCallback_ != nullptr;
}
bool HandleHoverEvent(bool isHovered)
{
if (!onHoverCallback_) {
@ -441,9 +525,12 @@ public:
return false;
}
AccessibilityHoverAction ConvertAccessibilityHoverAction(TouchType type);
private:
OnHoverEventFunc onHoverCallback_;
OnHoverFunc onHoverEventCallback_;
OnAccessibilityHoverFunc onAccessibilityHoverCallback_;
};
class HoverEffectTarget : public virtual TouchEventTarget {

View File

@ -51,6 +51,7 @@ enum class TouchType : size_t {
HOVER_ENTER,
HOVER_MOVE,
HOVER_EXIT,
HOVER_CANCEL,
UNKNOWN,
};

View File

@ -168,6 +168,8 @@ public:
// Called by ohos AceContainer when touch event received.
virtual void OnTouchEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node, bool isSubPipe = false) {}
virtual void OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node) {}
// Called by container when key event received.
// if return false, then this event needs platform to handle it.
virtual bool OnKeyEvent(const KeyEvent& event) = 0;

View File

@ -2495,6 +2495,33 @@ void PipelineContext::FlushTouchEvents()
}
}
void PipelineContext::OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node)
{
CHECK_RUN_ON(UI);
auto scaleEvent = point.CreateScalePoint(viewScale_);
if (scaleEvent.type != TouchType::HOVER_MOVE) {
eventManager_->GetEventTreeRecord().AddTouchPoint(scaleEvent);
TAG_LOGI(AceLogTag::ACE_ACCESSIBILITY,
"OnAccessibilityHoverEvent event id:%{public}d, fingerId:%{public}d, x=%{public}f y=%{public}f "
"type=%{public}d, "
"inject=%{public}d",
scaleEvent.touchEventId, scaleEvent.id, scaleEvent.x, scaleEvent.y, (int)scaleEvent.type,
scaleEvent.isInjected);
}
auto targerNode = node ? node : rootNode_;
if (accessibilityManagerNG_ != nullptr) {
accessibilityManagerNG_->HandleAccessibilityHoverEvent(targerNode, scaleEvent);
}
TouchRestrict touchRestrict { TouchRestrict::NONE };
touchRestrict.sourceType = scaleEvent.sourceType;
// use mouse to collect accessibility hover target
touchRestrict.hitTestType = SourceType::MOUSE;
touchRestrict.inputEventType = InputEventType::TOUCH_SCREEN;
eventManager_->AccessibilityHoverTest(scaleEvent, targerNode, touchRestrict);
eventManager_->DispatchAccessibilityHoverEventNG(scaleEvent);
RequestFrame();
}
void PipelineContext::OnMouseEvent(const MouseEvent& event, const RefPtr<FrameNode>& node)
{
CHECK_RUN_ON(UI);

View File

@ -134,6 +134,8 @@ public:
void OnTouchEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node, bool isSubPipe = false) override;
void OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node) override;
void OnMouseEvent(const MouseEvent& event, const RefPtr<NG::FrameNode>& node) override;
void OnAxisEvent(const AxisEvent& event, const RefPtr<NG::FrameNode>& node) override;

View File

@ -173,6 +173,8 @@ void PipelineContext::OnAxisEvent(const AxisEvent& event, const RefPtr<FrameNode
void PipelineContext::OnTouchEvent(const TouchEvent& point, bool isSubPipe) {}
void PipelineContext::OnAccessibilityHoverEvent(const TouchEvent& point, const RefPtr<NG::FrameNode>& node) {}
void PipelineContext::OnMouseEvent(const MouseEvent& event) {}
void PipelineContext::FlushTouchEvents() {}