diff --git a/frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.cpp b/frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.cpp index 39abeeaa2bee1148b8524ba0871878a59d462915..310199595184652d39c927a8fbf4bee09ec1f8a4 100644 --- a/frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.cpp +++ b/frameworks/bridge/declarative_frontend/engine/functions/js_drag_function.cpp @@ -171,6 +171,12 @@ JSRef JsDragFunction::Execute(const RefPtr& info, const std::s return JsFunction::ExecuteJS(2, params); } +JSRef JsDragFunction::Execute(const RefPtr& info){ + JSRef dragInfo = JSRef::Cast(CreateDragEvent(info)); + JSRef params[] = { dragInfo}; + return JsFunction::ExecuteJS(1, params); +} + JSRef JsDragFunction::ItemDragStartExecute(const ItemDragInfo& info, int32_t itemIndex) { JSRef itemDragInfo = JSRef::Cast(CreateItemDragInfo(info)); diff --git a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp index 516bb6dde0aaa564efb1130f4b1af93ec0a3b8d1..ffb485f9bf2e2cf7e56eee19d68835e2900731ff 100644 --- a/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp +++ b/frameworks/bridge/declarative_frontend/jsview/js_view_abstract.cpp @@ -3146,6 +3146,24 @@ void JSViewAbstract::JsOnDragEnter(const JSCallbackInfo& info) ViewAbstractModel::GetInstance()->SetOnDragEnter(std::move(onDragEnter)); } +void JSViewAbstract::JsOnDragFinsh(const JSCallbackInfo& info) +{ + std::vector checkList { JSCallbackInfoType::FUNCTION }; + if (!CheckJSCallbackInfo("JsOnDragFinsh", info, checkList)) { + return; + } + RefPtr jsOnDragFinshFunc = AceType::MakeRefPtr(JSRef::Cast(info[0])); + + auto onDragFinsh = [execCtx = info.GetExecutionContext(), func = std::move(jsOnDragEnterFunc)]( + const RefPtr& info) { + JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx); + ACE_SCORING_EVENT("onDragFinsh"); + func->Execute(info); + }; + + ViewAbstractModel::GetInstance()->SetOnDragFinsh(std::move(onDragFinsh)); +} + void JSViewAbstract::JsOnDragMove(const JSCallbackInfo& info) { std::vector checkList { JSCallbackInfoType::FUNCTION }; @@ -4000,6 +4018,7 @@ void JSViewAbstract::JSBind() JSClass::StaticMethod("onDragMove", &JSViewAbstract::JsOnDragMove); JSClass::StaticMethod("onDragLeave", &JSViewAbstract::JsOnDragLeave); JSClass::StaticMethod("onDrop", &JSViewAbstract::JsOnDrop); + JSClass::StaticMethod("onDragFinsh", &JSViewAbstract::JsOnDragFinsh); JSClass::StaticMethod("linearGradient", &JSViewAbstract::JsLinearGradient); JSClass::StaticMethod("sweepGradient", &JSViewAbstract::JsSweepGradient); diff --git a/frameworks/core/components_ng/base/view_abstract.cpp b/frameworks/core/components_ng/base/view_abstract.cpp index a239d7f6edc349b300fae7e8607d84b4f7e32413..09086a646dac3cabb46c1f4f6e075d4ab6f49b22 100644 --- a/frameworks/core/components_ng/base/view_abstract.cpp +++ b/frameworks/core/components_ng/base/view_abstract.cpp @@ -624,6 +624,17 @@ void ViewAbstract::SetOnDrop(std::function&)>&& onDragFinsh) +{ + auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->SetOnDragFinsh(std::move(onDragFinsh)); + + AddDragFrameNodeToManager(); +} + + void ViewAbstract::SetAlign(Alignment alignment) { if (!ViewStackProcessor::GetInstance()->IsCurrentVisualStateProcess()) { diff --git a/frameworks/core/components_ng/base/view_abstract.h b/frameworks/core/components_ng/base/view_abstract.h index 68159c49f3299f191dd13f3e64696fe51026f33a..e7a8b9601839564522c736fb71029b0a8f722512 100644 --- a/frameworks/core/components_ng/base/view_abstract.h +++ b/frameworks/core/components_ng/base/view_abstract.h @@ -167,6 +167,12 @@ public: std::function&, const std::string&)>&& onDragMove); static void SetOnDrop(std::function&, const std::string&)>&& onDrop); + static void SetOnDragFinsh( + std::function&)>&& onDragFinsh); + + static void SetOnDropDestination( + std::function&)>&& onDragFinsh); + // flex properties static void SetAlignSelf(FlexAlign value); static void SetFlexShrink(float value); diff --git a/frameworks/core/components_ng/components.gni b/frameworks/core/components_ng/components.gni index 7fca83de8263247a2d1f2c4255438f49af5b4516..6fa501c1548d224dbf809aa292e754adcba0609a 100644 --- a/frameworks/core/components_ng/components.gni +++ b/frameworks/core/components_ng/components.gni @@ -116,6 +116,9 @@ template("build_component_ng") { "//third_party/bounds_checking_function/include", ] + deps += [ "//foundation/graphic/graphic_2d/rosen/modules/render_service_client:librender_service_client" ] + include_dirs += [ "//foundation/graphic/graphic_2d/rosen/modules/", ] + if (defined(config.model_component_support) && config.model_component_support) { include_dirs += [ diff --git a/frameworks/core/components_ng/event/drag_event.cpp b/frameworks/core/components_ng/event/drag_event.cpp index 1d765fb66701e24ad6319308a30de8b67fead9bf..b93bd082bede4b44913c97265c0a72eba88361bc 100644 --- a/frameworks/core/components_ng/event/drag_event.cpp +++ b/frameworks/core/components_ng/event/drag_event.cpp @@ -116,6 +116,7 @@ void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, co }; panRecognizer_->SetOnActionCancel(actionCancel); + longPressRecognizer_->SetGestureHub(gestureEventHub_); std::vector> recognizers { longPressRecognizer_, panRecognizer_ }; if (!SequencedRecognizer_) { SequencedRecognizer_ = AceType::MakeRefPtr(recognizers); diff --git a/frameworks/core/components_ng/event/event_hub.h b/frameworks/core/components_ng/event/event_hub.h index 91cc6825cf80401676ffe153d6d5434807c4db93..f9d7535278e2ebea39a5332b44715c40a2271688 100644 --- a/frameworks/core/components_ng/event/event_hub.h +++ b/frameworks/core/components_ng/event/event_hub.h @@ -139,6 +139,7 @@ public: } using OnDragFunc = std::function&, const std::string&)>; + using OnNewDragFunc = std::function&)>; using OnDragStartFunc = std::function&, const std::string&)>; void SetOnDragStart(OnDragStartFunc&& onDragStart) { @@ -196,6 +197,16 @@ public: onDrop_ = std::move(onDrop); } + void SetOnDragFinsh(OnNewDragFunc&& onDragFinsh) + { + onDragFinsh_ = std::move(onDragFinsh); + } + + void SetOnDropDestination(OnNewDragFunc&& onDropDestination) + { + onDropDestination_ = std::move(onDropDestination); + } + void FireOnDrop(const RefPtr& info, const std::string& extraParams) { if (onDrop_) { @@ -275,7 +286,8 @@ private: OnDragFunc onDragLeave_; OnDragFunc onDragMove_; OnDragFunc onDrop_; - + OnNewDragFunc onDragFinsh_; + OnNewDragFunc onDropDestination_; bool enabled_ { true }; ACE_DISALLOW_COPY_AND_MOVE(EventHub); @@ -283,4 +295,4 @@ private: } // namespace OHOS::Ace::NG -#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_EVENT_HUB_H \ No newline at end of file +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_EVENT_HUB_H diff --git a/frameworks/core/components_ng/event/gesture_event_hub.cpp b/frameworks/core/components_ng/event/gesture_event_hub.cpp index 7302a637e3a0023ac5e3347e20f18daed7352a60..ce89a437c2a994b71b8fdbd68db5fe6041952ee8 100644 --- a/frameworks/core/components_ng/event/gesture_event_hub.cpp +++ b/frameworks/core/components_ng/event/gesture_event_hub.cpp @@ -348,8 +348,10 @@ void GestureEventHub::HandleOnDragStart(const GestureEvent& info) if (dragDropInfo.customNode) { dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(dragDropInfo.customNode, info); - } else { + } else if (dragDropInfo.pixelMap) { dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(dragDropInfo.pixelMap, info); + } else { + dragDropProxy_ = dragDropManager->CreateAndShowDragWindow(pixelMap_, info); } if (!dragDropProxy_) { LOGE("HandleOnDragStart: drag start error"); diff --git a/frameworks/core/components_ng/event/gesture_event_hub.h b/frameworks/core/components_ng/event/gesture_event_hub.h index c98d85635db71165a3f752846a08846c2e4b6357..f1b17e8014c0eaef5b70d041c0b891c45953a09a 100644 --- a/frameworks/core/components_ng/event/gesture_event_hub.h +++ b/frameworks/core/components_ng/event/gesture_event_hub.h @@ -306,6 +306,11 @@ public: touchable_ = touchable; } + void SetPixelMap(RefPtr pixelMap) + { + pixelMap_ = pixelMap; + } + void InitDragDropEvent(); void HandleOnDragStart(const GestureEvent& info); void HandleOnDragUpdate(const GestureEvent& info); @@ -351,6 +356,7 @@ private: bool isResponseRegion_ = false; std::vector responseRegion_; bool touchable_ = true; + RefPtr pixelMap_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/gestures/long_press_gesture.cpp b/frameworks/core/components_ng/gestures/long_press_gesture.cpp index 12aa271724427f7a3fda8462c8a7f39201fb2909..1bdfe5658ba8426f3d819264f018bc0c73cb2f1b 100644 --- a/frameworks/core/components_ng/gestures/long_press_gesture.cpp +++ b/frameworks/core/components_ng/gestures/long_press_gesture.cpp @@ -15,6 +15,7 @@ #include "core/components_ng/gestures/long_press_gesture.h" +#include "core/components_ng/event/gesture_event_hub.h" #include "core/components_ng/gestures/recognizers/long_press_recognizer.h" namespace OHOS::Ace::NG { diff --git a/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp b/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp index 7217e07e44d6790f4758df4d363e1742ba3cf316..406e40bbb70431ebb6f31b4871a8c4b64b45d7ec 100644 --- a/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp +++ b/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp @@ -22,9 +22,19 @@ #include "core/event/ace_events.h" #include "core/pipeline_ng/pipeline_context.h" +// New Headers +#include "core/components_ng/event/gesture_event_hub.h" +#include "core/components_ng/render/adapter/rosen_render_context.h" +#include "render_service_client/core/transaction/rs_interfaces.h" +#include "core/components_ng/render/render_context.h" +#include "adapter/ohos/osal/pixel_map_ohos.h" + namespace OHOS::Ace::NG { namespace { +RefPtr g_pixelMap {}; +std::mutex g_mutex; +std::condition_variable thumbnailGet; constexpr double MAX_THRESHOLD = 15.0; constexpr int32_t MAX_FINGERS = 10; } // namespace @@ -57,6 +67,59 @@ void LongPressRecognizer::OnRejected() refereeState_ = RefereeState::FAIL; } +class DrawDragThumbnailCallback : public Rosen::SurfaceCaptureCallback { +public: + void OnSurfaceCapture(std::shared_ptr pixelMap) override + { + if (pixelMap == nullptr) { + LOGE("failed to get pixelmap, return nullptr"); + return; + } + std::unique_lock lock(g_mutex); + g_pixelMap = AceType::MakeRefPtr(pixelMap); + thumbnailGet.notify_all(); + } +}; + +void LongPressRecognizer::GetThumbnailPixelMap() +{ + auto gestureHub = gestureHub_.Upgrade(); + CHECK_NULL_VOID(gestureHub); + auto frameNode = gestureHub->GetFrameNode(); + CHECK_NULL_VOID(frameNode); + auto context = frameNode->GetRenderContext(); + CHECK_NULL_VOID(context); + auto rosenRenderContext = AceType::DynamicCast(context); + CHECK_NULL_VOID(rosenRenderContext); + auto rsNode = rosenRenderContext->GetRSNode(); + CHECK_NULL_VOID(rsNode); + + std::shared_ptr drawDragThumbnailCallback = + std::make_shared(); + Rosen::RSInterfaces::GetInstance().TakeSurfaceCaptureForUI(rsNode, drawDragThumbnailCallback, 1, 1); + std::unique_lock lock(g_mutex); + thumbnailGet.wait(lock); + gestureHub->SetPixelMap(g_pixelMap); +} + +void LongPressRecognizer::ThumbnailTimer(int32_t time) +{ + auto context = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(context); + + auto&& callback = [weakPtr = AceType::WeakClaim(this)]() { + auto refPtr = weakPtr.Upgrade(); + if (refPtr) { + refPtr->GetThumbnailPixelMap(); + } else { + LOGI("fail to get thumbnail pixelMap due to context is nullptr"); + } + }; + thumbnailTimer_.Reset(callback); + auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI); + taskExecutor.PostDelayedTask(thumbnailTimer_, time); +} + void LongPressRecognizer::HandleTouchDownEvent(const TouchEvent& event) { if (IsRefereeFinished()) { @@ -96,6 +159,7 @@ void LongPressRecognizer::HandleTouchDownEvent(const TouchEvent& event) DeadlineTimer(curDuration, false); } } + ThumbnailTimer(thumbnailDeadline); } void LongPressRecognizer::HandleTouchUpEvent(const TouchEvent& /*event*/) @@ -263,4 +327,9 @@ bool LongPressRecognizer::ReconcileFrom(const RefPtr& recog return true; } + +void LongPressRecognizer::SetGestureHub(WeakPtr gestureHub) +{ + gestureHub_ = gestureHub; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.h b/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.h index 7f9055171e3e58ea14e94f188b64f36ca4faaa1f..2f0e362361e5672d1bc402fdde8c9053e903d524 100644 --- a/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.h +++ b/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.h @@ -21,6 +21,8 @@ namespace OHOS::Ace::NG { +class GestureEventHub; + class LongPressInfo : public TouchLocationInfo { DECLARE_RELATIONSHIP_OF_CLASSES(LongPressInfo, TouchLocationInfo); @@ -66,6 +68,8 @@ public: duration_ = duration; } + void SetGestureHub(WeakPtr gestureHub); + private: void HandleTouchDownEvent(const TouchEvent& event) override; void HandleTouchUpEvent(const TouchEvent& event) override; @@ -74,16 +78,21 @@ private: bool ReconcileFrom(const RefPtr& recognizer) override; void HandleOverdueDeadline(bool isCatchMode); void DeadlineTimer(int32_t time, bool isCatchMode); + void ThumbnailTimer(int32_t time); void DoRepeat(); void StartRepeatTimer(); + void GetThumbnailPixelMap(); void SendCallbackMsg(const std::unique_ptr& callback, bool isRepeat); void OnResetStatus() override; double ConvertPxToVp(double offset) const; + WeakPtr gestureHub_; OnLongPress onLongPress_; CancelableCallback deadlineTimer_; CancelableCallback timer_; + CancelableCallback thumbnailTimer_; int32_t duration_ = 500; + int32_t thumbnailDeadline = 150; bool repeat_ = false; TimeStamp time_; bool useCatchMode_ = true; diff --git a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp index 55f6043d6876e9ac937eff06794208b18750fef0..15d7db5e207ccc1a398bab3f93c91f46384173fa 100644 --- a/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp +++ b/frameworks/core/components_ng/render/adapter/rosen_render_context.cpp @@ -416,6 +416,7 @@ void RosenRenderContext::OnTransformMatrixUpdate(const Matrix4& matrix) RectF RosenRenderContext::GetPaintRectWithTransform() { RectF rect; + const float pi = 3.14159265; CHECK_NULL_RETURN(rsNode_, rect); rect = GetPaintRectWithoutTransform(); auto translate = rsNode_->GetStagingProperties().GetTranslate(); @@ -431,6 +432,25 @@ RectF RosenRenderContext::GetPaintRectWithTransform() auto oldSize = rect.GetSize(); auto newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]); rect.SetSize(newSize); + // calculate rotate + int degree = rsNode_->GetStagingProperties().GetRotation(); + + if ((abs(degree) % 180 > 45) && (abs(degree) % 180 < 135)) { + degree = 90; + OffsetF leftCornerRotate(0, 0); + OffsetF leftCorner(-1 * oldSize.Width() * scale[0] / 2, -1 * oldSize.Height() * scale[1] / 2); + leftCornerRotate.SetX( + leftCorner.GetX() * cos(degree * pi / 180) * -1 - leftCorner.GetY() * sin(degree * pi / 180) * -1); + leftCornerRotate.SetY( + leftCorner.GetX() * sin(degree * pi / 180) * -1 + leftCorner.GetY() * cos(degree * pi / 180) * -1); + OffsetF screenRotate(rect.GetX() + leftCornerRotate.GetX() - leftCorner.GetX(), + rect.GetY() + oldSize.Height() * scale[1] - leftCornerRotate.GetY() + leftCorner.GetY()); + rect.SetOffset(screenRotate); + if (abs(degree) % 180 != 0) { + newSize = SizeF(oldSize.Height() * scale[1], oldSize.Width() * scale[0]); + rect.SetSize(newSize); + } + } return rect; }