From 6ee823f406f4032043b23dcd97181fb2900cba6a Mon Sep 17 00:00:00 2001 From: hw_wyx Date: Fri, 13 Oct 2023 02:21:32 +0000 Subject: [PATCH] Fix onClickFunc and onLongPressFunc Signed-off-by: hw_wyx Change-Id: I75c6ad9a750140f42b752fc32e4eaee9ae9d02ad --- .../jsview/js_richeditor.cpp | 74 +++++++++++++++++++ .../pattern/image/image_pattern.cpp | 20 +++-- .../pattern/rich_editor/rich_editor_model.h | 4 + .../rich_editor/rich_editor_pattern.cpp | 32 ++++++-- .../pattern/rich_editor/rich_editor_pattern.h | 4 + .../components_ng/pattern/text/span_node.h | 7 ++ .../pattern/text/text_pattern.cpp | 60 ++++++++++++++- .../components_ng/pattern/text/text_pattern.h | 8 ++ 8 files changed, 196 insertions(+), 13 deletions(-) diff --git a/frameworks/bridge/declarative_frontend/jsview/js_richeditor.cpp b/frameworks/bridge/declarative_frontend/jsview/js_richeditor.cpp index 9780231ed37..14280355b3c 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_richeditor.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_richeditor.cpp @@ -15,11 +15,13 @@ #include "bridge/declarative_frontend/jsview/js_richeditor.h" +#include #include #include #include "base/log/ace_scoring_log.h" #include "bridge/common/utils/utils.h" +#include "bridge/declarative_frontend/engine/functions/js_click_function.h" #include "bridge/declarative_frontend/engine/functions/js_function.h" #include "bridge/declarative_frontend/engine/js_types.h" #include "bridge/declarative_frontend/jsview/js_container_base.h" @@ -34,6 +36,7 @@ #include "core/components_ng/pattern/rich_editor/rich_editor_model.h" #include "core/components_ng/pattern/rich_editor/rich_editor_model_ng.h" #include "core/components_ng/pattern/rich_editor/rich_editor_selection.h" +#include "core/gestures/gesture_info.h" #include "frameworks/bridge/common/utils/engine_helper.h" namespace OHOS::Ace { @@ -776,6 +779,42 @@ void JSRichEditorController::AddImageSpan(const JSCallbackInfo& args) options.imageAttribute = imageStyle; } } + if (args.Length() > 2 && args[2]->IsObject()) { + JSRef imageObject = JSRef::Cast(args[2]); + auto clickFunc = imageObject->GetProperty("onClick"); + if (clickFunc->IsUndefined() && IsDisableEventVersion()) { + options.onClick = nullptr; + } else if (!clickFunc->IsFunction()) { + options.onClick = nullptr; + } else { + auto jsOnClickFunc = AceType::MakeRefPtr(JSRef::Cast(clickFunc)); + auto onClick = [execCtx = args.GetExecutionContext(), func = jsOnClickFunc](const BaseEventInfo* info) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + const auto* clickInfo = TypeInfoHelper::DynamicCast(info); + ACE_SCORING_EVENT("TextSpan.onClick"); + func->Execute(*clickInfo); + }; + auto tmpClickFunc = [func = std::move(onClick)](GestureEvent& info) { func(&info); }; + options.onClick = std::move(tmpClickFunc); + } + + auto onLongPressFunc = imageObject->GetProperty("onLongPress"); + if (onLongPressFunc->IsUndefined() && IsDisableEventVersion()) { + options.onClick = nullptr; + } else if (!onLongPressFunc->IsFunction()) { + options.onClick = nullptr; + } else { + auto jsLongPressFunc = AceType::MakeRefPtr(JSRef::Cast(onLongPressFunc)); + auto onLongPress = [execCtx = args.GetExecutionContext(), func = jsLongPressFunc](const BaseEventInfo* info) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + const auto* longPressInfo = TypeInfoHelper::DynamicCast(info); + ACE_SCORING_EVENT("ImageSpan.onLongPress"); + func->Execute(*longPressInfo); + }; + auto tmpOnLongPressFunc = [func = std::move(onLongPress)](GestureEvent& info) { func(&info); }; + options.onLongPress = std::move(tmpOnLongPressFunc); + } + } auto controller = controllerWeak_.Upgrade(); int32_t spanIndex = 0; if (controller) { @@ -880,6 +919,41 @@ void JSRichEditorController::AddTextSpan(const JSCallbackInfo& args) } } } + if (args.Length() > 2 && args[2]->IsObject()) { + JSRef spanObject = JSRef::Cast(args[2]); + auto clickFunc = spanObject->GetProperty("onClick"); + if (clickFunc->IsUndefined() && IsDisableEventVersion()) { + options.onClick = nullptr; + } else if (!clickFunc->IsFunction()) { + options.onClick = nullptr; + } else { + auto jsOnClickFunc = AceType::MakeRefPtr(JSRef::Cast(clickFunc)); + auto onClick = [execCtx = args.GetExecutionContext(), func = jsOnClickFunc](const BaseEventInfo* info) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + const auto* clickInfo = TypeInfoHelper::DynamicCast(info); + ACE_SCORING_EVENT("Text.onClick"); + func->Execute(*clickInfo); + }; + auto tmpClickFunc = [func = std::move(onClick)](GestureEvent& info) { func(&info); }; + options.onClick = std::move(tmpClickFunc); + } + auto longPressFunc = spanObject->GetProperty("onLongPress"); + if (longPressFunc->IsUndefined() && IsDisableEventVersion()) { + options.onClick = nullptr; + } else if (!longPressFunc->IsFunction()) { + options.onClick = nullptr; + } else { + auto jsLongPressFunc = AceType::MakeRefPtr(JSRef::Cast(longPressFunc)); + auto longPress = [execCtx = args.GetExecutionContext(), func = jsLongPressFunc](const BaseEventInfo* info) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + const auto* longPressInfo = TypeInfoHelper::DynamicCast(info); + ACE_SCORING_EVENT("TextSpan.onLongPress"); + func->Execute(*longPressInfo); + }; + auto tmpLongPressFunc = [func = std::move(longPress)](GestureEvent& info) { func(&info); }; + options.onLongPress = std::move(tmpLongPressFunc); + } + } auto controller = controllerWeak_.Upgrade(); int32_t spanIndex = 0; if (controller) { diff --git a/frameworks/core/components_ng/pattern/image/image_pattern.cpp b/frameworks/core/components_ng/pattern/image/image_pattern.cpp index 877562e8184..275025d9c99 100644 --- a/frameworks/core/components_ng/pattern/image/image_pattern.cpp +++ b/frameworks/core/components_ng/pattern/image/image_pattern.cpp @@ -328,15 +328,21 @@ void ImagePattern::OnModifyDone() CHECK_NULL_VOID(host); auto gestureHub = host->GetOrCreateGestureEventHub(); - gestureHub->SetLongPressEvent(nullptr); - longPressEvent_ = nullptr; + if (longPressEvent_) { + gestureHub->SetLongPressEvent(nullptr); + longPressEvent_ = nullptr; + } - gestureHub->RemoveClickEvent(clickEvent_); - clickEvent_ = nullptr; + if (clickEvent_) { + gestureHub->RemoveClickEvent(clickEvent_); + clickEvent_ = nullptr; + } - auto inputHub = host->GetOrCreateInputEventHub(); - inputHub->RemoveOnMouseEvent(mouseEvent_); - mouseEvent_ = nullptr; + if (mouseEvent_) { + auto inputHub = host->GetOrCreateInputEventHub(); + inputHub->RemoveOnMouseEvent(mouseEvent_); + mouseEvent_ = nullptr; + } } DataReadyNotifyTask ImagePattern::CreateDataReadyCallbackForAlt() diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_model.h b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_model.h index 7c33c269a1e..c0ea76afe9e 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_model.h +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_model.h @@ -50,6 +50,8 @@ struct ImageSpanOptions { std::optional moduleName; std::optional> imagePixelMap; std::optional imageAttribute; + GestureEventFunc onClick; + GestureEventFunc onLongPress; }; struct SpanPositionInfo { @@ -131,6 +133,8 @@ struct TextSpanOptions { std::string value; std::optional style; std::optional paraStyle; + GestureEventFunc onClick; + GestureEventFunc onLongPress; }; class ACE_EXPORT RichEditorControllerBase : public AceType { diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp index c751b218931..6c01b1bf5cd 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp @@ -18,8 +18,10 @@ #include #include +#include "base/geometry/dimension.h" #include "base/geometry/ng/offset_t.h" #include "base/log/dump_log.h" +#include "base/memory/ace_type.h" #include "base/utils/string_utils.h" #include "base/utils/utils.h" #include "core/common/clipboard/paste_data.h" @@ -29,6 +31,7 @@ #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/event/event_hub.h" #include "core/components_ng/event/gesture_event_hub.h" +#include "core/components_ng/event/long_press_event.h" #include "core/components_ng/pattern/image/image_pattern.h" #include "core/components_ng/pattern/rich_editor/rich_editor_event_hub.h" #include "core/components_ng/pattern/rich_editor/rich_editor_overlay_modifier.h" @@ -211,8 +214,18 @@ int32_t RichEditorPattern::AddImageSpan(const ImageSpanOptions& options, bool is imageNode->SetDraggable(false); auto gesture = imageNode->GetOrCreateGestureEventHub(); CHECK_NULL_RETURN(gesture, -1); - gesture->SetHitTestMode(HitTestMode::HTMNONE); - + // Masked the default drag behavior of node image + gesture->SetDragEvent(nullptr, { PanDirection::DOWN }, 0, Dimension(0)); + if (options.onClick) { + auto tmpFunc = options.onClick; + gesture->SetUserOnClick(std::move(tmpFunc)); + } + if (options.onLongPress) { + auto tmpFunc = options.onLongPress; + auto tmpFuncPtr = AceType::MakeRefPtr(std::move(tmpFunc)); + gesture->SetLongPressEvent(tmpFuncPtr); + } + int32_t spanIndex = 0; int32_t offset = -1; if (options.offset.has_value()) { @@ -263,7 +276,6 @@ int32_t RichEditorPattern::AddImageSpan(const ImageSpanOptions& options, bool is host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); host->MarkModifyDone(); auto spanItem = MakeRefPtr(); - // The length of the imageSpan defaults to the length of a character to calculate the position spanItem->content = " "; AddSpanItem(spanItem, offset); @@ -344,13 +356,19 @@ int32_t RichEditorPattern::AddTextSpan(const TextSpanOptions& options, bool isPa spanItem->content = options.value; spanItem->SetTextStyle(options.style); AddSpanItem(spanItem, offset); - if (options.paraStyle) { int32_t start, end; spanItem->GetIndex(start, end); UpdateParagraphStyle(start, end, *options.paraStyle); } - + if (options.onClick) { + auto tmpFunc = options.onClick; + spanItem->SetOnClickEvent(std::move(tmpFunc)); + } + if (options.onLongPress) { + auto tmpFunc = options.onLongPress; + spanItem->SetLongPressEvent(std::move(tmpFunc)); + } if (!isPaste && textSelector_.IsValid()) { CloseSelectOverlay(); ResetSelection(); @@ -1105,6 +1123,7 @@ void RichEditorPattern::HandleClickEvent(GestureEvent& info) LOGE("request focus fail"); } } + HandleSingleClickEvent(info); } void RichEditorPattern::InitClickEvent(const RefPtr& gestureHub) @@ -1218,6 +1237,9 @@ void RichEditorPattern::HandleLongPress(GestureEvent& info) CHECK_NULL_VOID(hub); auto gestureHub = hub->GetOrCreateGestureEventHub(); CHECK_NULL_VOID(gestureHub); + if (HandleSingleLongPressEvent(info)) { + return ; + } if (BetweenSelectedPosition(info.GetGlobalLocation())) { dragBoxes_ = GetTextBoxes(); // prevent long press event from being triggered when dragging diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h index 3a6f5515d4b..1f1233f7fac 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.h @@ -174,6 +174,10 @@ public: void CreateHandles() override; void HandleOnSelectAll() override; void HandleOnCopy() override; + int32_t GetPositionForClick(const Offset& textOffset) override + { + return paragraphs_.GetIndex(textOffset); + } bool IsUsingMouse() const { diff --git a/frameworks/core/components_ng/pattern/text/span_node.h b/frameworks/core/components_ng/pattern/text/span_node.h index 7568a5ad011..d60a6937de5 100644 --- a/frameworks/core/components_ng/pattern/text/span_node.h +++ b/frameworks/core/components_ng/pattern/text/span_node.h @@ -154,6 +154,7 @@ public: std::unique_ptr fontStyle; std::unique_ptr textLineStyle; GestureEventFunc onClick; + GestureEventFunc onLongPress; [[deprecated]] std::list> children; int32_t placeHolderIndex = -1; // when paragraph ends with a \n, it causes the paragraph height to gain an extra line @@ -187,6 +188,12 @@ public: { needRemoveNewLine = value; } + void SetOnClickEvent(GestureEventFunc&& onClick_) { + onClick = std::move(onClick_); + } + void SetLongPressEvent(GestureEventFunc&& onLongPress_) { + onLongPress = std::move(onLongPress_); + } std::string GetSpanContent(); private: std::optional textStyle_; diff --git a/frameworks/core/components_ng/pattern/text/text_pattern.cpp b/frameworks/core/components_ng/pattern/text/text_pattern.cpp index 96c45ef321e..a94f9f78cff 100644 --- a/frameworks/core/components_ng/pattern/text/text_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text/text_pattern.cpp @@ -451,7 +451,38 @@ void TextPattern::HandleClickEvent(GestureEvent& info) CloseSelectOverlay(true); ResetSelection(); } + RectF textContentRect = contentRect_; + textContentRect.SetTop(contentRect_.GetY() - std::min(baselineOffset_, 0.0f)); + textContentRect.SetHeight(contentRect_.Height() - std::max(baselineOffset_, 0.0f)); + bool isClickOnSpan = false; + if (textContentRect.IsInRegion(PointF(info.GetLocalLocation().GetX(), info.GetLocalLocation().GetY())) && + !spans_.empty() && paragraph_) { + Offset textOffset = { info.GetLocalLocation().GetX() - textContentRect.GetX(), + info.GetLocalLocation().GetY() - textContentRect.GetY() }; + auto position = GetPositionForClick(textOffset); + for (const auto& item : spans_) { + if (item && position < item->position) { + if (!item->onClick) { + break; + } + GestureEvent spanClickinfo = info; + EventTarget target = info.GetTarget(); + target.area.SetWidth(Dimension(0.0f)); + target.area.SetHeight(Dimension(0.0f)); + spanClickinfo.SetTarget(target); + item->onClick(spanClickinfo); + isClickOnSpan = true; + break; + } + } + } + if (onClick_ && !isClickOnSpan) { + auto onClick = onClick_; + onClick(info); + } +} +void TextPattern::HandleSingleClickEvent(GestureEvent& info) { RectF textContentRect = contentRect_; textContentRect.SetTop(contentRect_.GetY() - std::min(baselineOffset_, 0.0f)); textContentRect.SetHeight(contentRect_.Height() - std::max(baselineOffset_, 0.0f)); @@ -460,7 +491,7 @@ void TextPattern::HandleClickEvent(GestureEvent& info) !spans_.empty() && paragraph_) { Offset textOffset = { info.GetLocalLocation().GetX() - textContentRect.GetX(), info.GetLocalLocation().GetY() - textContentRect.GetY() }; - auto position = paragraph_->GetHandlePositionForClick(textOffset); + auto position = GetPositionForClick(textOffset); for (const auto& item : spans_) { if (item && position < item->position) { if (!item->onClick) { @@ -483,6 +514,33 @@ void TextPattern::HandleClickEvent(GestureEvent& info) } } +bool TextPattern::HandleSingleLongPressEvent(GestureEvent& info) { + RectF textContentRect = contentRect_; + textContentRect.SetTop(contentRect_.GetY() - std::min(baselineOffset_, 0.0f)); + textContentRect.SetHeight(contentRect_.Height() - std::max(baselineOffset_, 0.0f)); + if (textContentRect.IsInRegion(PointF(info.GetLocalLocation().GetX(), info.GetLocalLocation().GetY())) && + !spans_.empty() && paragraph_) { + Offset textOffset = { info.GetLocalLocation().GetX() - textContentRect.GetX(), + info.GetLocalLocation().GetY() - textContentRect.GetY() }; + auto position = GetPositionForClick(textOffset); + for (const auto& item : spans_) { + if (item && position < item->position) { + if (!item->onLongPress) { + break; + } + GestureEvent spanLongPressInfo = info; + EventTarget target = info.GetTarget(); + target.area.SetWidth(Dimension(0.0f)); + target.area.SetHeight(Dimension(0.0f)); + spanLongPressInfo.SetTarget(target); + item->onLongPress(spanLongPressInfo); + return true; + } + } + } + return false; +} + void TextPattern::HandleDoubleClickEvent(GestureEvent& info) { if (copyOption_ == CopyOptions::None) { diff --git a/frameworks/core/components_ng/pattern/text/text_pattern.h b/frameworks/core/components_ng/pattern/text/text_pattern.h index ced604d49cb..d897552326d 100644 --- a/frameworks/core/components_ng/pattern/text/text_pattern.h +++ b/frameworks/core/components_ng/pattern/text/text_pattern.h @@ -187,6 +187,12 @@ public: { return true; } + + virtual int32_t GetPositionForClick(const Offset& textOffset) + { + return paragraph_->GetHandlePositionForClick(textOffset); + } + virtual void CloseSelectOverlay() override; void CloseSelectOverlay(bool animation); void CreateHandles() override; @@ -289,6 +295,8 @@ protected: virtual void HandleOnSelectAll(); void InitSelection(const Offset& pos); void HandleLongPress(GestureEvent& info); + bool HandleSingleLongPressEvent(GestureEvent& info); + void HandleSingleClickEvent(GestureEvent& info); void HandleClickEvent(GestureEvent& info); void HandleDoubleClickEvent(GestureEvent& info); bool IsDraggable(const Offset& localOffset); -- Gitee