From 14c8a0e1b179309e2c29462279c015921260ec16 Mon Sep 17 00:00:00 2001 From: liwenzhen Date: Thu, 14 Apr 2022 10:25:06 +0800 Subject: [PATCH] :[xcomponent]Support mouse event Signed-off-by: liwenzhen Change-Id: Ia97edd515dce71e40c97cebbdd7e57e36f6aa7d7 --- adapter/ohos/entrance/ace_container.cpp | 5 +- .../native_interface_xcomponent_impl.cpp | 13 ++++ .../native_interface_xcomponent_impl.h | 12 ++++ .../xcomponent/render_xcomponent.cpp | 29 ++++++++ .../components/xcomponent/render_xcomponent.h | 1 + .../xcomponent/xcomponent_element.cpp | 44 +++++++++++- .../xcomponent/xcomponent_element.h | 4 +- frameworks/core/pipeline/pipeline_context.cpp | 10 +++ frameworks/core/pipeline/pipeline_context.h | 8 +++ interfaces/native/libace.ndk.json | 4 ++ .../native/native_interface_xcomponent.cpp | 9 +++ .../native/native_interface_xcomponent.h | 67 +++++++++++++++++++ 12 files changed, 202 insertions(+), 4 deletions(-) diff --git a/adapter/ohos/entrance/ace_container.cpp b/adapter/ohos/entrance/ace_container.cpp index ca74ce4a..98f01aad 100644 --- a/adapter/ohos/entrance/ace_container.cpp +++ b/adapter/ohos/entrance/ace_container.cpp @@ -505,7 +505,10 @@ void AceContainer::InitializeCallback() auto&& mouseEventCallback = [context = pipelineContext_, id = instanceId_](const MouseEvent& event) { ContainerScope scope(id); context->GetTaskExecutor()->PostTask( - [context, event]() { context->OnMouseEvent(event); }, TaskExecutor::TaskType::UI); + [context, event]() { + context->OnMouseEvent(event); + context->NotifyDispatchMouseEventDismiss(event); + }, TaskExecutor::TaskType::UI); }; aceView_->RegisterMouseEventCallback(mouseEventCallback); diff --git a/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp b/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp index 26dcb0a8..8b8c39c5 100644 --- a/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp +++ b/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp @@ -93,6 +93,19 @@ int32_t OH_NativeXComponent::GetTouchEvent(const void* window, OH_NativeXCompone return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; } +int32_t OH_NativeXComponent::GetMouseEvent(const void* window, OH_NativeXComponent_MouseEvent* mouseEvent) +{ + if (xcomponentImpl_ == nullptr) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + auto surfaceWindow = const_cast(xcomponentImpl_->GetSurface()); + if (window != surfaceWindow) { + return OH_NATIVEXCOMPONENT_RESULT_FAILED; + } + (*mouseEvent) = xcomponentImpl_->GetMouseEvent(); + return OH_NATIVEXCOMPONENT_RESULT_SUCCESS; +} + int32_t OH_NativeXComponent::RegisterCallback(OH_NativeXComponent_Callback* callback) { if (xcomponentImpl_ == nullptr) { diff --git a/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.h b/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.h index 5d5cac60..23d197ba 100644 --- a/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.h +++ b/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.h @@ -106,11 +106,21 @@ public: touchEvent_ = touchEvent; } + void SetMouseEvent(const OH_NativeXComponent_MouseEvent mouseEvent) + { + mouseEvent_ = mouseEvent; + } + const OH_NativeXComponent_TouchEvent GetTouchEvent() const { return touchEvent_; } + const OH_NativeXComponent_MouseEvent GetMouseEvent() const + { + return mouseEvent_; + } + private: std::string xcomponetId_; void* window_ = nullptr; @@ -119,6 +129,7 @@ private: double x_ = 0.0; double y_ = 0.0; OH_NativeXComponent_TouchEvent touchEvent_; + OH_NativeXComponent_MouseEvent mouseEvent_; OH_NativeXComponent_Callback* callback_ = nullptr; }; } @@ -131,6 +142,7 @@ struct OH_NativeXComponent { int32_t GetXComponentSize(const void* window, uint64_t* width, uint64_t* height); int32_t GetXComponentOffset(const void* window, double* x, double* y); int32_t GetTouchEvent(const void* window, OH_NativeXComponent_TouchEvent* touchEvent); + int32_t GetMouseEvent(const void* window, OH_NativeXComponent_MouseEvent* mouseEvent); int32_t RegisterCallback(OH_NativeXComponent_Callback* callback); private: diff --git a/frameworks/core/components/xcomponent/render_xcomponent.cpp b/frameworks/core/components/xcomponent/render_xcomponent.cpp index c28436f2..034d7de6 100644 --- a/frameworks/core/components/xcomponent/render_xcomponent.cpp +++ b/frameworks/core/components/xcomponent/render_xcomponent.cpp @@ -197,6 +197,35 @@ void RenderXComponent::NativeXComponentDispatchTouchEvent(const OH_NativeXCompon } } +void RenderXComponent::NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent& mouseEvent) +{ + auto pipelineContext = context_.Upgrade(); + if (!pipelineContext) { + LOGE("NativeXComponentDispatchTouchEvent context null"); + return; + } + float scale = pipelineContext->GetViewScale(); + float diffX = mouseEvent.x - position_.GetX() * scale; + float diffY = mouseEvent.y - position_.GetY() * scale; + if ((diffX >= 0) && (diffX <= drawSize_.Width() * scale) && (diffY >= 0) && (diffY <= drawSize_.Height() * scale)) { + pipelineContext->GetTaskExecutor()->PostTask( + [weakNXCompImpl = nativeXComponentImpl_, nXComp = nativeXComponent_, mouseEvent] { + auto nXCompImpl = weakNXCompImpl.Upgrade(); + if (nXComp != nullptr && nXCompImpl) { + nXCompImpl->SetMouseEvent(mouseEvent); + auto surface = const_cast(nXCompImpl->GetSurface()); + auto callback = nXCompImpl->GetCallback(); + if (callback != nullptr && callback->DispatchMouseEvent != nullptr) { + callback->DispatchMouseEvent(nXComp, surface); + } + } else { + LOGE("Native XComponent nullptr"); + } + }, + TaskExecutor::TaskType::JS); + } +} + void RenderXComponent::NativeXComponentOffset(const double&x, const double& y) { auto pipelineContext = context_.Upgrade(); diff --git a/frameworks/core/components/xcomponent/render_xcomponent.h b/frameworks/core/components/xcomponent/render_xcomponent.h index d6b13281..d4feddb6 100644 --- a/frameworks/core/components/xcomponent/render_xcomponent.h +++ b/frameworks/core/components/xcomponent/render_xcomponent.h @@ -61,6 +61,7 @@ public: } void NativeXComponentDispatchTouchEvent(const OH_NativeXComponent_TouchEvent& touchEvent); + void NativeXComponentDispatchMouseEvent(const OH_NativeXComponent_MouseEvent& mouseEvent); protected: RefPtr delegate_; diff --git a/frameworks/core/components/xcomponent/xcomponent_element.cpp b/frameworks/core/components/xcomponent/xcomponent_element.cpp index 2f5278c5..ba133505 100644 --- a/frameworks/core/components/xcomponent/xcomponent_element.cpp +++ b/frameworks/core/components/xcomponent/xcomponent_element.cpp @@ -59,7 +59,7 @@ void XComponentElement::Prepare(const WeakPtr& parent) xcomponent_ = AceType::DynamicCast(component_); InitEvent(); RegisterSurfaceDestroyEvent(); - RegisterDispatchTouchEventCallback(); + RegisterDispatchEventCallback(); if (xcomponent_) { if (!isExternalResource_) { CreatePlatformResource(); @@ -149,7 +149,7 @@ bool XComponentElement::IsDeclarativePara() return context->GetIsDeclarative(); } -void XComponentElement::RegisterDispatchTouchEventCallback() +void XComponentElement::RegisterDispatchEventCallback() { auto pipelineContext = context_.Upgrade(); if (!pipelineContext) { @@ -162,6 +162,12 @@ void XComponentElement::RegisterDispatchTouchEventCallback() element->DispatchTouchEvent(event); } }); + pipelineContext->SetDispatchMouseEventHandler([weak = WeakClaim(this)](const MouseEvent& event) { + auto element = weak.Upgrade(); + if (element) { + element->DispatchMousehEvent(event); + } + }); } void XComponentElement::DispatchTouchEvent(const TouchEvent& event) @@ -188,6 +194,40 @@ void XComponentElement::DispatchTouchEvent(const TouchEvent& event) } } + +void XComponentElement::DispatchMousehEvent(const MouseEvent& event) +{ + auto pipelineContext = context_.Upgrade(); + if (!pipelineContext) { + LOGE("DispatchTouchEvent pipelineContext is null"); + return; + } + auto renderXComponent = AceType::DynamicCast(renderNode_); + if (renderXComponent) { + mouseEventPoint_.x = event.x; + mouseEventPoint_.y = event.y; + mouseEventPoint_.z = event.z; + mouseEventPoint_.deltaX = event.deltaX; + mouseEventPoint_.deltaY = event.deltaY; + mouseEventPoint_.deltaZ = event.deltaZ; + mouseEventPoint_.scrollX = event.scrollX; + mouseEventPoint_.scrollY = event.scrollY; + mouseEventPoint_.scrollZ = event.scrollZ; + mouseEventPoint_.screenX = event.screenX; + mouseEventPoint_.screenY = event.screenY; + + mouseEventPoint_.action = static_cast(event.action); + mouseEventPoint_.button = static_cast(event.button); + mouseEventPoint_.pressedButtons = event.pressedButtons; + mouseEventPoint_.time = event.time.time_since_epoch().count(); + mouseEventPoint_.deviceId = event.deviceId; + mouseEventPoint_.sourceType = static_cast(event.sourceType); + mouseEventPoint_.pressedButtons = event.pressedButtons; + + renderXComponent->NativeXComponentDispatchMouseEvent(mouseEventPoint_); + } +} + void XComponentElement::SetTouchEventType(const TouchEvent& event) { switch (event.type) { diff --git a/frameworks/core/components/xcomponent/xcomponent_element.h b/frameworks/core/components/xcomponent/xcomponent_element.h index 8350c591..7025ab21 100644 --- a/frameworks/core/components/xcomponent/xcomponent_element.h +++ b/frameworks/core/components/xcomponent/xcomponent_element.h @@ -53,8 +53,9 @@ private: void SetTouchPoint(const TouchEvent& event); void OnXComponentInit(const std::string& param); void OnSurfaceInit(const std::string& componentId, const uint32_t nodeId); - void RegisterDispatchTouchEventCallback(); + void RegisterDispatchEventCallback(); void DispatchTouchEvent(const TouchEvent& event); + void DispatchMousehEvent(const MouseEvent& event); void OnXComponentSize(int64_t textureId, int32_t textureWidth, int32_t textureHeight); void OnTextureSize(int64_t textureId, std::string& result); @@ -66,6 +67,7 @@ private: InitEventCallback onXComponentInit_; DestroyEventCallback onXComponentDestroy_; OH_NativeXComponent_TouchEvent touchEventPoint_; + OH_NativeXComponent_MouseEvent mouseEventPoint_; std::string name_; std::string idStr_; bool hasSendDestroyEvent_ = false; diff --git a/frameworks/core/pipeline/pipeline_context.cpp b/frameworks/core/pipeline/pipeline_context.cpp index 4ad6ed5b..ffa42f43 100644 --- a/frameworks/core/pipeline/pipeline_context.cpp +++ b/frameworks/core/pipeline/pipeline_context.cpp @@ -2349,6 +2349,16 @@ void PipelineContext::NotifyDispatchTouchEventDismiss(const TouchEvent& event) c } } +void PipelineContext::NotifyDispatchMouseEventDismiss(const MouseEvent& event) const +{ + CHECK_RUN_ON(UI); + for (auto& iterDispatchMouseEventHander : dispatchMouseEventHandler_) { + if (iterDispatchMouseEventHander) { + iterDispatchMouseEventHander(event); + } + } +} + void PipelineContext::ShowFocusAnimation( const RRect& rrect, const Color& color, const Offset& offset, bool isIndented) const { diff --git a/frameworks/core/pipeline/pipeline_context.h b/frameworks/core/pipeline/pipeline_context.h index 3cdfedff..337fc59e 100644 --- a/frameworks/core/pipeline/pipeline_context.h +++ b/frameworks/core/pipeline/pipeline_context.h @@ -390,6 +390,13 @@ public: } void NotifyDispatchTouchEventDismiss(const TouchEvent& event) const; + using DispatchMouseEventHandler = std::function; + void SetDispatchMouseEventHandler(DispatchMouseEventHandler&& listener) + { + dispatchMouseEventHandler_.push_back(std::move(listener)); + } + void NotifyDispatchMouseEventDismiss(const MouseEvent& event) const; + float GetViewScale() const { return viewScale_; @@ -1361,6 +1368,7 @@ private: std::list isPagePathInvalidEventHandler_; std::list destroyEventHandler_; std::list dispatchTouchEventHandler_; + std::list dispatchMouseEventHandler_; RefPtr textFieldManager_; RefPtr messageBridge_; diff --git a/interfaces/native/libace.ndk.json b/interfaces/native/libace.ndk.json index 66933685..a7df5d63 100644 --- a/interfaces/native/libace.ndk.json +++ b/interfaces/native/libace.ndk.json @@ -18,5 +18,9 @@ { "first_introduced": "8", "name": "OH_NativeXComponent_GetXComponentOffset" + }, + { + "first_introduced": "8", + "name": "OH_NativeXComponent_GetMouseEvent" } ] \ No newline at end of file diff --git a/interfaces/native/native_interface_xcomponent.cpp b/interfaces/native/native_interface_xcomponent.cpp index 9bb24aa1..5179d4ea 100644 --- a/interfaces/native/native_interface_xcomponent.cpp +++ b/interfaces/native/native_interface_xcomponent.cpp @@ -60,6 +60,15 @@ int32_t OH_NativeXComponent_GetTouchEvent( return component->GetTouchEvent(window, touchEvent); } +int32_t OH_NativeXComponent_GetMouseEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent) +{ + if ((component == nullptr) || (window == nullptr) || (mouseEvent == nullptr)) { + return OH_NATIVEXCOMPONENT_RESULT_BAD_PARAMETER; + } + return component->GetMouseEvent(window, mouseEvent); +} + int32_t OH_NativeXComponent_RegisterCallback(OH_NativeXComponent* component, OH_NativeXComponent_Callback* callback) { if ((component == nullptr) || (callback == nullptr)) { diff --git a/interfaces/native/native_interface_xcomponent.h b/interfaces/native/native_interface_xcomponent.h index 41586ff3..d36996b5 100644 --- a/interfaces/native/native_interface_xcomponent.h +++ b/interfaces/native/native_interface_xcomponent.h @@ -70,6 +70,33 @@ enum OH_NativeXComponent_TouchEventType { OH_NATIVEXCOMPONENT_UNKNOWN, }; +enum OH_NativeXComponent_MouseEventAction { + OH_NATIVEXCOMPONENT_NONE = 0, + OH_NATIVEXCOMPONENT_PRESS, + OH_NATIVEXCOMPONENT_RELEASE, + OH_NATIVEXCOMPONENT_HOVER, + OH_NATIVEXCOMPONENT_HOVER_ENTER, + OH_NATIVEXCOMPONENT_HOVER_MOVE, + OH_NATIVEXCOMPONENT_HOVER_EXIT, +}; + +enum OH_NativeXComponent_MouseEventButton { + OH_NATIVEXCOMPONENT_NONE_BUTTON = 0, + OH_NATIVEXCOMPONENT_LEFT_BUTTON = 1, + OH_NATIVEXCOMPONENT_RIGHT_BUTTON = 2, + OH_NATIVEXCOMPONENT_MIDDLE_BUTTON = 4, + OH_NATIVEXCOMPONENT_BACK_BUTTON = 8, + OH_NATIVEXCOMPONENT_FORWARD_BUTTON = 16, +}; + +enum OH_NativeXComponent_SourceType : int32_t { + OH_NATIVEXCOMPONENT_SOURCETYPE_NONE = 0, + OH_NATIVEXCOMPONENT_SOURCETYPE_MOUSE = 1, + OH_NATIVEXCOMPONENT_SOURCETYPE_TOUCH = 2, + OH_NATIVEXCOMPONENT_SOURCETYPE_TOUCH_PAD = 3, + OH_NATIVEXCOMPONENT_SOURCETYPE_KEYBOARD = 4, +}; + #define OH_NATIVE_XCOMPONENT_OBJ ("__NATIVE_XCOMPONENT_OBJ__") const uint32_t OH_XCOMPONENT_ID_LEN_MAX = 128; const uint32_t OH_MAX_TOUCH_POINTS_NUMBER = 10; @@ -125,6 +152,31 @@ struct OH_NativeXComponent_TouchEvent { uint32_t numPoints = 0; }; +// Represents the mouse point information. +struct OH_NativeXComponent_MouseEvent { + /** X coordinate of the mouse point relative to the left edge of the element to mouse. */ + float x = 0.0; + /** Y coordinate of the mouse point relative to the upper edge of the element to mouse. */ + float y = 0.0; + float z = 0.0; + float deltaX = 0.0f; + float deltaY = 0.0f; + float deltaZ = 0.0f; + float scrollX = 0.0f; + float scrollY = 0.0f; + float scrollZ = 0.0f; + /** X coordinate of the mouse point relative to the left edge of the screen. */ + float screenX = 0.0; + /** Y coordinate of the mouse point relative to the upper edge of the screen. */ + float screenY = 0.0; + OH_NativeXComponent_MouseEventAction action = OH_NativeXComponent_MouseEventAction::OH_NATIVEXCOMPONENT_NONE; + OH_NativeXComponent_MouseEventButton button = OH_NativeXComponent_MouseEventButton::OH_NATIVEXCOMPONENT_NONE_BUTTON; + int32_t pressedButtons = 0; // combined by MouseButtons + int64_t time = 0; + int64_t deviceId = 0; + OH_NativeXComponent_SourceType sourceType = OH_NativeXComponent_SourceType::OH_NATIVEXCOMPONENT_SOURCETYPE_NONE; +}; + /** * @brief Provides an encapsulated OH_NativeXComponent instance. * @@ -152,6 +204,8 @@ typedef struct OH_NativeXComponent_Callback { void (*OnSurfaceDestroyed)(OH_NativeXComponent* component, void* window); /** Called when a touch event is triggered. */ void (*DispatchTouchEvent)(OH_NativeXComponent* component, void* window); + /** Called when a mouse event is triggered. */ + void (*DispatchMouseEvent)(OH_NativeXComponent* component, void* window); } OH_NativeXComponent_Callback; /** @@ -210,6 +264,19 @@ int32_t OH_NativeXComponent_GetXComponentOffset( int32_t OH_NativeXComponent_GetTouchEvent( OH_NativeXComponent* component, const void* window, OH_NativeXComponent_TouchEvent* touchEvent); +/** + * @brief Obtains the mouse event dispatched by the ArkUI XComponent. + * + * @param component Indicates the pointer to this OH_NativeXComponent instance. + * @param window Indicates the native window handler. + * @param mouseEvent Indicates the pointer to the current mouse event. + * @return Returns the status code of the execution. + * @since 8 + * @version 1.0 + */ +int32_t OH_NativeXComponent_GetMouseEvent( + OH_NativeXComponent* component, const void* window, OH_NativeXComponent_MouseEvent* mouseEvent); + /** * @brief Registers a callback for this OH_NativeXComponent instance. *