From e12aa097a5dd73093eaf53f83eac14b5b6bf93b9 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Tue, 17 Oct 2023 18:34:01 +0800 Subject: [PATCH 01/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=B8=8E=E4=B8=BB?= =?UTF-8?q?=E5=B9=B2=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I078043b6b3be4d4c309a2ff426a436860da4694d --- .../core/components_ng/event/drag_event.cpp | 4 - .../core/components_ng/manager/BUILD.gn | 1 + .../select_overlay/select_overlay_client.cpp | 214 + .../select_overlay/select_overlay_client.h | 160 + .../select_overlay/select_overlay_manager.cpp | 61 +- .../select_overlay/select_overlay_manager.h | 8 + .../select_overlay/select_overlay_proxy.cpp | 14 + .../select_overlay/select_overlay_proxy.h | 4 + .../select_overlay_scroll_notifier.h | 51 + .../core/components_ng/pattern/BUILD.gn | 3 + .../pattern/rich_editor/paragraph_manager.cpp | 18 +- .../pattern/rich_editor/paragraph_manager.h | 4 +- .../rich_editor_layout_algorithm.cpp | 2 +- .../rich_editor_layout_algorithm.h | 2 +- .../rich_editor/rich_editor_paint_method.cpp | 2 +- .../rich_editor/rich_editor_pattern.cpp | 28 +- .../pattern/rich_editor/rich_editor_pattern.h | 7 +- .../rich_editor_drag_pattern.cpp | 17 +- .../pattern/scrollable/scrollable_pattern.cpp | 6 +- .../pattern/search/search_model_ng.cpp | 91 +- .../pattern/search/search_model_ng.h | 3 + .../pattern/search/search_pattern.cpp | 3 +- .../pattern/search/search_text_field.cpp | 54 + .../pattern/search/search_text_field.h | 37 + .../select_overlay_layout_algorithm.cpp | 34 +- .../select_overlay_layout_algorithm.h | 8 + .../select_overlay/select_overlay_pattern.cpp | 22 +- .../select_overlay/select_overlay_pattern.h | 4 + .../select_overlay/select_overlay_property.h | 1 + .../components_ng/pattern/text/text_base.h | 38 +- .../pattern/text/text_content_modifier.h | 4 +- .../pattern/text/text_layout_algorithm.cpp | 24 +- .../pattern/text/text_layout_algorithm.h | 10 +- .../pattern/text/text_overlay_modifier.cpp | 6 +- .../pattern/text/text_overlay_modifier.h | 6 +- .../pattern/text/text_paint_method.cpp | 4 +- .../pattern/text/text_pattern.cpp | 120 +- .../components_ng/pattern/text/text_pattern.h | 47 +- .../components_ng/pattern/text/text_styles.h | 29 + .../text_area/text_area_layout_algorithm.cpp | 273 ++ .../text_area/text_area_layout_algorithm.h | 41 + .../pattern/text_area/text_area_pattern.h | 35 + .../pattern/text_drag/text_drag_base.h | 10 +- .../pattern/text_drag/text_drag_pattern.cpp | 37 +- .../pattern/text_drag/text_drag_pattern.h | 6 +- .../components_ng/pattern/text_field/BUILD.gn | 3 + .../pattern/text_field/content_controller.cpp | 239 ++ .../pattern/text_field/content_controller.h | 93 + .../pattern/text_field/key_event_handler.cpp | 16 +- .../text_field_accessibility_property.cpp | 15 +- .../text_field_content_modifier.cpp | 89 +- .../text_field/text_field_content_modifier.h | 7 - .../text_field_layout_algorithm.cpp | 746 +--- .../text_field/text_field_layout_algorithm.h | 76 +- .../text_field/text_field_layout_property.h | 8 +- .../text_field/text_field_model_ng.cpp | 69 +- .../text_field_overlay_modifier.cpp | 101 +- .../text_field/text_field_overlay_modifier.h | 10 +- .../text_field/text_field_paint_method.cpp | 26 +- .../text_field/text_field_paint_property.h | 2 + .../pattern/text_field/text_field_pattern.cpp | 3793 +++++------------ .../pattern/text_field/text_field_pattern.h | 470 +- .../text_field/text_input_response_area.cpp | 297 ++ .../text_field/text_input_response_area.h | 129 + .../text_field/text_select_controller.cpp | 379 ++ .../text_field/text_select_controller.h | 210 + .../pattern/text_field/text_selector.h | 20 +- .../text_input_layout_algorithm.cpp | 203 + .../text_input/text_input_layout_algorithm.h | 35 + .../render/adapter/txt_paragraph.cpp | 97 +- .../render/adapter/txt_paragraph.h | 17 +- .../core/components_ng/render/paragraph.h | 41 +- .../pattern/text/mock_overlay_modifier.cpp | 4 +- .../text/mock_text_layout_algorithm.cpp | 2 +- .../mock/pattern/text/mock_text_pattern.cpp | 6 +- .../rich_editor/rich_editor_test_ng.cpp | 2 +- .../test/pattern/text/text_test_ng.cpp | 37 +- .../pattern/textfield/textfield_test_ng.cpp | 236 +- .../inspector/inspector_constants.cpp | 1 + .../inspector/inspector_constants.h | 1 + test/mock/core/render/mock_paragraph.h | 15 +- 81 files changed, 4639 insertions(+), 4409 deletions(-) create mode 100644 frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp create mode 100644 frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h create mode 100644 frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h create mode 100644 frameworks/core/components_ng/pattern/search/search_text_field.cpp create mode 100644 frameworks/core/components_ng/pattern/search/search_text_field.h create mode 100644 frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp create mode 100644 frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h create mode 100644 frameworks/core/components_ng/pattern/text_area/text_area_pattern.h create mode 100644 frameworks/core/components_ng/pattern/text_field/content_controller.cpp create mode 100644 frameworks/core/components_ng/pattern/text_field/content_controller.h create mode 100644 frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp create mode 100644 frameworks/core/components_ng/pattern/text_field/text_input_response_area.h create mode 100644 frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp create mode 100644 frameworks/core/components_ng/pattern/text_field/text_select_controller.h create mode 100644 frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp create mode 100644 frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.h diff --git a/frameworks/core/components_ng/event/drag_event.cpp b/frameworks/core/components_ng/event/drag_event.cpp index 19a6e735f23..a287cc1e8e9 100644 --- a/frameworks/core/components_ng/event/drag_event.cpp +++ b/frameworks/core/components_ng/event/drag_event.cpp @@ -723,10 +723,6 @@ void DragEventActuator::GetTextPixelMap(bool startDrag) auto manager = pipeline->GetOverlayManager(); CHECK_NULL_VOID(manager); manager->RemovePixelMap(); - if (!startDrag) { - CHECK_NULL_VOID(pattern); - pattern->CreateHandles(); - } auto dragDropManager = pipeline->GetDragDropManager(); CHECK_NULL_VOID(dragDropManager); if (!dragDropManager->IsDragged()) { diff --git a/frameworks/core/components_ng/manager/BUILD.gn b/frameworks/core/components_ng/manager/BUILD.gn index 09c9efb95e8..b45e62932f8 100644 --- a/frameworks/core/components_ng/manager/BUILD.gn +++ b/frameworks/core/components_ng/manager/BUILD.gn @@ -20,6 +20,7 @@ build_component_ng("manager_ng") { "drag_drop/drag_drop_proxy.cpp", "full_screen/full_screen_manager.cpp", "safe_area/safe_area_manager.cpp", + "select_overlay/select_overlay_client.cpp", "select_overlay/select_overlay_manager.cpp", "select_overlay/select_overlay_proxy.cpp", "shared_overlay/shared_overlay_manager.cpp", diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp new file mode 100644 index 00000000000..4b2c097ce46 --- /dev/null +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/manager/select_overlay/select_overlay_client.h" + +#include + +#include "base/memory/ace_type.h" +#include "base/utils/utils.h" +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/pattern/scrollable/scrollable_pattern.h" +#include "core/components_v2/inspector/inspector_constants.h" +#include "core/pipeline_ng/pipeline_context.h" + +namespace OHOS::Ace::NG { + +void SelectOverlayClient::InitSelectOverlay() +{ + selectOverlayInfo_.menuCallback.onCopy = [weak = WeakClaim(this)]() { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnSelectOverlayMenuClicked(SelectOverlayMenuId::COPY); + }; + selectOverlayInfo_.menuCallback.onCut = [weak = WeakClaim(this)]() { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnSelectOverlayMenuClicked(SelectOverlayMenuId::CUT); + }; + selectOverlayInfo_.menuCallback.onSelectAll = [weak = WeakClaim(this)]() { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnSelectOverlayMenuClicked(SelectOverlayMenuId::SELECT_ALL); + }; + selectOverlayInfo_.menuCallback.onPaste = [weak = WeakClaim(this)]() { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnSelectOverlayMenuClicked(SelectOverlayMenuId::PASTE); + }; + selectOverlayInfo_.onHandleMoveStart = [weak = WeakClaim(this)](bool isFirst) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnHandleMoveStart(isFirst); + }; + selectOverlayInfo_.onHandleMove = [weak = WeakClaim(this)](const RectF& rect, bool isFirst) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnHandleMove(rect, isFirst); + }; + selectOverlayInfo_.onHandleMoveDone = [weak = WeakClaim(this)](const RectF& rect, bool isFirst) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnHandleMoveDone(rect, isFirst); + }; + selectOverlayInfo_.onClose = [weak = WeakClaim(this)](bool closedByGlobalEvent) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnHandleClosed(closedByGlobalEvent); + }; + selectOverlayInfo_.callerFrameNode = GetClientHost(); + selectOverlayInfo_.firstHandle.isShow = false; + selectOverlayInfo_.secondHandle.isShow = false; +} + +void SelectOverlayClient::RequestOpenSelectOverlay(ClientOverlayInfo showOverlayInfo) +{ + LOGI("RequestOpenSelectOverlay start, has first handle %{public}d, has second handle %{public}d", + showOverlayInfo.firstHandleInfo.has_value(), showOverlayInfo.secondHandleInfo.has_value()); + auto firstHandleInfo = showOverlayInfo.firstHandleInfo; + auto secondHandleInfo = showOverlayInfo.secondHandleInfo; + HandleShowMode showMode; + if (firstHandleInfo.has_value() && secondHandleInfo.has_value()) { + showMode = HandleShowMode::DOUBLE; + firstHandleInfo->isShow = CheckHandleVisible(firstHandleInfo->paintRect); + secondHandleInfo->isShow = CheckHandleVisible(secondHandleInfo->paintRect); + } else if (!firstHandleInfo.has_value() && secondHandleInfo.has_value()) { + showMode = HandleShowMode::SINGLE; + secondHandleInfo->isShow = CheckHandleVisible(secondHandleInfo->paintRect); + } else { + showMode = HandleShowMode::NONE; + } + if (!selectOverlayProxy_ || selectOverlayProxy_->IsClosed()) { + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + SelectOverlayInfo overlayInfo = selectOverlayInfo_; + if (showOverlayInfo.overlayInfoModifier) { + showOverlayInfo.overlayInfoModifier(overlayInfo); + } + overlayInfo.firstHandle = firstHandleInfo.has_value() ? *firstHandleInfo : overlayInfo.firstHandle; + overlayInfo.secondHandle = secondHandleInfo.has_value() ? *secondHandleInfo : overlayInfo.secondHandle; + overlayInfo.isSingleHandle = showMode == HandleShowMode::SINGLE; + overlayInfo.isSelectRegionVisible = CheckSelectionRectVisible(); + if (!GetMenuOptionItems().empty()) { + overlayInfo.menuOptionItems = GetMenuOptionItems(); + } + if (!OnPreShowSelectOverlay(overlayInfo, showOverlayInfo.extraInfo)) { + return; + } + LOGD("first handle visibility %{public}d, second handle visibility %{public}d, select rect visibility " + "%{public}d", + overlayInfo.firstHandle.isShow, overlayInfo.secondHandle.isShow, overlayInfo.isSelectRegionVisible); + selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( + overlayInfo, WeakClaim(this), showOverlayInfo.animation); + StartListeningScrollableParent(GetClientHost()); + return; + } + if (showMode == HandleShowMode::DOUBLE) { + selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(*firstHandleInfo, *secondHandleInfo); + return; + } + if (showMode == HandleShowMode::SINGLE) { + selectOverlayProxy_->UpdateSecondSelectHandleInfo(*secondHandleInfo); + } +} + +void SelectOverlayClient::RequestCloseSelectOverlay(bool animation) +{ + StopListeningScrollableParent(GetClientHost()); + if (selectOverlayProxy_ && !selectOverlayProxy_->IsClosed()) { + selectOverlayProxy_->Close(animation); + } +} + +bool SelectOverlayClient::SelectOverlayIsOn() +{ + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_RETURN(pipeline, false); + CHECK_NULL_RETURN(selectOverlayProxy_, false); + auto overlayId = selectOverlayProxy_->GetSelectOverlayId(); + return pipeline->GetSelectOverlayManager()->HasSelectOverlay(overlayId); +} + +void SelectOverlayClient::UpdateSelectInfo(const std::string& selectInfo) +{ + auto selectOverlay = GetSelectOverlayProxy(); + CHECK_NULL_VOID(selectOverlay); + selectOverlay->SetSelectInfo(selectInfo); +} + +void SelectOverlayClient::UpdateSelectMenuInfo(std::function updateAction) +{ + auto selectOverlay = GetSelectOverlayProxy(); + CHECK_NULL_VOID(selectOverlay); + selectOverlay->UpdateSelectMenuInfo(updateAction); +} + +void SelectOverlayClient::UpdateSelectMenuVisibility(bool isVisible) +{ + auto selectOverlay = GetSelectOverlayProxy(); + CHECK_NULL_VOID(selectOverlay); + selectOverlay->ShowOrHiddenMenu(!isVisible); +} + +void SelectOverlayClient::StartListeningScrollableParent(const RefPtr& host) +{ + if (!scrollableParentInfo_.hasParent) { + LOGI("has no scrollable parent"); + return; + } + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + auto registerScrollCallback = [&](int32_t parentId, int32_t callbackId) { + if (!scrollCallback_) { + scrollCallback_ = [weak = WeakClaim(this)](bool isEnd) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + client->OnParentScrollCallback(isEnd); + }; + } + context->GetSelectOverlayManager()->RegisterScrollCallback(parentId, callbackId, std::move(scrollCallback_)); + }; + if (scrollableParentInfo_.parentIds.empty()) { + auto parent = host->GetParent(); + while (parent && parent->GetTag() != V2::PAGE_ETS_TAG) { + auto parentNode = AceType::DynamicCast(parent); + if (parentNode) { + auto pattern = parentNode->GetPattern(); + if (pattern) { + scrollableParentInfo_.parentIds.emplace_back(parentNode->GetId()); + registerScrollCallback(parentNode->GetId(), host->GetId()); + } + } + parent = parent->GetParent(); + } + scrollableParentInfo_.hasParent = !scrollableParentInfo_.parentIds.empty(); + LOGI("find scrollable parent %{public}d", scrollableParentInfo_.hasParent); + } else { + for (const auto& scrollId : scrollableParentInfo_.parentIds) { + registerScrollCallback(scrollId, host->GetId()); + } + } +} + +void SelectOverlayClient::StopListeningScrollableParent(const RefPtr& host) +{ + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + context->GetSelectOverlayManager()->RemoveScrollCallback(host->GetId()); +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h new file mode 100644 index 00000000000..cbac38c20fb --- /dev/null +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_CLIENT_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_CLIENT_H + +#include +#include +#include + +#include "base/geometry/offset.h" +#include "base/memory/ace_type.h" +#include "base/memory/referenced.h" +#include "core/components_ng/base/frame_node.h" +#include "core/components_ng/manager/select_overlay/select_overlay_proxy.h" +#include "core/components_ng/manager/select_overlay/selection_host.h" +#include "core/components_ng/pattern/select_overlay/select_overlay_property.h" +#include "core/pipeline_ng/pipeline_context.h" + +namespace OHOS::Ace::NG { + +enum class HandleShowMode { DOUBLE, SINGLE, NONE }; + +using ParentScrollableCallback = std::function; + +struct OverlayExtraInfo { + std::map boolExtra; + + bool GetBoolOrDefault(std::string key, bool defaultValue) + { + auto it = boolExtra.find(key); + if (it == boolExtra.end()) { + return defaultValue; + } + return it->second; + }; +}; + +struct ClientOverlayInfo { + std::optional firstHandleInfo; + std::optional secondHandleInfo; + bool animation = true; + bool isMenuShow = true; + std::function overlayInfoModifier; + OverlayExtraInfo extraInfo; +}; + +struct ScrollableParentInfo { + bool hasParent = true; + std::vector parentIds; +}; + +enum class SelectOverlayMenuId { + COPY, + CUT, + PASTE, + SELECT_ALL +}; + +class SelectOverlayClient : public SelectionHost { + DECLARE_ACE_TYPE(SelectOverlayClient, SelectionHost); + +public: + void InitSelectOverlay(); + void RequestOpenSelectOverlay(ClientOverlayInfo overlayInfo); + virtual void RequestCloseSelectOverlay(bool animation); + bool SelectOverlayIsOn(); + + virtual bool CheckHandleVisible(const RectF& paintRect) + { + return true; + } + + virtual bool CheckSelectionRectVisible() + { + return false; + } + + virtual bool OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extraInfo) + { + return false; + } + + virtual void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) {} + virtual void OnHandleMoveStart(bool isFirst) {} + virtual void OnHandleMove(const RectF&, bool isFirst) {} + virtual void OnHandleMoveDone(const RectF&, bool isFirst) {} + virtual void OnHandleClosed(bool closedByGlobalEvent) + { + if (closedByGlobalEvent) { + StopListeningScrollableParent(GetClientHost()); + } + } + + virtual RefPtr GetClientHost() const = 0; + void UpdateSelectInfo(const std::string& selectInfo); + + void SetMenuOptionItems(std::vector&& menuOptionItems) + { + menuOptionItems_ = std::move(menuOptionItems); + } + + const std::vector&& GetMenuOptionItems() const + { + return std::move(menuOptionItems_); + } + + virtual void OnParentScrollCallback(bool isEnd) + { + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + if (isEnd) { + proxy->ShowOrHiddenMenu(false); + } else { + proxy->ShowOrHiddenMenu(true); + } + } + + void StartListeningScrollableParent(const RefPtr& host); + + void StopListeningScrollableParent(const RefPtr& host); + + void UpdateSelectMenuInfo(std::function updateAction); + + void UpdateSelectMenuVisibility(bool isVisible); + +protected: + const RefPtr& GetSelectOverlayProxy() + { + return selectOverlayProxy_; + } + + void ResetSelectOverlayClient() + { + scrollableParentInfo_.hasParent = true; + scrollableParentInfo_.parentIds.clear(); + } + +private: + ParentScrollableCallback scrollCallback_; + ScrollableParentInfo scrollableParentInfo_; + SelectOverlayInfo selectOverlayInfo_; + RefPtr selectOverlayProxy_; + std::vector menuOptionItems_; +}; + +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_CLIENT_H \ No newline at end of file diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp index 887037b3e33..365cb39ae1f 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp @@ -48,13 +48,12 @@ RefPtr SelectOverlayManager::CreateAndShowSelectOverlay( auto taskExecutor = Container::CurrentTaskExecutor(); taskExecutor->PostTask( - [weakRoot = rootNodeWeak_, weakNode = AceType::WeakClaim(AceType::RawPtr(selectOverlayNode)), animation, + [weakRoot = rootNodeWeak_, overlayNode = selectOverlayNode, animation, isUsingMouse = infoPtr->isUsingMouse, weak = WeakClaim(this), weakCaller = infoPtr->callerFrameNode] { auto selectOverlayManager = weak.Upgrade(); CHECK_NULL_VOID(selectOverlayManager); - auto selectOverlayNode = weakNode.Upgrade(); - CHECK_NULL_VOID(selectOverlayNode); - if (weakNode != selectOverlayManager->GetSelectOverlayItem()) { + CHECK_NULL_VOID(overlayNode); + if (overlayNode != selectOverlayManager->GetSelectOverlayItem()) { LOGD("current selectOverlayItem not is %{public}d", selectOverlayNode->GetId()); return; } @@ -65,7 +64,6 @@ RefPtr SelectOverlayManager::CreateAndShowSelectOverlay( rootNode = DynamicCast(root); } CHECK_NULL_VOID(rootNode); - // get keyboard index to put selet_overlay before keyboard node int32_t slot = DEFAULT_NODE_SLOT; int32_t index = 0; @@ -77,10 +75,10 @@ RefPtr SelectOverlayManager::CreateAndShowSelectOverlay( index++; } - selectOverlayNode->MountToParent(rootNode, slot); + overlayNode->MountToParent(rootNode, slot); rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); if (!isUsingMouse) { - auto node = DynamicCast(selectOverlayNode); + auto node = DynamicCast(overlayNode); CHECK_NULL_VOID(node); node->ShowSelectOverlay(animation); } @@ -340,4 +338,53 @@ void SelectOverlayManager::MarkDirty(PropertyChangeFlag flag) selectOverlayItem->MarkDirtyNode(flag); } } + +void SelectOverlayManager::NotifyOnScrollCallback(int32_t id, bool isEnd) +{ + LOGI("NotifyOnScrollCallback scroll id %{public}d", id); + if (parentScrollCallbacks_.empty()) { + return; + } + auto it = parentScrollCallbacks_.find(id); + if (it == parentScrollCallbacks_.end()) { + return; + } + auto callbackMap = it->second; + if (callbackMap.empty()) { + parentScrollCallbacks_.erase(id); + return; + } + for (const auto& pair : callbackMap) { + pair.second(isEnd); + } +} + +void SelectOverlayManager::RegisterScrollCallback( + int32_t scrollableParentId, int32_t callbackId, std::function&& callback) +{ + LOGI("RegisterScrollCallback scroll parent id %{public}d, callbackId %{public}d", scrollableParentId, callbackId); + auto it = parentScrollCallbacks_.find(scrollableParentId); + if (it == parentScrollCallbacks_.end()) { + std::map> callbackMap = { { callbackId, std::move(callback) } }; + parentScrollCallbacks_.insert(std::make_pair(scrollableParentId, callbackMap)); + } else { + it->second.insert(std::make_pair(callbackId, std::move(callback))); + } +} + +void SelectOverlayManager::RemoveScrollCallback(int32_t callbackId) +{ + LOGI("RemoveScrollCallback callbackId %{public}d", callbackId); + if (parentScrollCallbacks_.empty()) { + return; + } + for (auto it = parentScrollCallbacks_.begin(); it != parentScrollCallbacks_.end();) { + it->second.erase(callbackId); + if (it->second.empty()) { + it = parentScrollCallbacks_.erase(it); + } else { + ++it; + } + } +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h index f5e742c4478..92edbdaef88 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h @@ -73,6 +73,12 @@ public: return selectOverlayItem_; } + void NotifyOnScrollCallback(int32_t id, bool isEnd); + + void RegisterScrollCallback(int32_t scrollableParentId, int32_t callbackId, std::function&& callback); + + void RemoveScrollCallback(int32_t callbackId); + private: void DestroyHelper(const RefPtr& overlay, bool animation = false); @@ -94,6 +100,8 @@ private: std::vector touchDownPoints_; std::vector touchTestResults_; + std::map>> parentScrollCallbacks_; + ACE_DISALLOW_COPY_AND_MOVE(SelectOverlayManager); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp index 73025c60b4f..465f62c81dd 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp @@ -66,6 +66,13 @@ void SelectOverlayProxy::UpdateSelectMenuInfo(const SelectMenuInfo& info) const pattern->UpdateSelectMenuInfo(info); } +void SelectOverlayProxy::UpdateSelectMenuInfo(std::function updateAction) const +{ + auto pattern = GetSelectOverlayPattern(selectOverlayId_); + CHECK_NULL_VOID(pattern); + pattern->UpdateSelectMenuInfo(updateAction); +} + void SelectOverlayProxy::UpdateShowArea(const RectF& area) const { auto pattern = GetSelectOverlayPattern(selectOverlayId_); @@ -73,6 +80,13 @@ void SelectOverlayProxy::UpdateShowArea(const RectF& area) const pattern->UpdateShowArea(area); } +void SelectOverlayProxy::SetSelectRegionVisible(bool isSelectRegionVisible) +{ + auto pattern = GetSelectOverlayPattern(selectOverlayId_); + CHECK_NULL_VOID(pattern); + pattern->SetSelectRegionVisible(isSelectRegionVisible); +} + void SelectOverlayProxy::SetHandleReverse(bool reverse) { auto pattern = GetSelectOverlayPattern(selectOverlayId_); diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h index f76004b4cf3..7de93856245 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h @@ -42,8 +42,12 @@ public: void UpdateSelectMenuInfo(const SelectMenuInfo& info) const; + void UpdateSelectMenuInfo(std::function updateAction) const; + void UpdateShowArea(const RectF& area) const; + void SetSelectRegionVisible(bool isSelectRegionVisible); + void SetHandleReverse(bool reverse); bool IsClosed() const; diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h new file mode 100644 index 00000000000..88d0ac410b9 --- /dev/null +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_SCROLL_NOTIFIER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_SCROLL_NOTIFIER_H + +#include "core/components_ng/pattern/pattern.h" +#include "core/components_ng/pattern/scrollable/scrollable_properties.h" +#include "core/pipeline_ng/pipeline_context.h" + +namespace OHOS::Ace::NG { +class SelectOverlayScrollNotifier { + +public: + static inline void NotifyOnScrollCallback(WeakPtr pattern, float offset, int32_t source) + { + if (source == SCROLL_FROM_START) { + NotifyOnScrollEvent(pattern, false); + } + } + + static inline void NotifyOnScrollEnd(WeakPtr pattern) + { + NotifyOnScrollEvent(pattern, true); + } + + static inline void NotifyOnScrollEvent(WeakPtr pattern, bool isEnd) + { + auto scrollablePattern = pattern.Upgrade(); + CHECK_NULL_VOID(scrollablePattern); + auto host = scrollablePattern->GetHost(); + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + context->GetSelectOverlayManager()->NotifyOnScrollCallback(host->GetId(), isEnd); + } +}; +} // namespace OHOS::Ace::NG +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_SCROLL_NOTIFIER_H diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index ac198e2cf65..4699ebe707a 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -330,6 +330,7 @@ build_component_ng("pattern_ng") { "search/search_node.cpp", "search/search_paint_method.cpp", "search/search_pattern.cpp", + "search/search_text_field.cpp", "select/select_accessibility_property.cpp", "select/select_layout_algorithm.cpp", "select/select_model_ng.cpp", @@ -436,6 +437,8 @@ build_component_ng("pattern_ng") { "text_picker/textpicker_pattern.cpp", "text_picker/textpicker_row_accessibility_property.cpp", "text_picker/toss_animation_controller.cpp", + "text_area/text_area_layout_algorithm.cpp", + "text_input/text_input_layout_algorithm.cpp", "texttimer/text_timer_accessibility_property.cpp", "texttimer/text_timer_layout_algorithm.cpp", "texttimer/text_timer_layout_property.cpp", diff --git a/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.cpp b/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.cpp index a5be007fede..3928c116eb5 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.cpp @@ -41,18 +41,18 @@ int32_t ParagraphManager::GetIndex(Offset offset) const // get offset relative to each paragraph offset.SetY(offset.GetY() - info.paragraph->GetHeight()); } else { - return info.paragraph->GetHandlePositionForClick(offset) + info.start; + return info.paragraph->GetGlyphIndexByCoordinate(offset) + info.start; } } - return paragraphs_.back().paragraph->GetHandlePositionForClick(offset) + paragraphs_.back().start; + return paragraphs_.back().paragraph->GetGlyphIndexByCoordinate(offset) + paragraphs_.back().start; } -std::vector ParagraphManager::GetRects(int32_t start, int32_t end) const +std::vector ParagraphManager::GetRects(int32_t start, int32_t end) const { - std::vector res; + std::vector res; float y = 0.0f; for (auto&& info : paragraphs_) { - std::vector rects; + std::vector rects; if (info.start > end) { break; } @@ -70,12 +70,12 @@ std::vector ParagraphManager::GetRects(int32_t start, int32_t end) const return res; } -std::vector ParagraphManager::GetPlaceholderRects() const +std::vector ParagraphManager::GetPlaceholderRects() const { - std::vector res; + std::vector res; float y = 0.0f; for (auto&& info : paragraphs_) { - std::vector rects; + std::vector rects; info.paragraph->GetRectsForPlaceholders(rects); for (auto& rect : rects) { rect.SetTop(rect.Top() + y); @@ -109,7 +109,7 @@ OffsetF ParagraphManager::ComputeCursorOffset(int32_t index, float& selectLineHe int32_t relativeIndex = index - it->start; auto&& paragraph = it->paragraph; - CaretMetrics metrics; + CaretMetricsF metrics; auto computeSuccess = paragraph->ComputeOffsetForCaretDownstream(relativeIndex, metrics) || paragraph->ComputeOffsetForCaretUpstream(relativeIndex, metrics); CHECK_NULL_RETURN(computeSuccess, OffsetF(0.0f, y)); diff --git a/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.h b/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.h index 20653e84609..884f151b3bf 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.h +++ b/frameworks/core/components_ng/pattern/rich_editor/paragraph_manager.h @@ -44,8 +44,8 @@ public: } void Reset(); - std::vector GetRects(int32_t start, int32_t end) const; - std::vector GetPlaceholderRects() const; + std::vector GetRects(int32_t start, int32_t end) const; + std::vector GetPlaceholderRects() const; OffsetF ComputeCursorOffset(int32_t index, float& selectLineHeight) const; void AddParagraph(ParagraphInfo&& info) diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.cpp index 84d16843254..120878948cb 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.cpp @@ -125,7 +125,7 @@ void RichEditorLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) TextLayoutAlgorithm::Layout(layoutWrapper); } -void RichEditorLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) +void RichEditorLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) { rects = pManager_->GetPlaceholderRects(); } diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.h b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.h index 60888d2eb44..1b2a2b8eaf4 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_layout_algorithm.h @@ -40,7 +40,7 @@ public: void Measure(LayoutWrapper* layoutWrapper) override; private: - void GetPlaceholderRects(std::vector& rects) override; + void GetPlaceholderRects(std::vector& rectF) override; int32_t GetPreviousLength() const override; ParagraphStyle GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const override; diff --git a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_paint_method.cpp b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_paint_method.cpp index aa03d50bf08..841ea120483 100644 --- a/frameworks/core/components_ng/pattern/rich_editor/rich_editor_paint_method.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor/rich_editor_paint_method.cpp @@ -53,7 +53,7 @@ void RichEditorPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper) overlayMod->SetCaretOffsetAndHeight( OffsetF(rect.GetX(), rect.GetY()), Dimension(DEFAULT_CARET_HEIGHT, DimensionUnit::VP).ConvertToPx()); } - std::vector selectedRects; + std::vector selectedRects; const auto& selection = richEditorPattern->GetTextSelector(); if (richEditorPattern->GetTextContentLength() > 0 && selection.GetTextStart() != selection.GetTextEnd()) { selectedRects = pManager_->GetRects(selection.GetTextStart(), selection.GetTextEnd()); 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 c53b73b36d9..cd5eb52ee13 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 @@ -2482,7 +2482,7 @@ void RichEditorPattern::HandleMouseLeftButton(const MouseInfo& info) mouseStatus_ = MouseStatus::MOVE; if (isFirstMouseSelect_) { int32_t extend = paragraphs_.GetIndex(textOffset); - int32_t extendEnd = extend + GetGraphemeClusterLength(extend); + int32_t extendEnd = extend + GetGraphemeClusterLength(GetWideText(), extend); textSelector_.Update(extend, extendEnd); isFirstMouseSelect_ = false; } else { @@ -3309,7 +3309,7 @@ bool RichEditorPattern::BetweenSelectedPosition(const Offset& globalOffset) auto panOffset = OffsetF(localOffset.GetX(), localOffset.GetY()) - contentRect_.GetOffset() + OffsetF(0.0, std::min(baselineOffset_, 0.0f)); for (const auto& selectedRect : selectedRects) { - if (selectedRect.IsInRegion(Point(panOffset.GetX(), panOffset.GetY()))) { + if (selectedRect.IsInRegion(PointF(panOffset.GetX(), panOffset.GetY()))) { return true; } } @@ -3371,7 +3371,7 @@ void RichEditorPattern::InitSelection(const Offset& pos) { int32_t currentPosition = paragraphs_.GetIndex(pos); currentPosition = std::min(currentPosition, GetTextContentLength()); - int32_t nextPosition = currentPosition + GetGraphemeClusterLength(currentPosition); + int32_t nextPosition = currentPosition + GetGraphemeClusterLength(GetWideText(), currentPosition); nextPosition = std::min(nextPosition, GetTextContentLength()); textSelector_.Update(currentPosition, nextPosition); auto selectedRects = paragraphs_.GetRects(currentPosition, nextPosition); @@ -3453,28 +3453,6 @@ int32_t RichEditorPattern::GetHandleIndex(const Offset& offset) const return paragraphs_.GetIndex(offset); } -#ifndef USE_GRAPHIC_TEXT_GINE -std::vector RichEditorPattern::GetTextBoxes() -#else -std::vector RichEditorPattern::GetTextBoxes() -#endif -{ - auto selectedRects = paragraphs_.GetRects(textSelector_.GetTextStart(), textSelector_.GetTextEnd()); -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector res; -#else - std::vector res; -#endif - res.reserve(selectedRects.size()); - for (auto&& rect : selectedRects) { - if (NearZero(rect.Width())) { - continue; - } - res.emplace_back(ConvertRect(rect)); - } - return res; -} - float RichEditorPattern::GetLineHeight() const { auto selectedRects = paragraphs_.GetRects(textSelector_.GetTextStart(), textSelector_.GetTextEnd()); 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 d39ee25fcb8..d6ad1715046 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 @@ -243,11 +243,6 @@ public: void OnColorConfigurationUpdate() override {} bool IsDisabled() const; float GetLineHeight() const override; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector GetTextBoxes() override; -#else - std::vector GetTextBoxes() override; -#endif private: void UpdateSelectMenuInfo(bool hasData, SelectOverlayInfo& selectInfo, bool isCopyAll) @@ -391,7 +386,7 @@ private: #endif // ENABLE_DRAG_FRAMEWORK std::map, std::shared_ptr> selectionMenuMap_; std::optional selectedType_; - + std::function customKeyboardBuilder_; ACE_DISALLOW_COPY_AND_MOVE(RichEditorPattern); diff --git a/frameworks/core/components_ng/pattern/rich_editor_drag/rich_editor_drag_pattern.cpp b/frameworks/core/components_ng/pattern/rich_editor_drag/rich_editor_drag_pattern.cpp index 321d3403b82..9c8c541d9ec 100644 --- a/frameworks/core/components_ng/pattern/rich_editor_drag/rich_editor_drag_pattern.cpp +++ b/frameworks/core/components_ng/pattern/rich_editor_drag/rich_editor_drag_pattern.cpp @@ -60,7 +60,7 @@ RefPtr RichEditorDragPattern::CreateDragNode( auto rectsForPlaceholders = richEditor->GetRectsForPlaceholders(); size_t index = 0; - std::vector realRectsForPlaceholders; + std::vector realRectsForPlaceholders; std::list> realImageChildren; auto boxes = hostPattern->GetTextBoxes(); for (const auto& child : imageChildren) { @@ -68,24 +68,15 @@ RefPtr RichEditorDragPattern::CreateDragNode( auto rect = rectsForPlaceholders.at(imageIndex); for (const auto& box : boxes) { -#ifndef USE_GRAPHIC_TEXT_GINE - if (LessOrEqual(box.rect_.GetLeft(), rect.Left()) && GreatOrEqual(box.rect_.GetRight(), rect.Right()) && - LessOrEqual(box.rect_.GetTop(), rect.Top()) && GreatOrEqual(box.rect_.GetBottom(), rect.Bottom())) { -#else - if (LessOrEqual(box.rect.GetLeft(), rect.Left()) && GreatOrEqual(box.rect.GetRight(), rect.Right()) && - LessOrEqual(box.rect.GetTop(), rect.Top()) && GreatOrEqual(box.rect.GetBottom(), rect.Bottom())) { -#endif + if (LessOrEqual(box.Left(), rect.Left()) && GreatOrEqual(box.Right(), rect.Right()) && + LessOrEqual(box.Top(), rect.Top()) && GreatOrEqual(box.Bottom(), rect.Bottom())) { realImageChildren.emplace_back(child); realRectsForPlaceholders.emplace_back(rect); } } ++index; } -#ifndef USE_GRAPHIC_TEXT_GINE - dragPattern->SetLastLineHeight(boxes.back().rect_.GetHeight()); -#else - dragPattern->SetLastLineHeight(boxes.back().rect.GetHeight()); -#endif + dragPattern->SetLastLineHeight(boxes.back().Height()); dragPattern->InitSpanImageLayout(realImageChildren, realRectsForPlaceholders); return dragNode; } diff --git a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp index 2dd4cd82df7..242003f64f1 100644 --- a/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp +++ b/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp @@ -22,6 +22,7 @@ #include "core/common/container.h" #include "core/components/common/layout/constants.h" #include "core/components/scroll/scrollable.h" +#include "core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h" #include "core/components_ng/pattern/scroll/effect/scroll_fade_effect.h" #include "core/components_ng/pattern/scroll/scroll_spring_effect.h" #include "core/components_ng/pattern/scrollable/nestable_scroll_container.h" @@ -248,6 +249,7 @@ void ScrollablePattern::OnScrollEnd() } OnScrollEndCallback(); + SelectOverlayScrollNotifier::NotifyOnScrollEnd(WeakClaim(this)); } void ScrollablePattern::AddScrollEvent() @@ -1186,7 +1188,9 @@ bool ScrollablePattern::HandleScrollImpl(float offset, int32_t source) if (!OnScrollPosition(offset, source)) { return false; } - return OnScrollCallback(offset, source); + auto result = OnScrollCallback(offset, source); + SelectOverlayScrollNotifier::NotifyOnScrollCallback(WeakClaim(this), offset, source); + return result; } void ScrollablePattern::NotifyMoved(bool value) diff --git a/frameworks/core/components_ng/pattern/search/search_model_ng.cpp b/frameworks/core/components_ng/pattern/search/search_model_ng.cpp index 86d88239a80..06c61eae567 100644 --- a/frameworks/core/components_ng/pattern/search/search_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/search/search_model_ng.cpp @@ -15,6 +15,7 @@ #include "core/components_ng/pattern/search/search_model_ng.h" +#include "base/utils/utils.h" #include "core/components/common/properties/color.h" #include "core/components/search/search_theme.h" #include "core/components/theme/icon_theme.h" @@ -24,6 +25,7 @@ #include "core/components_ng/pattern/button/button_pattern.h" #include "core/components_ng/pattern/image/image_pattern.h" #include "core/components_ng/pattern/search/search_pattern.h" +#include "core/components_ng/pattern/search/search_text_field.h" #include "core/components_ng/pattern/text/text_pattern.h" #include "core/components_ng/pattern/text_field/text_field_event_hub.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" @@ -76,7 +78,7 @@ RefPtr SearchModelNG::Create(const std::optionalSetSearchController(AceType::MakeRefPtr()); auto textFieldFrameNode = AceType::DynamicCast(frameNode->GetChildAtIndex(TEXTFIELD_INDEX)); auto textFieldPattern = textFieldFrameNode->GetPattern(); - pattern->UpdateChangeEvent(textFieldPattern->GetTextEditingValue().text); + pattern->UpdateChangeEvent(textFieldPattern->GetTextValue()); return pattern->GetSearchController(); } @@ -479,11 +481,21 @@ void SearchModelNG::SetOnSubmit(std::function&& onSubm void SearchModelNG::SetOnChange(std::function&& onChange) { - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - CHECK_NULL_VOID(frameNode); - auto eventHub = frameNode->GetEventHub(); + auto searchTextField = GetSearchTextFieldFrameNode(); + CHECK_NULL_VOID(searchTextField); + auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - eventHub->SetOnChange(std::move(onChange)); + auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), onChange]( + const std::string& value) { + if (onChange) { + onChange(value); + } + auto node = weak.Upgrade(); + if (node) { + node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + }; + eventHub->SetOnChange(std::move(searchChangeFunc)); } void SearchModelNG::SetOnTextSelectionChange(std::function&& func) @@ -522,23 +534,49 @@ void SearchModelNG::SetSelectionMenuHidden(bool selectionMenuHidden) void SearchModelNG::SetOnCopy(std::function&& func) { - auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub(); + auto searchTextField = GetSearchTextFieldFrameNode(); + CHECK_NULL_VOID(searchTextField); + auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->SetOnCopy(std::move(func)); } void SearchModelNG::SetOnCut(std::function&& func) { - auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub(); + auto searchTextField = GetSearchTextFieldFrameNode(); + CHECK_NULL_VOID(searchTextField); + auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - eventHub->SetOnCut(std::move(func)); + auto searchPasteFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), func]( + const std::string& value) { + if (func) { + func(value); + } + auto node = weak.Upgrade(); + if (node) { + node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + }; + eventHub->SetOnCut(std::move(searchPasteFunc)); } void SearchModelNG::SetOnPaste(std::function&& func) { - auto eventHub = ViewStackProcessor::GetInstance()->GetMainFrameNodeEventHub(); + auto searchTextField = GetSearchTextFieldFrameNode(); + CHECK_NULL_VOID(searchTextField); + auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - eventHub->SetOnPaste(std::move(func)); + auto searchPasteFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), func]( + const std::string& value) { + if (func) { + func(value); + } + auto node = weak.Upgrade(); + if (node) { + node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + }; + eventHub->SetOnPaste(std::move(searchPasteFunc)); } void SearchModelNG::SetCustomKeyboard(const std::function&& buildFunc) @@ -562,12 +600,12 @@ void SearchModelNG::CreateTextField(const RefPtr& parentNode, const CHECK_NULL_VOID(searchTheme); auto nodeId = parentNode->GetTextFieldId(); auto frameNode = FrameNode::GetOrCreateFrameNode( - V2::TEXTINPUT_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr(); }); + V2::SEARCH_Field_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr(); }); auto textFieldLayoutProperty = frameNode->GetLayoutProperty(); auto pattern = frameNode->GetPattern(); - auto textEditingValue = pattern->GetTextEditingValue(); + auto textValue = pattern->GetTextValue(); if (textFieldLayoutProperty) { - if (value.has_value() && value.value() != textEditingValue.text) { + if (value.has_value() && value.value() != textValue) { pattern->InitEditingValueText(value.value()); } textFieldLayoutProperty->UpdatePlaceholder(placeholder.value_or("")); @@ -777,10 +815,29 @@ RefPtr SearchModelNG::GetOrCreateSearchNode( void SearchModelNG::SetOnChangeEvent(std::function&& onChangeEvent) { - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - CHECK_NULL_VOID(frameNode); - auto eventHub = frameNode->GetEventHub(); + auto searchTextField = GetSearchTextFieldFrameNode(); + CHECK_NULL_VOID(searchTextField); + auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - eventHub->SetOnChangeEvent(std::move(onChangeEvent)); + auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), onChangeEvent]( + const std::string& value) { + if (onChangeEvent) { + onChangeEvent(value); + } + auto node = weak.Upgrade(); + if (node) { + node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } + }; + eventHub->SetOnChangeEvent(std::move(searchChangeFunc)); +} + +RefPtr SearchModelNG::GetSearchTextFieldFrameNode() const +{ + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_RETURN(frameNode, nullptr); + auto textFieldChild = AceType::DynamicCast(frameNode->GetChildren().front()); + CHECK_NULL_RETURN(textFieldChild, nullptr); + return textFieldChild; } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/search/search_model_ng.h b/frameworks/core/components_ng/pattern/search/search_model_ng.h index b8d0b7d0795..bd7807bad84 100644 --- a/frameworks/core/components_ng/pattern/search/search_model_ng.h +++ b/frameworks/core/components_ng/pattern/search/search_model_ng.h @@ -16,6 +16,8 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SEARCH_SEARCH_MODEL_NG_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SEARCH_SEARCH_MODEL_NG_H +#include "base/memory/referenced.h" +#include "core/components_ng/base/frame_node.h" #include "core/components_ng/pattern/search/search_model.h" #include "core/components_ng/pattern/search/search_node.h" @@ -66,6 +68,7 @@ private: void CreateCancelButton(const RefPtr& parentNode, bool hasCancelButtonNode); RefPtr GetOrCreateSearchNode( const std::string& tag, int32_t nodeId, const std::function(void)>& patternCreator); + RefPtr GetSearchTextFieldFrameNode() const; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/search/search_pattern.cpp b/frameworks/core/components_ng/pattern/search/search_pattern.cpp index 9bccd7db2e1..a56b40a5ddd 100644 --- a/frameworks/core/components_ng/pattern/search/search_pattern.cpp +++ b/frameworks/core/components_ng/pattern/search/search_pattern.cpp @@ -362,7 +362,6 @@ void SearchPattern::OnClickCancelButton() auto textFieldPattern = textFieldFrameNode->GetPattern(); CHECK_NULL_VOID(textFieldPattern); textFieldPattern->InitEditingValueText(""); - textFieldPattern->InitCaretPosition(""); auto textRect = textFieldPattern->GetTextRect(); textRect.SetLeft(0.0f); textFieldPattern->SetTextRect(textRect); @@ -776,7 +775,7 @@ void SearchPattern::ToJsonValueForTextField(std::unique_ptr& json) co auto textFieldPattern = textFieldFrameNode->GetPattern(); CHECK_NULL_VOID(textFieldPattern); - json->Put("value", textFieldPattern->GetTextEditingValue().text.c_str()); + json->Put("value", textFieldPattern->GetTextValue().c_str()); json->Put("placeholder", textFieldPattern->GetPlaceHolder().c_str()); json->Put("placeholderColor", textFieldPattern->GetPlaceholderColor().c_str()); json->Put("placeholderFont", textFieldPattern->GetPlaceholderFont().c_str()); diff --git a/frameworks/core/components_ng/pattern/search/search_text_field.cpp b/frameworks/core/components_ng/pattern/search/search_text_field.cpp new file mode 100644 index 00000000000..de8c91f0967 --- /dev/null +++ b/frameworks/core/components_ng/pattern/search/search_text_field.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/search/search_text_field.h" + +#include "core/components_ng/pattern/search/search_event_hub.h" + +namespace OHOS::Ace::NG { + +bool SearchTextFieldPattern::IsSearchParentNode() const +{ + auto parentFrameNode = AceType::DynamicCast(GetHost()->GetParent()); + return parentFrameNode && parentFrameNode->GetTag() == V2::SEARCH_ETS_TAG; +} + +RefPtr SearchTextFieldPattern::GetFocusHub() const +{ + if (!IsSearchParentNode()) { + return TextFieldPattern::GetFocusHub(); + } + + auto parentFrameNode = AceType::DynamicCast(GetHost()->GetParent()); + return parentFrameNode->GetOrCreateFocusHub(); +} + +void SearchTextFieldPattern::PerformAction(TextInputAction action, bool forceCloseKeyboard) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto parentFrameNode = AceType::DynamicCast(host->GetParent()); + auto eventHub = parentFrameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->UpdateSubmitEvent(GetTextValue()); + CloseKeyboard(forceCloseKeyboard); +} + +TextInputAction SearchTextFieldPattern::GetDefaultTextInputAction() +{ + return TextInputAction::SEARCH; +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/search/search_text_field.h b/frameworks/core/components_ng/pattern/search/search_text_field.h new file mode 100644 index 00000000000..40caf9e3048 --- /dev/null +++ b/frameworks/core/components_ng/pattern/search/search_text_field.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SEARCH_SEARCH_TEXT_FIELD_PATTERN_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SEARCH_SEARCH_TEXT_FIELD_PATTERN_H + +#include "core/components_ng/pattern/text_field/text_field_pattern.h" + +namespace OHOS::Ace::NG { + +class SearchTextFieldPattern final : public TextFieldPattern { + DECLARE_ACE_TYPE(SearchTextFieldPattern, TextFieldPattern); + +public: + SearchTextFieldPattern() = default; + ~SearchTextFieldPattern() override = default; + + RefPtr GetFocusHub() const override; + bool IsSearchParentNode() const; + void PerformAction(TextInputAction action, bool forceCloseKeyboard = true) override; + TextInputAction GetDefaultTextInputAction() override; +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SEARCH_SEARCH_TEXT_FIELD_PATTERN_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp index 70cce129ff8..baa1d1c15b3 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp @@ -15,6 +15,8 @@ #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h" +#include + #include #include "base/geometry/ng/offset_t.h" @@ -36,7 +38,7 @@ void SelectOverlayLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) if (!CheckInShowArea(*info_)) { menu->SetActive(false); return; - } else if (!info_->firstHandle.isShow && !info_->secondHandle.isShow) { + } else if (!info_->firstHandle.isShow && !info_->secondHandle.isShow && !info_->isSelectRegionVisible) { menu->SetActive(false); } else { menu->SetActive(true); @@ -134,12 +136,13 @@ OffsetF SelectOverlayLayoutAlgorithm::ComputeSelectMenuPosition(LayoutWrapper* l singleHandle.Width(), singleHandle.Height()); } + float menuSpacing = 0.0f; if (info_->isSingleHandle) { - auto menuSpacing = static_cast(menuSpacingBetweenText); + menuSpacing = static_cast(menuSpacingBetweenText); menuPosition = OffsetF((singleHandle.Left() + singleHandle.Right() - menuWidth) / 2.0f, static_cast(singleHandle.Top() - menuSpacing - menuHeight)); } else { - auto menuSpacing = static_cast(menuSpacingBetweenText + menuSpacingBetweenHandle); + menuSpacing = static_cast(menuSpacingBetweenText + menuSpacingBetweenHandle); menuPosition = OffsetF((firstHandleRect.Left() + secondHandleRect.Left() - menuWidth) / 2.0f, static_cast(firstHandleRect.Top() - menuSpacing - menuHeight)); @@ -188,6 +191,7 @@ OffsetF SelectOverlayLayoutAlgorithm::ComputeSelectMenuPosition(LayoutWrapper* l menuPosition.SetY(viewPort.GetY() + viewPort.Height() + menuSpacingBetweenText); } LOGD("select_overlay menuPosition: %{public}s", menuPosition.ToString().c_str()); + ConstraintMenuWithAnchorNode(menuPosition, { menuSpacing, menuHeight, frameNode, viewPort }); defaultMenuEndOffset_ = menuPosition + OffsetF(menuWidth, 0.0f); if (isExtension) { return defaultMenuEndOffset_ - OffsetF(width, 0); @@ -220,4 +224,28 @@ bool SelectOverlayLayoutAlgorithm::IsTextAreaSelectAll() return info_->menuInfo.menuOffset.has_value() && (!info_->firstHandle.isShow || !info_->secondHandle.isShow); } +void SelectOverlayLayoutAlgorithm::ConstraintMenuWithAnchorNode(OffsetF& menuOffset, const ConstraintMenuParams& params) +{ + CHECK_NULL_VOID(params.anchorNode); + auto context = params.anchorNode->GetContext(); + CHECK_NULL_VOID(context); + auto parentGlobalOffset = params.anchorNode->GetPaintRectOffset() - context->GetRootRect().GetOffset(); + auto geometryNode = params.anchorNode->GetGeometryNode(); + CHECK_NULL_VOID(geometryNode); + auto contentRect = geometryNode->GetContentRect(); + auto anchorGlobalOffset = geometryNode->GetContentOffset() + parentGlobalOffset; + contentRect.SetOffset(anchorGlobalOffset); + auto interRect = params.viewPort.IntersectRectT(contentRect); + auto menuBottomDistance = interRect.GetY() - (menuOffset.GetY() + params.minSpacing + params.menuHeight); + if (menuBottomDistance > 0) { + menuOffset.AddY(menuBottomDistance); + return; + } + auto menuTopDistance = + anchorGlobalOffset.GetY() + geometryNode->GetContentSize().Height() - (menuOffset.GetY() - params.minSpacing); + if (menuTopDistance < 0) { + menuOffset.AddY(menuTopDistance); + } +} + } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h index ec05ee1d6be..9fe18664606 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h @@ -25,6 +25,13 @@ namespace OHOS::Ace::NG { +struct ConstraintMenuParams { + float minSpacing; + float menuHeight; + RefPtr anchorNode; + RectF viewPort; +}; + class ACE_EXPORT SelectOverlayLayoutAlgorithm : public BoxLayoutAlgorithm { DECLARE_ACE_TYPE(SelectOverlayLayoutAlgorithm, BoxLayoutAlgorithm); @@ -64,6 +71,7 @@ private: OffsetF ComputeSelectMenuPosition(LayoutWrapper* layoutWrapper); OffsetF ComputeExtensionMenuPosition(LayoutWrapper* layoutWrapper, const OffsetF& offset); bool IsTextAreaSelectAll(); + void ConstraintMenuWithAnchorNode(OffsetF& menuOffset, const ConstraintMenuParams& params); std::shared_ptr info_; diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp index c013d540997..36502d946a6 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp @@ -403,6 +403,16 @@ void SelectOverlayPattern::SetHandleReverse(bool reverse) host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } +void SelectOverlayPattern::SetSelectRegionVisible(bool isSelectRegionVisible) +{ + if (info_->isSelectRegionVisible != isSelectRegionVisible) { + info_->isSelectRegionVisible = isSelectRegionVisible; + auto host = DynamicCast(GetHost()); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } +} + void SelectOverlayPattern::UpdateFirstSelectHandleInfo(const SelectHandleInfo& info) { if (info_->firstHandle == info) { @@ -475,6 +485,15 @@ void SelectOverlayPattern::UpdateShowArea(const RectF& area) host->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT); } +void SelectOverlayPattern::UpdateSelectMenuInfo(std::function updateAction) +{ + if (updateAction) { + SelectMenuInfo shadowMenuInfo = info_->menuInfo; + updateAction(shadowMenuInfo); + UpdateSelectMenuInfo(shadowMenuInfo); + } +} + void SelectOverlayPattern::ShowOrHiddenMenu(bool isHidden) { auto host = DynamicCast(GetHost()); @@ -482,7 +501,8 @@ void SelectOverlayPattern::ShowOrHiddenMenu(bool isHidden) if (info_->menuInfo.menuIsShow && isHidden) { info_->menuInfo.menuIsShow = false; host->UpdateToolBar(false); - } else if (!info_->menuInfo.menuIsShow && !isHidden && (info_->firstHandle.isShow || info_->secondHandle.isShow)) { + } else if (!info_->menuInfo.menuIsShow && !isHidden && + (info_->firstHandle.isShow || info_->secondHandle.isShow || info_->isSelectRegionVisible)) { info_->menuInfo.menuIsShow = true; host->UpdateToolBar(false); } diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h index 23f68a91a07..689cd91ac2c 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h @@ -88,8 +88,12 @@ public: void UpdateSelectMenuInfo(const SelectMenuInfo& info); + void UpdateSelectMenuInfo(std::function updateAction); + void UpdateShowArea(const RectF& area); + void SetSelectRegionVisible(bool isSelectRegionVisible); + void SetHandleReverse(bool reverse); void SetSelectInfo(const std::string& selectInfo) diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.h b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.h index b7fe4af088b..55af0372cd4 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.h +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.h @@ -87,6 +87,7 @@ struct SelectOverlayInfo { bool handleReverse = false; // Used to determine the range of judgment that is parallel to the first and second handles. float singleLineHeight = 10.0f; + bool isSelectRegionVisible = false; SelectHandleInfo firstHandle; SelectHandleInfo secondHandle; HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF; diff --git a/frameworks/core/components_ng/pattern/text/text_base.h b/frameworks/core/components_ng/pattern/text/text_base.h index 192984cd9a0..eb9a6045c61 100644 --- a/frameworks/core/components_ng/pattern/text/text_base.h +++ b/frameworks/core/components_ng/pattern/text/text_base.h @@ -17,7 +17,7 @@ #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_H #include "base/memory/ace_type.h" -#include "core/components_ng/manager/select_overlay/selection_host.h" +#include "core/components_ng/manager/select_overlay/select_overlay_client.h" #include "core/components_ng/pattern/text_field/text_selector.h" #include "core/components_ng/render/drawing.h" #include "core/components_ng/render/paragraph.h" @@ -27,8 +27,25 @@ using ParagraphT = std::variant, RefPtr> enum class MouseStatus { PRESSED, RELEASED, MOVE, NONE }; -class TextBase : public SelectionHost { - DECLARE_ACE_TYPE(TextBase, SelectionHost); +struct HandleMoveStatus { + bool isFirsthandle = false; + int32_t position = -1; + OffsetF handleOffset; + + void Reset() + { + isFirsthandle = false; + position = -1; + } + + bool IsValid() + { + return position >= 0; + } +}; + +class TextBase : public SelectOverlayClient { + DECLARE_ACE_TYPE(TextBase, SelectOverlayClient); public: TextBase() = default; @@ -49,6 +66,21 @@ public: return mouseStatus_; } + static int32_t GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev = false) + { + char16_t aroundChar = 0; + if (checkPrev) { + if (static_cast(extend) <= text.length()) { + aroundChar = text[std::max(0, extend - 1)]; + } + } else { + if (static_cast(extend) <= (text.length())) { + aroundChar = text[std::min(static_cast(text.length() - 1), extend)]; + } + } + return StringUtils::NotInUtf16Bmp(aroundChar) ? 2 : 1; + } + protected: TextSelector textSelector_; MouseStatus mouseStatus_ = MouseStatus::NONE; diff --git a/frameworks/core/components_ng/pattern/text/text_content_modifier.h b/frameworks/core/components_ng/pattern/text/text_content_modifier.h index cb1c938cc7d..f909c95333b 100644 --- a/frameworks/core/components_ng/pattern/text/text_content_modifier.h +++ b/frameworks/core/components_ng/pattern/text/text_content_modifier.h @@ -74,7 +74,7 @@ public: ifHaveSpanItemChildren_ = value; } - void SetDrawObscuredRects(const std::vector& drawObscuredRects) + void SetDrawObscuredRects(const std::vector& drawObscuredRects) { drawObscuredRects_ = drawObscuredRects; } @@ -165,7 +165,7 @@ private: std::vector obscuredReasons_; bool ifHaveSpanItemChildren_ = false; - std::vector drawObscuredRects_; + std::vector drawObscuredRects_; ACE_DISALLOW_COPY_AND_MOVE(TextContentModifier); }; diff --git a/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp index 2cb244fe913..d25c7dbe5d1 100644 --- a/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp @@ -312,7 +312,7 @@ void TextLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) } size_t index = 0; - std::vector rectsForPlaceholders; + std::vector rectsForPlaceholders; GetPlaceholderRects(rectsForPlaceholders); const auto& children = layoutWrapper->GetAllChildrenWithBuild(); // children only contains the image span. @@ -735,9 +735,9 @@ bool TextLayoutAlgorithm::IncludeImageSpan(LayoutWrapper* layoutWrapper) } void TextLayoutAlgorithm::GetSpanAndImageSpanList( - std::list>& spanList, std::map>>& imageSpanList) + std::list>& spanList, std::map>>& imageSpanList) { - std::vector rectsForPlaceholders; + std::vector rectsForPlaceholders; paragraph_->GetRectsForPlaceholders(rectsForPlaceholders); for (const auto& child : spanItemChildren_) { @@ -758,7 +758,7 @@ void TextLayoutAlgorithm::GetSpanAndImageSpanList( void TextLayoutAlgorithm::SplitSpanContentByLines(const TextStyle& textStyle, const std::list>& spanList, - std::map>>>& spanContentLines) + std::map>>>& spanContentLines) { int32_t currentLine = 0; size_t currentLength = 0; @@ -767,12 +767,12 @@ void TextLayoutAlgorithm::SplitSpanContentByLines(const TextStyle& textStyle, continue; } std::string textValue = child->content; - std::vector selectedRects; + std::vector selectedRects; if (!textValue.empty()) { paragraph_->GetRectsForRange(currentLength, currentLength + textValue.size(), selectedRects); } currentLength += textValue.size(); - Rect currentRect; + RectF currentRect; auto preLinetLastSpan = spanContentLines.rbegin(); double preLineFontSize = textStyle.GetFontSize().Value(); if (preLinetLastSpan != spanContentLines.rend()) { @@ -810,8 +810,8 @@ void TextLayoutAlgorithm::SplitSpanContentByLines(const TextStyle& textStyle, } void TextLayoutAlgorithm::SetImageSpanTextStyleByLines(const TextStyle& textStyle, - std::map>>& imageSpanList, - std::map>>>& spanContentLines) + std::map>>& imageSpanList, + std::map>>>& spanContentLines) { auto pipelineContext = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipelineContext); @@ -827,7 +827,7 @@ void TextLayoutAlgorithm::SetImageSpanTextStyleByLines(const TextStyle& textStyl auto offset = imageSpanItem->second.first.GetOffset(); auto imageSpanItemRect = imageSpanItem->second.first; - imageSpanItemRect.SetOffset(Offset(spanItem->second.first.GetOffset().GetX(), offset.GetY())); + imageSpanItemRect.SetOffset(OffsetF(spanItem->second.first.GetOffset().GetX(), offset.GetY())); bool isIntersectWith = spanItem->second.first.IsIntersectWith(imageSpanItemRect); if (!isIntersectWith) { break; @@ -858,11 +858,11 @@ void TextLayoutAlgorithm::SetImageSpanTextStyle(const TextStyle& textStyle) CHECK_NULL_VOID(paragraph_); std::list> spanList; - std::map>> imageSpanList; + std::map>> imageSpanList; GetSpanAndImageSpanList(spanList, imageSpanList); // split text content by lines - std::map>>> spanContentLines; + std::map>>> spanContentLines; SplitSpanContentByLines(textStyle, spanList, spanContentLines); // set imagespan textstyle @@ -892,7 +892,7 @@ size_t TextLayoutAlgorithm::GetLineCount() const return paragraph_->GetLineCount(); } -void TextLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) +void TextLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) { CHECK_NULL_VOID(paragraph_); paragraph_->GetRectsForPlaceholders(rects); diff --git a/frameworks/core/components_ng/pattern/text/text_layout_algorithm.h b/frameworks/core/components_ng/pattern/text/text_layout_algorithm.h index 715f4b5adad..f5ed87a05dc 100644 --- a/frameworks/core/components_ng/pattern/text/text_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text/text_layout_algorithm.h @@ -84,7 +84,7 @@ protected: return 0; } - virtual void GetPlaceholderRects(std::vector& rects); + virtual void GetPlaceholderRects(std::vector& rects); virtual ParagraphStyle GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const; @@ -126,12 +126,12 @@ private: bool IncludeImageSpan(LayoutWrapper* layoutWrapper); void SetImageSpanTextStyle(const TextStyle& textStyle); void GetSpanAndImageSpanList(std::list>& spanList, - std::map>>& imageSpanList); + std::map>>& imageSpanList); void SplitSpanContentByLines(const TextStyle& textStyle, const std::list>& spanList, - std::map>>>& spanContentLines); + std::map>>>& spanContentLines); void SetImageSpanTextStyleByLines(const TextStyle& textStyle, - std::map>>& imageSpanList, - std::map>>>& spanContentLines); + std::map>>& imageSpanList, + std::map>>>& spanContentLines); std::list> spanItemChildren_; RefPtr paragraph_; diff --git a/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp b/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp index 28fe5c17067..35ec784fc53 100644 --- a/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp +++ b/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp @@ -48,7 +48,7 @@ void TextOverlayModifier::onDraw(DrawingContext& drawingContext) auto rect = selectedRect; if (contentRect_.has_value()) { if (rect.Right() > contentRect_.value().Right()) { - rect.SetWidth(std::max(contentRect_.value().Right() - rect.Left(), 0.0)); + rect.SetWidth(std::max(contentRect_.value().Right() - rect.Left(), 0.0f)); } } drawingContext.canvas.DrawRect(RSRect(paintOffset.GetX() + rect.Left(), paintOffset.GetY() + rect.Top(), @@ -70,7 +70,7 @@ void TextOverlayModifier::SetSelectedColor(uint32_t selectedColor) selectedColor_->Set(static_cast(selectedColor)); } -void TextOverlayModifier::SetSelectedRects(const std::vector& selectedRects) +void TextOverlayModifier::SetSelectedRects(const std::vector& selectedRects) { if (changeSelectedRects_ && IsSelectedRectsChanged(selectedRects)) { changeSelectedRects_->Set(!changeSelectedRects_->Get()); @@ -78,7 +78,7 @@ void TextOverlayModifier::SetSelectedRects(const std::vector& selectedRect selectedRects_ = selectedRects; } -bool TextOverlayModifier::IsSelectedRectsChanged(const std::vector& selectedRects) +bool TextOverlayModifier::IsSelectedRectsChanged(const std::vector& selectedRects) { bool result = false; if (selectedRects.size() == selectedRects_.size()) { diff --git a/frameworks/core/components_ng/pattern/text/text_overlay_modifier.h b/frameworks/core/components_ng/pattern/text/text_overlay_modifier.h index 6ccb4ed5ae6..fb5028350a0 100644 --- a/frameworks/core/components_ng/pattern/text/text_overlay_modifier.h +++ b/frameworks/core/components_ng/pattern/text/text_overlay_modifier.h @@ -37,7 +37,7 @@ public: void SetSelectedColor(uint32_t selectedColor); - void SetSelectedRects(const std::vector& selectedRects); + void SetSelectedRects(const std::vector& selectedRects); void SetContentRect(const RectF& contentRect) { @@ -54,13 +54,13 @@ protected: std::optional contentRect_; private: - bool IsSelectedRectsChanged(const std::vector& selectedRects); + bool IsSelectedRectsChanged(const std::vector& selectedRects); RefPtr paintOffset_; RefPtr selectedColor_; RefPtr changeSelectedRects_; RefPtr isClip_;; - std::vector selectedRects_; + std::vector selectedRects_; ACE_DISALLOW_COPY_AND_MOVE(TextOverlayModifier); }; diff --git a/frameworks/core/components_ng/pattern/text/text_paint_method.cpp b/frameworks/core/components_ng/pattern/text/text_paint_method.cpp index 547381f427f..ede56252f39 100644 --- a/frameworks/core/components_ng/pattern/text/text_paint_method.cpp +++ b/frameworks/core/components_ng/pattern/text/text_paint_method.cpp @@ -71,7 +71,7 @@ void TextPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper) auto spanItemChildren = pattern->GetSpanItemChildren(); textContentModifier_->SetIfHaveSpanItemChildren(!spanItemChildren.empty()); auto wideTextLength = pattern->GetDisplayWideTextLength(); - std::vector drawObscuredRects; + std::vector drawObscuredRects; if (wideTextLength != 0) { paragraph_->GetRectsForRange(0, wideTextLength, drawObscuredRects); } @@ -108,7 +108,7 @@ void TextPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper) auto context = host->GetRenderContext(); CHECK_NULL_VOID(context); const auto& selection = textPattern->GetTextSelector(); - std::vector selectedRects; + std::vector selectedRects; if (selection.GetTextStart() != selection.GetTextEnd()) { paragraph_->GetRectsForRange(selection.GetTextStart(), selection.GetTextEnd(), selectedRects); } diff --git a/frameworks/core/components_ng/pattern/text/text_pattern.cpp b/frameworks/core/components_ng/pattern/text/text_pattern.cpp index 976e630bbb6..cfacaf632bc 100644 --- a/frameworks/core/components_ng/pattern/text/text_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text/text_pattern.cpp @@ -115,46 +115,31 @@ void TextPattern::ResetSelection() } } -int32_t TextPattern::GetGraphemeClusterLength(int32_t extend) const -{ - auto text = textForDisplay_; - char16_t aroundChar = 0; - - if (static_cast(extend) < (text.length())) { - aroundChar = text[std::min(static_cast(text.length() - 1), extend)]; - } - return StringUtils::NotInUtf16Bmp(aroundChar) ? 2 : 1; -} - void TextPattern::InitSelection(const Offset& pos) { CHECK_NULL_VOID(paragraph_); - int32_t extend = paragraph_->GetHandlePositionForClick(pos); + int32_t extend = paragraph_->GetGlyphIndexByCoordinate(pos); int32_t start = 0; int32_t end = 0; if (!paragraph_->GetWordBoundary(extend, start, end)) { start = extend; - end = std::min( - static_cast(GetWideText().length()) + imageCount_, extend + GetGraphemeClusterLength(extend)); + end = std::min(static_cast(GetWideText().length()) + imageCount_, + extend + GetGraphemeClusterLength(GetWideText(), extend)); } textSelector_.Update(start, end); } -OffsetF TextPattern::CalcCursorOffsetByPosition(int32_t position, float& selectLineHeight) +void TextPattern::CalcCaretMetricsByPosition(int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) { auto host = GetHost(); - CHECK_NULL_RETURN(host, OffsetF(0.0f, 0.0f)); + CHECK_NULL_VOID(host); auto rect = host->GetGeometryNode()->GetFrameRect(); - CHECK_NULL_RETURN(paragraph_, OffsetF(0.0f, 0.0f)); - CaretMetrics metrics; - auto computeSuccess = paragraph_->ComputeOffsetForCaretDownstream(position, metrics) || - paragraph_->ComputeOffsetForCaretUpstream(position, metrics); + CHECK_NULL_VOID(paragraph_); + auto computeSuccess = paragraph_->CalcCaretMetricsByPosition(extent, caretCaretMetric, textAffinity); if (!computeSuccess) { LOGW("Get caret offset failed, set it to text tail"); - return { rect.Width(), 0.0f }; + caretCaretMetric = CaretMetricsF(OffsetF(0.0f, rect.Width()), 0.0f); } - selectLineHeight = metrics.height; - return { static_cast(metrics.offset.GetX()), static_cast(metrics.offset.GetY()) }; } void TextPattern::CalculateHandleOffsetAndShowOverlay(bool isUsingMouse) @@ -168,28 +153,40 @@ void TextPattern::CalculateHandleOffsetAndShowOverlay(bool isUsingMouse) auto textPaintOffset = offset - OffsetF(0.0f, std::min(baselineOffset_, 0.0f)); // calculate firstHandleOffset, secondHandleOffset and handlePaintSize - float startSelectHeight = 0.0f; - float endSelectHeight = 0.0f; - auto startOffset = CalcCursorOffsetByPosition(textSelector_.baseOffset, startSelectHeight); - auto endOffset = CalcCursorOffsetByPosition(textSelector_.destinationOffset, endSelectHeight); - OffsetF firstHandleOffset = startOffset + textPaintOffset - rootOffset; - OffsetF secondHandleOffset = endOffset + textPaintOffset - rootOffset; + CaretMetricsF firstHandleMetrics; + CaretMetricsF secondHandleMetrics; + CalcCaretMetricsByPosition(textSelector_.baseOffset, firstHandleMetrics, TextAffinity::DOWNSTREAM); + CalcCaretMetricsByPosition(textSelector_.destinationOffset, secondHandleMetrics, TextAffinity::UPSTREAM); + OffsetF firstHandleOffset = firstHandleMetrics.offset + textPaintOffset - rootOffset; + OffsetF secondHandleOffset = secondHandleMetrics.offset + textPaintOffset - rootOffset; textSelector_.selectionBaseOffset = firstHandleOffset; textSelector_.selectionDestinationOffset = secondHandleOffset; RectF firstHandle; firstHandle.SetOffset(firstHandleOffset); - firstHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), startSelectHeight }); + firstHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), firstHandleMetrics.height }); textSelector_.firstHandle = firstHandle; RectF secondHandle; secondHandle.SetOffset(secondHandleOffset); - secondHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), endSelectHeight }); - secondHandle.SetHeight(endSelectHeight); + secondHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), secondHandleMetrics.height }); + secondHandle.SetHeight(secondHandleMetrics.height); textSelector_.secondHandle = secondHandle; } +OffsetF TextPattern::GetTextPaintOffset() const +{ + auto host = GetHost(); + CHECK_NULL_RETURN(host, OffsetF(0.0f, 0.0f)); + auto pipeline = host->GetContext(); + CHECK_NULL_RETURN(pipeline, OffsetF(0.0f, 0.0f)); + auto rootOffset = pipeline->GetRootRect().GetOffset(); + auto offset = host->GetPaintRectOffset() + contentRect_.GetOffset(); + auto textPaintOffset = offset - OffsetF(0.0f, std::min(baselineOffset_, 0.0f)); + return textPaintOffset - rootOffset; +} + void TextPattern::HandleLongPress(GestureEvent& info) { if (copyOption_ == CopyOptions::None || isMousePressed_) { @@ -523,7 +520,7 @@ void TextPattern::HandleSingleClickEvent(GestureEvent& info) !spans_.empty() && paragraph_) { Offset textOffset = { info.GetLocalLocation().GetX() - textContentRect.GetX(), info.GetLocalLocation().GetY() - textContentRect.GetY() }; - auto position = paragraph_->GetHandlePositionForClick(textOffset); + auto position = paragraph_->GetGlyphIndexByCoordinate(textOffset); for (const auto& item : spans_) { if (item && position < item->position) { if (!item->onClick) { @@ -631,7 +628,7 @@ void TextPattern::HandleMouseEvent(const MouseInfo& info) Offset textOffset = { info.GetLocalLocation().GetX() - textPaintOffset.GetX(), info.GetLocalLocation().GetY() - textPaintOffset.GetY() }; CHECK_NULL_VOID(paragraph_); - auto start = paragraph_->GetHandlePositionForClick(textOffset); + auto start = paragraph_->GetGlyphIndexByCoordinate(textOffset); textSelector_.Update(start, start); } @@ -644,7 +641,7 @@ void TextPattern::HandleMouseEvent(const MouseInfo& info) Offset textOffset = { info.GetLocalLocation().GetX() - textPaintOffset.GetX(), info.GetLocalLocation().GetY() - textPaintOffset.GetY() }; CHECK_NULL_VOID(paragraph_); - auto end = paragraph_->GetHandlePositionForClick(textOffset); + auto end = paragraph_->GetGlyphIndexByCoordinate(textOffset); textSelector_.Update(textSelector_.baseOffset, end); } @@ -656,11 +653,11 @@ void TextPattern::HandleMouseEvent(const MouseInfo& info) if (isDoubleClick_) { isDoubleClick_ = false; } else { - auto textPaintOffset = contentRect_.GetOffset() - OffsetF(0.0f, std::min(baselineOffset_, 0.0f)); + auto textPaintOffset = contentRect_.GetOffset() - OffsetF(0.0, std::min(baselineOffset_, 0.0f)); Offset textOffset = { info.GetLocalLocation().GetX() - textPaintOffset.GetX(), info.GetLocalLocation().GetY() - textPaintOffset.GetY() }; CHECK_NULL_VOID(paragraph_); - auto end = paragraph_->GetHandlePositionForClick(textOffset); + auto end = paragraph_->GetGlyphIndexByCoordinate(textOffset); textSelector_.Update(textSelector_.baseOffset, end); } isMousePressed_ = false; @@ -769,12 +766,12 @@ bool TextPattern::IsDraggable(const Offset& offset) if (copyOption_ != CopyOptions::None && draggable && GreatNotEqual(textSelector_.GetTextEnd(), textSelector_.GetTextStart())) { // Determine if the pan location is in the selected area - std::vector selectedRects; + std::vector selectedRects; paragraph_->GetRectsForRange(textSelector_.GetTextStart(), textSelector_.GetTextEnd(), selectedRects); auto panOffset = OffsetF(offset.GetX(), offset.GetY()) - contentRect_.GetOffset() + OffsetF(0.0f, std::min(baselineOffset_, 0.0f)); for (const auto& selectedRect : selectedRects) { - if (selectedRect.IsInRegion(Point(panOffset.GetX(), panOffset.GetY()))) { + if (selectedRect.IsInRegion(PointF(panOffset.GetX(), panOffset.GetY()))) { return true; } } @@ -865,39 +862,17 @@ std::function TextPattern::GetThumbnailCallback() // TextDragBase implementations float TextPattern::GetLineHeight() const { - std::vector selectedRects; + std::vector selectedRects; paragraph_->GetRectsForRange(textSelector_.GetTextStart(), textSelector_.GetTextEnd(), selectedRects); CHECK_NULL_RETURN(selectedRects.size(), {}); return selectedRects.front().Height(); } -#ifndef USE_GRAPHIC_TEXT_GINE -RSTypographyProperties::TextBox TextPattern::ConvertRect(const Rect& rect) -#else -RSTextRect TextPattern::ConvertRect(const Rect& rect) -#endif -{ - return { RSRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom()), RSTextDirection::LTR }; -} - -#ifndef USE_GRAPHIC_TEXT_GINE -std::vector TextPattern::GetTextBoxes() -#else -std::vector TextPattern::GetTextBoxes() -#endif +std::vector TextPattern::GetTextBoxes() { - std::vector selectedRects; + std::vector selectedRects; paragraph_->GetRectsForRange(textSelector_.GetTextStart(), textSelector_.GetTextEnd(), selectedRects); -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector res; -#else - std::vector res; -#endif - res.reserve(selectedRects.size()); - for (auto&& rect : selectedRects) { - res.emplace_back(ConvertRect(rect)); - } - return res; + return selectedRects; } OffsetF TextPattern::GetParentGlobalOffset() const @@ -1369,17 +1344,10 @@ OffsetF TextPattern::GetDragUpperLeftCoordinates() if (dragBoxes_.empty()) { return { 0.0f, 0.0f }; } -#ifndef USE_GRAPHIC_TEXT_GINE - auto startY = dragBoxes_.front().rect_.GetTop(); - auto startX = dragBoxes_.front().rect_.GetLeft(); + auto startY = dragBoxes_.front().Top(); + auto startX = dragBoxes_.front().Left(); - auto endY = dragBoxes_.back().rect_.GetTop(); -#else - auto startY = dragBoxes_.front().rect.GetTop(); - auto startX = dragBoxes_.front().rect.GetLeft(); - - auto endY = dragBoxes_.back().rect.GetTop(); -#endif + auto endY = dragBoxes_.back().Top(); OffsetF offset; if (NearEqual(startY, endY)) { offset = { contentRect_.GetX() + startX, startY + contentRect_.GetY() }; @@ -1423,7 +1391,7 @@ RefPtr TextPattern::CreateNodePaintMethod() int32_t TextPattern::GetHandleIndex(const Offset& offset) const { - return paragraph_->GetHandlePositionForClick(offset); + return paragraph_->GetGlyphIndexByCoordinate(offset); } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text/text_pattern.h b/frameworks/core/components_ng/pattern/text/text_pattern.h index 5676263ebda..df231d93490 100644 --- a/frameworks/core/components_ng/pattern/text/text_pattern.h +++ b/frameworks/core/components_ng/pattern/text/text_pattern.h @@ -172,13 +172,11 @@ public: } float GetLineHeight() const override; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector GetTextBoxes() override; -#else - std::vector GetTextBoxes() override; -#endif + std::vector GetTextBoxes() override; OffsetF GetParentGlobalOffset() const override; + OffsetF GetTextPaintOffset() const; + RefPtr MoveDragNode() override { return std::move(dragNode_); @@ -237,7 +235,7 @@ public: #endif void InitSpanImageLayout(const std::vector& placeHolderIndex, - const std::vector& rectsForPlaceholders, OffsetF contentOffset) override + const std::vector& rectsForPlaceholders, OffsetF contentOffset) override { placeHolderIndex_ = placeHolderIndex; imageOffset_ = contentOffset; @@ -249,7 +247,7 @@ public: return placeHolderIndex_; } - const std::vector& GetRectsForPlaceholders() + const std::vector& GetRectsForPlaceholders() { return rectsForPlaceholders_; } @@ -288,6 +286,27 @@ public: #else static RSTextRect ConvertRect(const Rect& rect); #endif + // override SelectOverlayClient methods + void OnHandleMoveDone(const RectF& handleRect, bool isFirstHandle) override; + void OnHandleMove(const RectF& handleRect, bool isFirstHandle) override; + void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) override + { + switch (menuId) { + case SelectOverlayMenuId::COPY: + HandleOnCopy(); + return; + case SelectOverlayMenuId::SELECT_ALL: + HandleOnSelectAll(); + return; + default: + return; + } + } + + RefPtr GetClientHost() const override + { + return GetHost(); + } protected: virtual void HandleOnCopy(); @@ -304,15 +323,13 @@ protected: void CalculateHandleOffsetAndShowOverlay(bool isUsingMouse = false); void ShowSelectOverlay(const RectF& firstHandle, const RectF& secondHandle); void ShowSelectOverlay(const RectF& firstHandle, const RectF& secondHandle, bool animation); - int32_t GetGraphemeClusterLength(int32_t extend) const; bool OnDirtyLayoutWrapperSwap(const RefPtr& dirty, const DirtySwapConfig& config) override; bool IsSelectAll(); - virtual void OnHandleMoveDone(const RectF& handleRect, bool isFirstHandle); - virtual void OnHandleMove(const RectF& handleRect, bool isFirstHandle); virtual int32_t GetHandleIndex(const Offset& offset) const; std::wstring GetWideText() const; std::string GetSelectedText(int32_t start, int32_t end) const; - OffsetF CalcCursorOffsetByPosition(int32_t position, float& selectLineHeight); + void CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity = TextAffinity::DOWNSTREAM); bool showSelectOverlay_ = false; bool mouseEventInitialized_ = false; @@ -335,11 +352,7 @@ protected: float baselineOffset_ = 0.0f; int32_t imageCount_ = 0; SelectMenuInfo selectMenuInfo_; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector dragBoxes_; -#else - std::vector dragBoxes_; -#endif + std::vector dragBoxes_; private: void OnDetachFromFrameNode(FrameNode* node) override; @@ -371,7 +384,7 @@ private: RefPtr paragraph_; std::vector menuOptionItems_; std::vector placeHolderIndex_; - std::vector rectsForPlaceholders_; + std::vector rectsForPlaceholders_; OffsetF imageOffset_; OffsetF contentOffset_; diff --git a/frameworks/core/components_ng/pattern/text/text_styles.h b/frameworks/core/components_ng/pattern/text/text_styles.h index e0aff32c3ee..8c21c6e48d6 100644 --- a/frameworks/core/components_ng/pattern/text/text_styles.h +++ b/frameworks/core/components_ng/pattern/text/text_styles.h @@ -56,6 +56,35 @@ struct TextLineStyle { ACE_DEFINE_PROPERTY_GROUP_ITEM(WordBreak, WordBreak); }; +struct HandleInfoNG { + void UpdateOffset(const OffsetF& offset) + { + rect.SetOffset(offset); + } + + void AddOffset(float x, float y) + { + auto offset = rect.GetOffset(); + offset.AddX(x); + offset.AddY(y); + UpdateOffset(offset); + } + + bool operator==(const HandleInfoNG& handleInfo) const + { + + return rect == handleInfo.rect && index == handleInfo.index; + } + + bool operator!=(const HandleInfoNG& handleInfo) const + { + return !operator==(handleInfo); + } + + int32_t index = 0; + RectF rect; +}; + TextStyle CreateTextStyleUsingTheme(const std::unique_ptr& fontStyle, const std::unique_ptr& textLineStyle, const RefPtr& textTheme); diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp new file mode 100644 index 00000000000..64cc0ad1c8d --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/text_area/text_area_layout_algorithm.h" + +#include + +#include "base/geometry/dimension.h" +#include "base/utils/utils.h" +#include "core/components/common/layout/constants.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" +#include "core/pipeline/pipeline_base.h" +#include "core/pipeline_ng/pipeline_context.h" + +namespace OHOS::Ace::NG { +namespace { +constexpr float PARAGRAPH_SAVE_BOUNDARY = 1.0f; +constexpr uint32_t COUNTER_TEXT_MAXLINE = 1; +} // namespace +std::optional TextAreaLayoutAlgorithm::MeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) +{ + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(frameNode, std::nullopt); + auto textFieldLayoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_RETURN(pattern, std::nullopt); + + // Construct text style. + TextStyle textStyle; + std::string textContent; + bool showPlaceHolder = false; + ConstructTextStyles(frameNode, textStyle, textContent, showPlaceHolder); + + auto isInlineStyle = pattern->IsNormalInlineState(); + + // Create paragraph. + if (pattern->IsDragging() && !showPlaceHolder) { + CreateParagraph(textStyle, pattern->GetDragContents(), textContent, false); + } else { + CreateParagraph(textStyle, textContent, false, pattern->GetNakedCharPosition()); + } + + // constraint size. + auto contentIdealSize = CalculateConstraintSize(contentConstraint, layoutWrapper); + + // CounterNode measureContent. + if (textFieldLayoutProperty->GetShowCounterValue(false) && textFieldLayoutProperty->HasMaxLength() && + !isInlineStyle) { + auto counterNodeLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + if (counterNodeLayoutWrapper) { + auto textLength = static_cast(showPlaceHolder ? 0 : StringUtils::ToWstring(textContent).length()); + auto maxLength = static_cast(textFieldLayoutProperty->GetMaxLength().value()); + LayoutConstraintF textContentConstraint; + textContentConstraint.UpdateIllegalSelfIdealSizeWithCheck( + OptionalSizeF(contentIdealSize.Width(), std::nullopt)); + CounterNodeMeasureContent(textLength, maxLength, textContentConstraint, counterNodeLayoutWrapper); + auto height = counterNodeLayoutWrapper->GetGeometryNode()->GetFrameSize().Height(); + contentIdealSize.SetHeight(std::max(contentIdealSize.Height() - height, 0.0f)); + } + } + + // Used for empty text. + preferredHeight_ = pattern->PreferredLineHeight(); + + // Paragraph layout.} + if (isInlineStyle) { + return InlineMeasureContent(contentConstraint, layoutWrapper, contentIdealSize); + } else if (showPlaceHolder) { + return PlaceHolderMeasureContent(contentIdealSize); + } else { + return TextAreaMeasureContent(contentIdealSize); + } +} + +void TextAreaLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint(); + OptionalSizeF frameSize = + CreateIdealSize(layoutConstraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT_MAIN_AXIS); + const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); + const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + float contentWidth = 0.0f; + float contentHeight = 0.0f; + if (content) { + auto contentSize = content->GetRect().GetSize(); + contentWidth = contentSize.Width(); + contentHeight = contentSize.Height(); + } + + // Add children height; + auto counterNodeLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + if (counterNodeLayoutWrapper) { + auto counterSize = counterNodeLayoutWrapper->GetGeometryNode()->GetFrameSize(); + contentHeight += counterSize.Height(); + } + + if (pattern->IsNormalInlineState() && pattern->IsFocus()) { + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum() + PARAGRAPH_SAVE_BOUNDARY); + frameSize.SetHeight(contentHeight + pattern->GetVerticalPaddingSum() + PARAGRAPH_SAVE_BOUNDARY); + } else { + auto textFieldLayoutProperty = pattern->GetLayoutProperty(); + CHECK_NULL_VOID(textFieldLayoutProperty); + if (!frameSize.Width().has_value()) { + // If width is not set, select the maximum value of minWidth and maxWidth to layoutConstraint + if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && + calcLayoutConstraint->maxSize.value().Width().has_value()) { + frameSize.SetHeight( + std::min(layoutConstraint->maxSize.Width(), contentWidth + pattern->GetHorizontalPaddingSum())); + } else if (!calcLayoutConstraint) { + // If calcLayoutConstraint has not set, use the LayoutConstraint initial value + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum()); + } else { + // If maxWidth is not set and calcLayoutConstraint is set, set minWidth to layoutConstraint + frameSize.SetWidth(layoutConstraint->minSize.Width()); + } + } + if (!frameSize.Height().has_value()) { + // Like width + if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && + calcLayoutConstraint->maxSize.value().Height().has_value()) { + frameSize.SetHeight( + std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); + } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { + // calcLayoutConstraint initialized once when setting width, set minHeight=0, + // so add "minHeight=0" to the constraint. + frameSize.SetHeight( + std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); + } else { + frameSize.SetHeight( + std::max(layoutConstraint->minSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); + } + } + + if (textFieldLayoutProperty->GetWidthAutoValue(false)) { + frameSize.SetWidth(std::min(contentWidth, textRect_.Width()) + pattern->GetHorizontalPaddingSum()); + } + + // Here's what happens when the height or width is set at list one + if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { + frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); + } else { + auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, + layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), + layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); + frameSize.SetWidth(finalSize.Width()); + frameSize.SetHeight(finalSize.Height()); + } + if (layoutConstraint->maxSize.Height() < layoutConstraint->minSize.Height()) { + frameSize.SetHeight(layoutConstraint->minSize.Height()); + } + if (layoutConstraint->maxSize.Width() < layoutConstraint->minSize.Width()) { + frameSize.SetWidth(layoutConstraint->minSize.Width()); + } + } + layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); +} + +void TextAreaLayoutAlgorithm::CounterNodeMeasureContent(uint32_t textLength, uint32_t maxLength, + const LayoutConstraintF& contentConstraint, RefPtr& layoutWrapper) +{ + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto theme = pipeline->GetTheme(); + CHECK_NULL_VOID(theme); + TextStyle countTextStyle = (textLength != maxLength) ? theme->GetCountTextStyle() : theme->GetOverCountTextStyle(); + auto textNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(textNode); + auto textLayoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(textLayoutProperty); + + std::string counterText = std::to_string(textLength) + "/" + std::to_string(maxLength); + textLayoutProperty->UpdateContent(counterText); + textLayoutProperty->UpdateFontSize(countTextStyle.GetFontSize()); + textLayoutProperty->UpdateTextColor(countTextStyle.GetTextColor()); + textLayoutProperty->UpdateFontWeight(countTextStyle.GetFontWeight()); + textLayoutProperty->UpdateTextAlign(TextAlign::END); + textLayoutProperty->UpdateMaxLines(COUNTER_TEXT_MAXLINE); + + layoutWrapper->Measure(contentConstraint); +} + +void TextAreaLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +{ + // update child position. + auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); + CHECK_NULL_VOID(content); + auto contentSize = content->GetRect().GetSize(); + auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + auto context = layoutWrapper->GetHostNode()->GetContext(); + CHECK_NULL_VOID(context); + parentGlobalOffset_ = layoutWrapper->GetHostNode()->GetPaintRectOffset() - context->GetRootRect().GetOffset(); + auto align = Alignment::CENTER; + bool hasAlign = false; + if (layoutWrapper->GetLayoutProperty()->GetPositionProperty()) { + align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align); + hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value(); + } + // Update content position. + OffsetF contentOffset = Alignment::GetAlignPosition(size, contentSize, align); + auto isInlineStyle = pattern->IsNormalInlineState(); + if (hasAlign) { + if (isInlineStyle) { + content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX(), contentOffset.GetY())); + } else { + content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), + contentOffset.GetY() + pattern->GetBorderTop())); + } + + OffsetF textRectOffSet = Alignment::GetAlignPosition(size, textRect_.GetSize(), align); + if (LessOrEqual(textRect_.Height(), content->GetRect().Height())) { + textRect_.SetOffset(OffsetF(pattern->GetTextRect().GetOffset().GetX(), textRectOffSet.GetY())); + } else { + textRect_.SetOffset(pattern->GetTextRect().GetOffset()); + } + } else { + if (isInlineStyle) { + content->SetOffset(pattern->GetUtilPadding().Offset()); + } else { + content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), + pattern->GetUtilPadding().Offset().GetY() + pattern->GetBorderTop())); + } + textRect_.SetOffset(pattern->GetTextRect().GetOffset()); + } + + // CounterNode Layout. + if (layoutProperty->GetShowCounterValue(false) && layoutProperty->HasMaxLength() && !isInlineStyle) { + CounterLayout(layoutWrapper); + } +} + +void TextAreaLayoutAlgorithm::CounterLayout(LayoutWrapper* layoutWrapper) +{ + auto counterNodeLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + if (counterNodeLayoutWrapper) { + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto frameRect = layoutWrapper->GetGeometryNode()->GetFrameRect(); + auto textGeometryNode = counterNodeLayoutWrapper->GetGeometryNode(); + CHECK_NULL_VOID(textGeometryNode); + const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); + CHECK_NULL_VOID(content); + textGeometryNode->SetFrameOffset(OffsetF(content->GetRect().GetX(), + frameRect.Height() - pattern->GetPaddingBottom() - textGeometryNode->GetFrameRect().Height())); + counterNodeLayoutWrapper->Layout(); + } +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h new file mode 100644 index 00000000000..24994d96f45 --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_PATTERN_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_PATTERN_H + +#include "core/components_ng/pattern/text_field/text_field_layout_algorithm.h" +namespace OHOS::Ace::NG { +class TextAreaLayoutAlgorithm : public TextFieldLayoutAlgorithm { + DECLARE_ACE_TYPE(TextAreaLayoutAlgorithm, TextFieldLayoutAlgorithm); + +public: + TextAreaLayoutAlgorithm() = default; + ~TextAreaLayoutAlgorithm() override = default; + + void Measure(LayoutWrapper* layoutWrapper) override; + std::optional MeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) override; + void Layout(LayoutWrapper* layoutWrapper) override; + +private: + void CounterNodeMeasureContent(uint32_t textLength, uint32_t maxLength, const LayoutConstraintF& contentConstraint, + RefPtr& layoutWrapper); + + void CounterLayout(LayoutWrapper* layoutWrapper); +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_PATTERN_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_pattern.h b/frameworks/core/components_ng/pattern/text_area/text_area_pattern.h new file mode 100644 index 00000000000..c48f8244945 --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_area/text_area_pattern.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_LAYOUT_ALGORITHM_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_LAYOUT_ALGORITHM_H + +#include "core/components_ng/pattern/text_area/text_area_layout_algorithm.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" +namespace OHOS::Ace::NG { +class TextAreaPattern : public TextFieldPattern { + DECLARE_ACE_TYPE(TextAreaPattern, TextFieldPattern); + +public: + TextAreaPattern(); + ~TextAreaPattern() override; + RefPtr CreateLayoutAlgorithm() override + { + return MakeRefPtr(); + } +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_AREA_TEXT_AREA_LAYOUT_ALGORITHM_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_drag/text_drag_base.h b/frameworks/core/components_ng/pattern/text_drag/text_drag_base.h index 375a8881085..ae06c7acd5b 100644 --- a/frameworks/core/components_ng/pattern/text_drag/text_drag_base.h +++ b/frameworks/core/components_ng/pattern/text_drag/text_drag_base.h @@ -41,11 +41,7 @@ public: virtual const RectF& GetTextContentRect() const = 0; virtual float GetLineHeight() const = 0; -#ifndef USE_GRAPHIC_TEXT_GINE - virtual std::vector GetTextBoxes() = 0; -#else - virtual std::vector GetTextBoxes() = 0; -#endif + virtual std::vector GetTextBoxes() = 0; virtual OffsetF GetParentGlobalOffset() const = 0; virtual RefPtr MoveDragNode() = 0; @@ -53,12 +49,12 @@ public: virtual ParagraphT GetDragParagraph() const = 0; virtual void CloseSelectOverlay() = 0; - virtual void CreateHandles() = 0; + virtual void CreateHandles() {}; virtual bool CloseKeyboard(bool forceClose) = 0; virtual OffsetF GetDragUpperLeftCoordinates() = 0; virtual void InitSpanImageLayout(const std::vector& placeHolderIndex, - const std::vector& rectsForPlaceholders, OffsetF contentOffset) {} + const std::vector& rectsForPlaceholders, OffsetF contentOffset) {} virtual OffsetF GetContentOffset() { diff --git a/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.cpp b/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.cpp index 74bcc4a79b7..20e1cfa42d4 100644 --- a/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.cpp @@ -72,17 +72,10 @@ TextDragData TextDragPattern::CalculateTextDragData(RefPtr& hostPa CHECK_NULL_RETURN(!boxes.empty(), {}); auto boxFirst = boxes.front(); auto boxLast = boxes.back(); -#ifndef USE_GRAPHIC_TEXT_GINE - float leftHandleX = boxFirst.rect_.GetLeft() + textStartX; - float leftHandleY = boxFirst.rect_.GetTop() + textStartY; - float rightHandleX = boxLast.rect_.GetRight() + textStartX; - float rightHandleY = boxLast.rect_.GetTop() + textStartY; -#else - float leftHandleX = boxFirst.rect.GetLeft() + textStartX; - float leftHandleY = boxFirst.rect.GetTop() + textStartY; - float rightHandleX = boxLast.rect.GetRight() + textStartX; - float rightHandleY = boxLast.rect.GetTop() + textStartY; -#endif + float leftHandleX = boxFirst.Left() + textStartX; + float leftHandleY = boxFirst.Top() + textStartY; + float rightHandleX = boxLast.Right() + textStartX; + float rightHandleY = boxLast.Top() + textStartY; bool oneLineSelected = (leftHandleY == rightHandleY); if (oneLineSelected) { if (leftHandleX < contentRect.Left()) { @@ -96,11 +89,7 @@ TextDragData TextDragPattern::CalculateTextDragData(RefPtr& hostPa leftHandleX = contentRect.Left(); leftHandleY = contentRect.Top(); } -#ifndef USE_GRAPHIC_TEXT_GINE - if ((boxLast.rect_.GetBottom() + textStartY) > contentRect.Bottom()) { -#else - if ((boxLast.rect.GetBottom() + textStartY) > contentRect.Bottom()) { -#endif + if ((boxLast.Bottom() + textStartY) > contentRect.Bottom()) { rightHandleX = contentRect.Right(); rightHandleY = contentRect.Bottom() - lineHeight; } @@ -116,22 +105,14 @@ TextDragData TextDragPattern::CalculateTextDragData(RefPtr& hostPa width += delta; globalX -= delta / 2; // 2 : half } -#ifndef USE_GRAPHIC_TEXT_GINE - dragPattern->SetContentOffset(OffsetF(boxes.front().rect_.GetLeft() - TEXT_DRAG_OFFSET.ConvertToPx(), - boxes.front().rect_.GetTop() - TEXT_DRAG_OFFSET.ConvertToPx())); -#else - dragPattern->SetContentOffset(OffsetF(boxes.front().rect.GetLeft() - TEXT_DRAG_OFFSET.ConvertToPx(), - boxes.front().rect.GetTop() - TEXT_DRAG_OFFSET.ConvertToPx())); -#endif + + dragPattern->SetContentOffset(OffsetF(boxes.front().Left() - TEXT_DRAG_OFFSET.ConvertToPx(), + boxes.front().Top() - TEXT_DRAG_OFFSET.ConvertToPx())); } else { globalX = contentRect.Left() + hostGlobalOffset.GetX() - TEXT_DRAG_OFFSET.ConvertToPx(); width = contentRect.Width(); dragPattern->SetContentOffset( -#ifndef USE_GRAPHIC_TEXT_GINE - OffsetF(0 - TEXT_DRAG_OFFSET.ConvertToPx(), boxes.front().rect_.GetTop() - TEXT_DRAG_OFFSET.ConvertToPx())); -#else - OffsetF(0 - TEXT_DRAG_OFFSET.ConvertToPx(), boxes.front().rect.GetTop() - TEXT_DRAG_OFFSET.ConvertToPx())); -#endif + OffsetF(0 - TEXT_DRAG_OFFSET.ConvertToPx(), boxes.front().Top() - TEXT_DRAG_OFFSET.ConvertToPx())); } dragContext->UpdatePosition(OffsetT(Dimension(globalX), Dimension(globalY))); RectF dragTextRect( diff --git a/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.h b/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.h index 5e729a07932..0ed2aa55289 100644 --- a/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.h +++ b/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.h @@ -156,7 +156,7 @@ public: } void InitSpanImageLayout( - const std::list>& imageChildren, const std::vector& rectsForPlaceholders) + const std::list>& imageChildren, const std::vector& rectsForPlaceholders) { imageChildren_ = imageChildren; rectsForPlaceholders_ = rectsForPlaceholders; @@ -172,7 +172,7 @@ public: contentOffset_ = contentOffset; } - const std::vector& GetRectsForPlaceholders() + const std::vector& GetRectsForPlaceholders() { return rectsForPlaceholders_; } @@ -200,7 +200,7 @@ private: std::shared_ptr clipPath_; std::shared_ptr backGroundPath_; std::list> imageChildren_; - std::vector rectsForPlaceholders_; + std::vector rectsForPlaceholders_; ACE_DISALLOW_COPY_AND_MOVE(TextDragPattern); }; diff --git a/frameworks/core/components_ng/pattern/text_field/BUILD.gn b/frameworks/core/components_ng/pattern/text_field/BUILD.gn index 89a0974e33a..ef0118071f5 100644 --- a/frameworks/core/components_ng/pattern/text_field/BUILD.gn +++ b/frameworks/core/components_ng/pattern/text_field/BUILD.gn @@ -16,6 +16,7 @@ import( build_component_ng("text_field_pattern_ng") { sources = [ + "content_controller.cpp", "key_event_handler.cpp", "text_field_accessibility_property.cpp", "text_field_content_modifier.cpp", @@ -27,6 +28,8 @@ build_component_ng("text_field_pattern_ng") { "text_field_paint_method.cpp", "text_field_paint_property.cpp", "text_field_pattern.cpp", + "text_input_response_area.cpp", + "text_select_controller.cpp", ] standard_input_sources = [ "on_text_changed_listener_impl.cpp" ] diff --git a/frameworks/core/components_ng/pattern/text_field/content_controller.cpp b/frameworks/core/components_ng/pattern/text_field/content_controller.cpp new file mode 100644 index 00000000000..30560405d1b --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/content_controller.cpp @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "core/components_ng/pattern/text_field/content_controller.h" + +#include +#include +#include + +#include "base/utils/string_utils.h" +#include "base/utils/utils.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" + +namespace OHOS::Ace::NG { +namespace { +const std::string DIGIT_WHITE_LIST = "[0-9]"; +const std::string PHONE_WHITE_LIST = R"([\d\-\+\*\#]+)"; +const std::string EMAIL_WHITE_LIST = "[\\w.\\@]"; +const std::string URL_WHITE_LIST = "[a-zA-z]+://[^\\s]*"; +} // namespace + +void ContentController::InsertValue(int32_t index, const std::string& value) +{ + ReplaceSelectedValue(index, index, value); +} + +void ContentController::ReplaceSelectedValue(int32_t startIndex, int32_t endIndex, const std::string& value) +{ + FormatIndex(startIndex, endIndex); + auto wideText = GetWideText(); + content_ = StringUtils::ToString(wideText.substr(0, startIndex)) + value + + StringUtils::ToString(wideText.substr(endIndex, static_cast(wideText.length()) - endIndex)); + FilterValue(); +} + +std::string ContentController::GetSelectedValue(int32_t startIndex, int32_t endIndex) +{ + FormatIndex(startIndex, endIndex); + auto wideText = GetWideText(); + return StringUtils::ToString(wideText.substr(startIndex, endIndex - startIndex)); +} + +void ContentController::FormatIndex(int32_t& startIndex, int32_t& endIndex) +{ + startIndex = std::min(startIndex, endIndex); + endIndex = std::max(startIndex, endIndex); + auto wideText = GetWideText(); + startIndex = std::clamp(startIndex, 0, static_cast(wideText.length())); + endIndex = std::clamp(endIndex, 0, static_cast(wideText.length())); +} + +void ContentController::FilterTextInputStyle(bool& textChanged, std::string& result) +{ + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textField = DynamicCast(pattern); + CHECK_NULL_VOID(textField); + auto property = textField->GetLayoutProperty(); + if (!property->GetTextInputType().has_value()) { + return; + } + switch (property->GetTextInputType().value()) { + case TextInputType::NUMBER: { + textChanged |= FilterWithEvent(DIGIT_WHITE_LIST, result); + break; + } + case TextInputType::PHONE: { + textChanged |= FilterWithEvent(PHONE_WHITE_LIST, result); + break; + } + case TextInputType::EMAIL_ADDRESS: { + textChanged |= FilterWithEvent(EMAIL_WHITE_LIST, result); + textChanged |= FilterWithEmail(result); + break; + } + case TextInputType::URL: { + textChanged |= FilterWithEvent(URL_WHITE_LIST, result); + break; + } + case TextInputType::VISIBLE_PASSWORD: { + textChanged |= FilterWithAscii(result); + break; + } + default: { + break; + } + } +} + +void ContentController::FilterValue() +{ + bool textChanged = false; + auto result = content_; + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textField = DynamicCast(pattern); + CHECK_NULL_VOID(textField); + auto property = textField->GetLayoutProperty(); + if (property->GetInputFilter().has_value() && !content_.empty()) { + textChanged |= FilterWithEvent(property->GetInputFilter().value(), result); + } + FilterTextInputStyle(textChanged, result); + if (textChanged) { + content_ = result; + } + auto maxLength = + property->HasMaxLength() ? property->GetMaxLengthValue(Infinity()) : Infinity(); + auto textWidth = static_cast(GetWideText().length()); + if (GreatNotEqual(textWidth, maxLength)) { + content_ = StringUtils::ToString(GetWideText().substr(0, maxLength)); + } +} + +std::string ContentController::RemoveErrorTextFromValue(const std::string& value, const std::string& errorText) +{ + std::string result; + int32_t valuePtr = 0; + int32_t errorTextPtr = 0; + auto valueSize = static_cast(value.length()); + auto errorTextSize = static_cast(errorText.length()); + while (errorTextPtr < errorTextSize) { + while (value[valuePtr] != errorText[errorTextPtr] && valuePtr < valueSize) { + result += value[valuePtr]; + valuePtr++; + } + // no more text left to remove in value + if (valuePtr >= valueSize) { + return result; + } + // increase both value ptr and error text ptr if char in value is removed + valuePtr++; + errorTextPtr++; + } + result += value.substr(valuePtr); + return result; +} + +std::string ContentController::FilterWithRegex(const std::string& filter, std::string& result) +{ + std::regex filterRegex(filter); + auto errorText = regex_replace(result, filterRegex, ""); + result = RemoveErrorTextFromValue(result, errorText); + return errorText; +} + +bool ContentController::FilterWithEmail(std::string& result) +{ + auto valueToUpdate = result; + bool first = true; + std::replace_if( + result.begin(), result.end(), + [&first](const char c) { + if (c == '@' && !first) { + return true; + } + if (c == '@') { + first = false; + } + return false; + }, + ' '); + + // remove the spaces + result.erase(std::remove(result.begin(), result.end(), ' '), result.end()); + return result != valueToUpdate; +} + +bool ContentController::FilterWithAscii(std::string& result) +{ + if (result.empty()) { + LOGD("Text is empty or filter is empty"); + return false; + } + auto valueToUpdate = result; + bool textChange = true; + std::string errorText; + result.clear(); + for (char valuePtr : valueToUpdate) { + if (isascii(valuePtr)) { + result += valuePtr; + } else { + errorText += valuePtr; + } + } + if (errorText.empty()) { + textChange = false; + } else { + LOGI("FilterWithAscii Error text %{private}s", errorText.c_str()); + } + return textChange; +} + +bool ContentController::FilterWithEvent(const std::string& filter, std::string& result) +{ + auto errorValue = FilterWithRegex(filter, result); + if (!errorValue.empty()) { + auto pattern = pattern_.Upgrade(); + CHECK_NULL_RETURN(pattern, false); + auto textField = DynamicCast(pattern); + CHECK_NULL_RETURN(textField, false); + auto host = textField->GetHost(); + CHECK_NULL_RETURN(host, false); + auto eventHub = host->GetEventHub(); + eventHub->FireOnInputFilterError(errorValue); + auto textFieldAccessibilityProperty = host->GetAccessibilityProperty(); + CHECK_NULL_RETURN(textFieldAccessibilityProperty, false); + textFieldAccessibilityProperty->SetErrorText(errorValue); + } + return !errorValue.empty(); +} + +void ContentController::erase(int32_t startIndex, int32_t length) +{ + auto wideText = GetWideText().erase(startIndex, length); + content_ = StringUtils::ToString(wideText); +} + +std::string ContentController::GetValueBeforeIndex(int32_t index) +{ + return StringUtils::ToString(GetWideText().substr(0, index)); +} + +std::string ContentController::GetValueAfterIndex(int32_t index) +{ + return StringUtils::ToString(GetWideText().substr(index, GetWideText().length() - index)); +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/content_controller.h b/frameworks/core/components_ng/pattern/text_field/content_controller.h new file mode 100644 index 00000000000..517673d3712 --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/content_controller.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_CONTENT_CONTROLLER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_CONTENT_CONTROLLER_H + +#include +#include + +#include "foundation/graphic/graphic_utils_lite/interfaces/kits/gfx_utils/graphic_types.h" + +#include "base/memory/ace_type.h" +#include "base/memory/referenced.h" +#include "base/utils/string_utils.h" +#include "core/common/ime/text_input_type.h" +#include "core/components_ng/pattern/pattern.h" + +namespace OHOS::Ace::NG { + +class ContentController : public virtual AceType { + DECLARE_ACE_TYPE(ContentController, AceType); + +public: + explicit ContentController(const WeakPtr& pattern) : pattern_(pattern) {} + ~ContentController() override = default; + void InsertValue(int32_t index, const std::string& value); + void ReplaceSelectedValue(int32_t startIndex, int32_t endIndex, const std::string& value); + std::string GetSelectedValue(int32_t startIndex, int32_t endIndex); + std::string GetValueBeforeIndex(int32_t index); + std::string GetValueAfterIndex(int32_t index); + void erase(int32_t startIndex, int32_t length); + void FilterValue(); + + std::wstring GetWideText() + { + return StringUtils::ToWstring(content_); + } + + std::string GetTextValue() + { + return content_; + } + + bool IsEmpty() + { + return content_.empty(); + } + + void SetTextValue(std::string&& value) + { + content_ = value; + FilterValue(); + } + + void SetTextValue(const std::string& value) + { + content_ = value; + FilterValue(); + } + + void Reset() + { + content_ = ""; + } + +private: + void FormatIndex(int32_t& startIndex, int32_t& endIndex); + void FilterTextInputStyle(bool& textChanged, std::string& result); + bool FilterWithEvent(const std::string& filter, std::string& result); + static std::string RemoveErrorTextFromValue(const std::string& value, const std::string& errorText); + static std::string FilterWithRegex(const std::string& filter, std::string& result); + static bool FilterWithEmail(std::string& result); + static bool FilterWithAscii(std::string& result); + + std::string content_; + WeakPtr pattern_; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_CONTENT_CONTROLLER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp b/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp index 622ba75a5b8..430924be26b 100644 --- a/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp +++ b/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp @@ -27,7 +27,7 @@ namespace { #define KEY_META_OR_CTRL_LEFT KeyCode::KEY_CTRL_LEFT #define KEY_META_OR_CTRL_RIGHT KeyCode::KEY_CTRL_RIGHT #endif -} +} // namespace bool KeyEventHandler::HandleKeyEvent(const KeyEvent& keyEvent) { LOGD("HandleKeyEvent event, caps lock %{public}d, key code %{public}d", keyEvent.enableCapsLock, keyEvent.code); @@ -89,21 +89,21 @@ bool KeyEventHandler::HandleKeyEvent(const KeyEvent& keyEvent) } if (keyEvent.code == KeyCode::KEY_DEL) { #if defined(PREVIEW) - pattern->DeleteForward(TextFieldPattern::GetGraphemeClusterLength( - pattern->GetEditingValue().GetWideText(), pattern->GetEditingValue().caretPosition)); + pattern->DeleteForward( + TextFieldPattern::GetGraphemeClusterLength(pattern->GetWideText(), pattern->GetCaretIndex())); #else - pattern->DeleteBackward(TextFieldPattern::GetGraphemeClusterLength( - pattern->GetEditingValue().GetWideText(), pattern->GetEditingValue().caretPosition, true)); + pattern->DeleteBackward( + TextFieldPattern::GetGraphemeClusterLength(pattern->GetWideText(), pattern->GetCaretIndex(), true)); #endif return true; } if (keyEvent.code == KeyCode::KEY_FORWARD_DEL) { #if defined(PREVIEW) pattern->DeleteBackward(TextFieldPattern::GetGraphemeClusterLength( - pattern->GetEditingValue().GetWideText(), pattern->GetEditingValue().caretPosition, true)); + pattern->GetWideText(), pattern->GetCaretIndex().caretPosition, true)); #else - pattern->DeleteForward(TextFieldPattern::GetGraphemeClusterLength( - pattern->GetEditingValue().GetWideText(), pattern->GetEditingValue().caretPosition)); + pattern->DeleteForward( + TextFieldPattern::GetGraphemeClusterLength(pattern->GetWideText(), pattern->GetCaretIndex())); #endif return true; } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp index c869ccdc601..4e43d4d84da 100755 --- a/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp @@ -102,7 +102,9 @@ int32_t TextFieldAccessibilityProperty::GetTextSelectionStart() const CHECK_NULL_RETURN(frameNode, -1); auto textFieldPattern = frameNode->GetPattern(); CHECK_NULL_RETURN(textFieldPattern, -1); - return textFieldPattern->GetTextSelector().GetStart(); + auto textSelectController = textFieldPattern->GetTextSelectController(); + CHECK_NULL_RETURN(textSelectController, -1); + return textSelectController->GetStartIndex(); } int32_t TextFieldAccessibilityProperty::GetTextSelectionEnd() const @@ -111,7 +113,9 @@ int32_t TextFieldAccessibilityProperty::GetTextSelectionEnd() const CHECK_NULL_RETURN(frameNode, -1); auto textFieldPattern = frameNode->GetPattern(); CHECK_NULL_RETURN(textFieldPattern, -1); - return textFieldPattern->GetTextSelector().GetEnd(); + auto textSelectController = textFieldPattern->GetTextSelectController(); + CHECK_NULL_RETURN(textSelectController, -1); + return textSelectController->GetEndIndex(); } std::string TextFieldAccessibilityProperty::GetText() const @@ -133,11 +137,8 @@ bool TextFieldAccessibilityProperty::IsHint() const CHECK_NULL_RETURN(frameNode, false); auto textFieldLayoutProperty = frameNode->GetLayoutProperty(); CHECK_NULL_RETURN(textFieldLayoutProperty, false); - if (!textFieldLayoutProperty->GetValueValue("").empty() || - textFieldLayoutProperty->GetPlaceholderValue("").empty()) { - return false; - } - return true; + return !(!textFieldLayoutProperty->GetValueValue("").empty() || + textFieldLayoutProperty->GetPlaceholderValue("").empty()); } std::string TextFieldAccessibilityProperty::GetHintText() const diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp index 4ac3a2d20a6..372d29b0d36 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp @@ -44,7 +44,6 @@ const FontWeight FONT_WEIGHT_CONVERT_MAP[] = { }; constexpr Dimension ERROR_TEXT_UNDERLINE_MARGIN = 8.0_vp; constexpr Dimension ERROR_TEXT_CAPSULE_MARGIN = 8.0_vp; -constexpr Dimension COUNTER_TEXT_AREA_MARGIN = 8.0_vp; inline FontWeight ConvertFontWeight(FontWeight fontWeight) { @@ -64,15 +63,10 @@ void TextFieldContentModifier::onDraw(DrawingContext& context) auto textFieldPattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(textFieldPattern); auto offset = contentOffset_->Get(); - auto passwordIconCanvasImage = textObscured_->Get() ? textFieldPattern->GetHidePasswordIconCanvasImage() - : textFieldPattern->GetShowPasswordIconCanvasImage(); auto paragraph = textFieldPattern->GetParagraph(); CHECK_NULL_VOID(paragraph); - auto contentSize = contentSize_->Get(); auto textFrameRect = textFieldPattern->GetFrameRect(); auto contentOffset = contentOffset_->Get(); - auto iconRect = textFieldPattern->GetImageRect(); - auto counterParagraph = textFieldPattern->GetCounterParagraph(); auto errorParagraph = textFieldPattern->GetErrorParagraph(); auto contentRect = textFieldPattern->GetContentRect(); auto clipRectHeight = 0.0f; @@ -96,66 +90,22 @@ void TextFieldContentModifier::onDraw(DrawingContext& context) if (errorParagraph && showErrorState_->Get()) { errorViewHeight = textFrameRect.Bottom() - textFrameRect.Top() + errorMargin; } - if (showCounter_->Get() && counterParagraph && !textFieldPattern->GetIsCounterIdealHeight()) { - clipRectHeight = contentRect.GetY() + contentRect.Height() - textFieldPattern->GetCountHeight(); - } else { - clipRectHeight = contentRect.GetY() + contentRect.Height() + errorViewHeight; - } + clipRectHeight = contentRect.GetY() + contentRect.Height() + errorViewHeight; canvas.Save(); - RSRect clipInnerRect = RSRect(contentRect.GetX(), contentRect.GetY(), contentRect.Width() + contentRect.GetX() - - textFieldPattern->GetUnitWidth() + textFieldPattern->GetInlinePadding(), clipRectHeight); + RSRect clipInnerRect = RSRect(contentRect.GetX(), contentRect.GetY(), + contentRect.Width() + contentRect.GetX() + textFieldPattern->GetInlinePadding(), + clipRectHeight); canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT); if (paragraph) { - paragraph->Paint(&canvas, textFieldPattern->GetTextRect().GetX(), + paragraph->Paint(canvas, textFieldPattern->GetTextRect().GetX(), textFieldPattern->IsTextArea() ? textFieldPattern->GetTextRect().GetY() : contentOffset.GetY()); } - canvas.Restore(); - if (showCounter_->Get() && counterParagraph) { - counterParagraph->Paint(&canvas, textRectX_->Get(), - textFrameRect.Bottom() - textFrameRect.Top() - COUNTER_TEXT_AREA_MARGIN.ConvertToPx() - - textFieldPattern->GetCountHeight()); - } - canvas.Save(); if (showErrorState_->Get() && errorParagraph && !textFieldPattern->IsDisabled()) { - errorParagraph->Paint(&canvas, offset.GetX(), textFrameRect.Bottom() - textFrameRect.Top() + errorMargin); - } - - clipInnerRect = RSRect(contentSize.Width() + contentOffset.GetX() - textFieldPattern->GetUnitWidth(), - contentOffset.GetY(), contentSize.Width() + contentOffset.GetX(), contentOffset.GetY() + contentSize.Height()); - canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT); - canvas.Restore(); - - if (!textFieldPattern->NeedShowPasswordIcon()) { - return; + errorParagraph->Paint(canvas, offset.GetX(), textFrameRect.Bottom() - textFrameRect.Top() + errorMargin); } - CHECK_NULL_VOID(passwordIconCanvasImage); - UpdatePaintConfig(passwordIconCanvasImage, context, iconRect); - const ImagePainter passwordIconImagePainter(passwordIconCanvasImage); - canvas.Save(); - auto iconRight = std::min(textFrameRect.Width(), iconRect.Width()) + iconRect.GetX(); - auto iconBottom = std::min(textFrameRect.Height(), iconRect.Height()) + iconRect.GetY(); - clipInnerRect = RSRect(iconRect.GetX(), iconRect.GetY(), iconRight, iconBottom); - canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT); - passwordIconImagePainter.DrawImage(canvas, iconRect.GetOffset(), iconRect.GetSize()); canvas.Restore(); } -void TextFieldContentModifier::UpdatePaintConfig( - RefPtr& passwordIconCanvasImage, DrawingContext context, RectF iconRect) const -{ - CHECK_NULL_VOID(passwordIconCanvasImage); - auto&& config = passwordIconCanvasImage->GetPaintConfig(); - config.renderMode_ = ImageRenderMode::ORIGINAL; - config.imageInterpolation_ = ImageInterpolation::NONE; - config.imageRepeat_ = ImageRepeat::NO_REPEAT; - config.imageFit_ = ImageFit::FILL; - if (context.height == 0 || context.width == 0) { - return; - } - config.scaleX_ = iconRect.GetSize().Width() / context.width; - config.scaleY_ = iconRect.GetSize().Height() / context.height; -} - void TextFieldContentModifier::SetDefaultAnimatablePropertyValue() { RefPtr theme; @@ -201,10 +151,7 @@ void TextFieldContentModifier::SetDefaultPropertyValue() textRectY_ = AceType::MakeRefPtr(textFieldPattern->GetTextRect().GetY()); textRectX_ = AceType::MakeRefPtr(textFieldPattern->GetTextRect().GetX()); textAlign_ = AceType::MakeRefPtr(static_cast(TextAlign::START)); - showCounter_ = AceType::MakeRefPtr(false); showErrorState_ = AceType::MakeRefPtr(false); - showPasswordIconSrc_ = AceType::MakeRefPtr(""); - hidePasswordIconSrc_ = AceType::MakeRefPtr(""); fontFamilyString_ = AceType::MakeRefPtr(""); fontReady_ = AceType::MakeRefPtr(false); AttachProperty(contentOffset_); @@ -217,11 +164,8 @@ void TextFieldContentModifier::SetDefaultPropertyValue() AttachProperty(dragStatus_); AttachProperty(textRectX_); AttachProperty(textAlign_); - AttachProperty(showCounter_); AttachProperty(showErrorState_); AttachProperty(showUnderline_); - AttachProperty(showPasswordIconSrc_); - AttachProperty(hidePasswordIconSrc_); AttachProperty(fontFamilyString_); AttachProperty(fontReady_); } @@ -393,13 +337,6 @@ void TextFieldContentModifier::SetTextAlign(const TextAlign value) } } -void TextFieldContentModifier::SetShowCounter(bool value) -{ - if (showCounter_) { - showCounter_->Set(value); - } -} - void TextFieldContentModifier::SetShowErrorState(bool value) { if (showErrorState_) { @@ -414,20 +351,6 @@ void TextFieldContentModifier::SetShowUnderlineState(bool value) } } -void TextFieldContentModifier::SetShowPasswordIcon(const std::string& value) -{ - if (showPasswordIconSrc_->Get() != value) { - showPasswordIconSrc_->Set(value); - } -} - -void TextFieldContentModifier::SetHidePasswordIcon(const std::string& value) -{ - if (hidePasswordIconSrc_->Get() != value) { - hidePasswordIconSrc_->Set(value); - } -} - void TextFieldContentModifier::SetFontReady(bool value) { if (fontReady_) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.h b/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.h index 2c1863ffdc3..c0a17f776fd 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.h @@ -55,12 +55,9 @@ public: void SetTextRectX(const float value); float GetTextRectY(); void SetTextAlign(const TextAlign value); - void SetShowCounter(bool value); bool NeedMeasureUpdate(PropertyChangeFlag& flag); void SetShowErrorState(bool value); void SetShowUnderlineState(bool value); - void SetShowPasswordIcon(const std::string& value); - void SetHidePasswordIcon(const std::string& value); void SetFontReady(bool value); private: @@ -69,7 +66,6 @@ private: void SetDefaultTextColor(const TextStyle& textStyle); void SetDefaultFontStyle(const TextStyle& textStyle); void SetDefaultPropertyValue(); - void UpdatePaintConfig(RefPtr& passwordIconCanvasImage, DrawingContext context, RectF iconRect) const; WeakPtr pattern_; RefPtr fontFamilyString_; @@ -93,11 +89,8 @@ private: RefPtr textObscured_; RefPtr dragStatus_; RefPtr textAlign_; - RefPtr showCounter_; RefPtr showErrorState_; RefPtr showUnderline_; - RefPtr showPasswordIconSrc_; - RefPtr hidePasswordIconSrc_; RefPtr fontStyle_; RefPtr fontReady_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp index 31b89e7a811..601ba2aa8db 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp @@ -17,7 +17,6 @@ #include "base/geometry/axis.h" #include "base/geometry/dimension.h" -#include "base/geometry/ng/offset_t.h" #include "base/geometry/ng/rect_t.h" #include "base/geometry/ng/size_t.h" #include "base/i18n/localization.h" @@ -34,180 +33,26 @@ #include "core/components_ng/pattern/text_field/text_field_pattern.h" #include "core/components_ng/pattern/text_field/text_selector.h" #include "core/components_ng/property/measure_utils.h" -#include "core/components_ng/render/drawing_prop_convertor.h" #include "core/pipeline_ng/pipeline_context.h" namespace OHOS::Ace::NG { namespace { -constexpr uint32_t COUNTER_TEXT_MAXLINE = 1; constexpr float PARAGRAPH_SAVE_BOUNDARY = 1.0f; } // namespace - -void TextFieldLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +void TextFieldLayoutAlgorithm::ConstructTextStyles( + const RefPtr& frameNode, TextStyle& textStyle, std::string& textContent, bool& showPlaceHolder) { - const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint(); - OptionalSizeF frameSize = - CreateIdealSize(layoutConstraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT_MAIN_AXIS); - const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); - const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); - auto frameNode = layoutWrapper->GetHostNode(); CHECK_NULL_VOID(frameNode); - auto pattern = frameNode->GetPattern(); - CHECK_NULL_VOID(pattern); - float contentWidth = 0.0f; - float contentHeight = 0.0f; - if (content) { - auto contentSize = content->GetRect().GetSize(); - contentWidth = contentSize.Width(); - contentHeight = contentSize.Height(); - } - if (pattern->IsTextArea()) { - if (!frameSize.Width().has_value()) { - // If width is not set, select the maximum value of minWidth and maxWidth to layoutConstraint - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Width().has_value()) { - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Width(), contentWidth + pattern->GetHorizontalPaddingSum())); - } else if (!calcLayoutConstraint) { - // If calcLayoutConstraint has not set, use the LayoutConstraint initial value - frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum()); - } else { - // If maxWidth is not set and calcLayoutConstraint is set, set minWidth to layoutConstraint - frameSize.SetWidth(layoutConstraint->minSize.Width()); - } - } - if (pattern->IsNormalInlineState()) { - frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum() + PARAGRAPH_SAVE_BOUNDARY); - } - if (!frameSize.Height().has_value()) { - // Like width - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Height().has_value()) { - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { - // calcLayoutConstraint initialized once when setting width, set minHeight=0, - // so add "minHeight=0" to the constraint. - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } else { - frameSize.SetHeight( - std::max(layoutConstraint->minSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } - } - - // Here's what happens when the height or width is set at list one - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { - frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); - } else { - auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, - layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), - layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - frameSize.SetWidth(finalSize.Width()); - frameSize.SetHeight(finalSize.Height()); - } - if (layoutConstraint->maxSize.Height() < layoutConstraint->minSize.Height()) { - frameSize.SetHeight(layoutConstraint->minSize.Height()); - } - if (layoutConstraint->maxSize.Width() < layoutConstraint->minSize.Width()) { - frameSize.SetWidth(layoutConstraint->minSize.Width()); - } - layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); - - frameRect_ = - RectF(layoutWrapper->GetGeometryNode()->GetFrameOffset(), layoutWrapper->GetGeometryNode()->GetFrameSize()); - return; - } - auto pipeline = PipelineBase::GetCurrentContext(); + auto pipeline = frameNode->GetContext(); CHECK_NULL_VOID(pipeline); auto textFieldTheme = pipeline->GetTheme(); CHECK_NULL_VOID(textFieldTheme); - auto defaultHeight = textFieldTheme->GetHeight().ConvertToPx(); - if (!frameSize.Height().has_value()) { - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Height().has_value()) { - frameSize.SetHeight(std::max(layoutConstraint->maxSize.Height(), layoutConstraint->minSize.Height())); - } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { - auto height = contentHeight + pattern->GetVerticalPaddingSum() < defaultHeight - ? defaultHeight - : contentHeight + pattern->GetVerticalPaddingSum(); - frameSize.SetHeight(std::min(layoutConstraint->maxSize.Height(), static_cast(height))); - } else { - frameSize.SetHeight(layoutConstraint->minSize.Height()); - } - } - auto textfieldLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - CHECK_NULL_VOID(textfieldLayoutProperty); - - if (textfieldLayoutProperty->GetWidthAutoValue(false)) { - auto width = - std::max(std::min(layoutConstraint->maxSize.Width(), contentWidth + pattern->GetHorizontalPaddingSum()), - layoutConstraint->minSize.Width()); - frameSize.SetWidth(width); - } - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { - frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); - } else { - auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, - layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), - layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - frameSize.SetWidth(finalSize.Width()); - frameSize.SetHeight(finalSize.Height()); - } - if (layoutConstraint->maxSize.Height() < layoutConstraint->minSize.Height()) { - frameSize.SetHeight(layoutConstraint->minSize.Height()); - } - if (layoutConstraint->maxSize.Width() < layoutConstraint->minSize.Width()) { - frameSize.SetWidth(layoutConstraint->minSize.Width()); - } - layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); - frameRect_ = - RectF(layoutWrapper->GetGeometryNode()->GetFrameOffset(), layoutWrapper->GetGeometryNode()->GetFrameSize()); - - auto children = frameNode->GetChildren(); - auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); - CHECK_NULL_VOID(layoutProperty); - if (!children.empty() && layoutProperty->GetShowUnderlineValue(false) && - layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::UNSPECIFIED) { - auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); - auto childLayoutConstraint = textfieldLayoutProperty->CreateChildConstraint(); - CHECK_NULL_VOID(childWrapper); - childWrapper->Measure(childLayoutConstraint); - } -} - -std::optional TextFieldLayoutAlgorithm::MeasureContent( - const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) -{ - auto frameNode = layoutWrapper->GetHostNode(); - CHECK_NULL_RETURN(frameNode, std::nullopt); - auto pipeline = frameNode->GetContext(); - CHECK_NULL_RETURN(pipeline, std::nullopt); - auto textFieldLayoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); - CHECK_NULL_RETURN(textFieldLayoutProperty, std::nullopt); - auto textFieldTheme = pipeline->GetTheme(); - CHECK_NULL_RETURN(textFieldTheme, std::nullopt); auto pattern = frameNode->GetPattern(); - CHECK_NULL_RETURN(pattern, std::nullopt); - - // Construct a textstyle. - TextStyle textStyle; - std::string textContent; - bool showPlaceHolder = false; - auto idealWidth = contentConstraint.selfIdealSize.Width().value_or(contentConstraint.maxSize.Width()); - auto idealHeight = contentConstraint.selfIdealSize.Height().value_or(contentConstraint.maxSize.Height()); - auto idealSize = SizeF { idealWidth, idealHeight }; - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { - idealSize.UpdateSizeWhenSmaller(contentConstraint.maxSize); - } else { - auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(static_cast>(idealSize), - layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), - layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - idealSize.UpdateSizeWhenSmaller(finalSize.ConvertToSizeT()); - } - idealWidth = idealSize.Width(); - idealHeight = idealSize.Height(); + CHECK_NULL_VOID(pattern); + auto textFieldLayoutProperty = pattern->GetLayoutProperty(); + CHECK_NULL_VOID(textFieldLayoutProperty); auto isInlineStyle = pattern->IsNormalInlineState(); + if (!textFieldLayoutProperty->GetValueValue("").empty()) { UpdateTextStyle(frameNode, textFieldLayoutProperty, textFieldTheme, textStyle, pattern->IsDisabled()); textContent = textFieldLayoutProperty->GetValueValue(""); @@ -228,278 +73,101 @@ std::optional TextFieldLayoutAlgorithm::MeasureContent( contentModifier->ModifyTextStyle(textStyle); contentModifier->SetFontReady(false); } - auto isPasswordType = - textFieldLayoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD; - auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder && !isInlineStyle; - // Create paragraph. - if (pattern->IsDragging() && !showPlaceHolder) { - TextStyle dragTextStyle = textStyle; - Color color = textStyle.GetTextColor().ChangeAlpha(DRAGGED_TEXT_OPACITY); - dragTextStyle.SetTextColor(color); - std::vector textStyles { textStyle, dragTextStyle, textStyle }; - CreateParagraph(textStyles, pattern->GetDragContents(), textContent, - isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, disableTextAlign); +} + +SizeF TextFieldLayoutAlgorithm::CalculateConstraintSize( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) +{ + // constraint size. + auto idealWidth = contentConstraint.selfIdealSize.Width().value_or(contentConstraint.maxSize.Width()); + auto idealHeight = contentConstraint.selfIdealSize.Height().value_or(contentConstraint.maxSize.Height()); + auto idealSize = SizeF { idealWidth, idealHeight }; + if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { + idealSize.UpdateSizeWhenSmaller(contentConstraint.maxSize); } else { - CreateParagraph(textStyle, textContent, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, - pattern->GetNakedCharPosition(), disableTextAlign); + auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(static_cast>(idealSize), + layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), + layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); + idealSize.UpdateSizeWhenSmaller(finalSize.ConvertToSizeT()); } + idealWidth = idealSize.Width(); + idealHeight = idealSize.Height(); + return SizeF { idealWidth, idealHeight }; +} - // paragraph Layout. - float imageSize = 0.0f; - auto showPasswordIcon = textFieldLayoutProperty->GetShowPasswordIcon().value_or(true); - imageSize = showPasswordIcon ? pattern->GetIconSize() : 0.0f; - auto imageHotZoneWidth = showPasswordIcon ? imageSize + pattern->GetIconRightOffset() : 0.0f; - auto scrollBarTheme = pipeline->GetTheme(); - CHECK_NULL_RETURN(scrollBarTheme, std::nullopt); - const auto& layoutConstraint = textFieldLayoutProperty->GetLayoutConstraint(); - if (isInlineStyle) { - // for InlineStyle, max width is content width with safe boundary. - float inlineBoxWidth = 0.0f; - if (pattern->IsFocus()) { - auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2; - paragraph_->Layout(pattern->GetPreviewWidth() == 0 ? idealWidth : pattern->GetPreviewWidth()); - if (pattern->GetPreviewWidth() != 0 && pattern->GetPreviewWidth() > layoutConstraint->maxSize.Width()) { - paragraph_->Layout(layoutConstraint->maxSize.Width() - safeBoundary - PARAGRAPH_SAVE_BOUNDARY); - } -#ifndef USE_GRAPHIC_TEXT_GINE - inlineBoxWidth = paragraph_->GetLongestLine() + PARAGRAPH_SAVE_BOUNDARY; -#else - inlineBoxWidth = paragraph_->GetActualWidth() + PARAGRAPH_SAVE_BOUNDARY; -#endif - if (inlineBoxWidth > layoutConstraint->maxSize.Width()) { - inlineBoxWidth = layoutConstraint->maxSize.Width() - safeBoundary; - } - paragraph_->Layout(pattern->GetPreviewWidth() == 0 ? idealWidth : inlineBoxWidth); - } else { - inlineBoxWidth = idealWidth; - paragraph_->Layout(inlineBoxWidth); - } - if (pattern->IsTextArea()) { - paragraph_->Layout(pattern->GetPreviewWidth() == 0 ? idealWidth : inlineBoxWidth); - } - } else if (showPlaceHolder) { - // for placeholder. - if (isPasswordType) { - paragraph_->Layout(idealWidth - imageHotZoneWidth); - } else { - paragraph_->Layout(idealWidth); - } - } else if (textStyle.GetMaxLines() == 1) { - // for text input case, need to measure in one line without constraint. - paragraph_->Layout(std::numeric_limits::infinity()); +std::optional TextFieldLayoutAlgorithm::InlineMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, const SizeF& idealSize) +{ + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(frameNode, std::nullopt); + auto pipeline = frameNode->GetContext(); + CHECK_NULL_RETURN(pipeline, std::nullopt); + auto textFieldLayoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_RETURN(textFieldLayoutProperty, std::nullopt); + auto textFieldTheme = pipeline->GetTheme(); + CHECK_NULL_RETURN(textFieldTheme, std::nullopt); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_RETURN(pattern, std::nullopt); + + if (pattern->IsFocus()) { + auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2; + paragraph_->Layout(idealSize.Width() - safeBoundary - PARAGRAPH_SAVE_BOUNDARY); + paragraph_->Layout(std::ceil(paragraph_->GetLongestLine())); } else { - // for text area, max width is content width without scroll bar. - paragraph_->Layout(idealWidth); + paragraph_->Layout(idealSize.Width()); } + textRect_.SetSize(SizeF(paragraph_->GetLongestLine(), paragraph_->GetHeight())); + pattern->SetSingleLineHeight(paragraph_->GetHeight() / paragraph_->GetLineCount()); - // counterParagraph Layout. - if (textFieldLayoutProperty->GetShowCounterValue(false) && textFieldLayoutProperty->HasMaxLength() && - !isInlineStyle) { - auto textLength = showPlaceHolder ? 0 : StringUtils::ToWstring(textContent).length(); - auto maxLength = textFieldLayoutProperty->GetMaxLength().value(); - CreateCounterParagraph(textLength, maxLength, textFieldTheme); - if (counterParagraph_) { - counterParagraph_->Layout(idealWidth); - } - } - // errorParagraph Layout. - if (textFieldLayoutProperty->GetShowErrorTextValue(false)) { - CreateErrorParagraph(textFieldLayoutProperty->GetErrorTextValue(""), textFieldTheme); - if (errorParagraph_) { - errorParagraph_->Layout(std::numeric_limits::infinity()); - } - } - auto paragraphNewWidth = static_cast(paragraph_->GetMaxIntrinsicWidth()); - if (!NearEqual(paragraphNewWidth, paragraph_->GetMaxWidth()) && !pattern->IsTextArea() && !showPlaceHolder && - !isInlineStyle) { - paragraph_->Layout(std::ceil(paragraphNewWidth)); - if (counterParagraph_) { - counterParagraph_->Layout(std::ceil(paragraphNewWidth)); - } - } - auto preferredHeight = static_cast(paragraph_->GetHeight()); - if (textContent.empty() || showPlaceHolder) { - preferredHeight = pattern->PreferredLineHeight(); - } - if (isInlineStyle && showPlaceHolder && !textContent.empty()) { - preferredHeight = static_cast(paragraph_->GetHeight()); - } -#ifndef USE_GRAPHIC_TEXT_GINE // support sigleline - if (isInlineStyle && pattern->IsFocus()) { - pattern->SetSingleLineHeight(preferredHeight); - } -#else // support multi-line - if (isInlineStyle && pattern->IsFocus() && paragraph_->GetLineCount() != 0) { - pattern->SetSingleLineHeight(preferredHeight / paragraph_->GetLineCount()); - } -#endif -#ifndef USE_GRAPHIC_TEXT_GINE - paragraphWidth_ = paragraph_->GetLongestLine(); -#else - paragraphWidth_ = paragraph_->GetActualWidth(); -#endif - // textarea size. - if (pattern->IsTextArea()) { - auto paragraphHeight = - (textContent.empty() || !showPlaceHolder) ? preferredHeight : static_cast(paragraph_->GetHeight()); - auto useHeight = - static_cast(paragraphHeight + (counterParagraph_ ? counterParagraph_->GetHeight() : 0.0f)); - if (isInlineStyle && pattern->IsFocus()) { - idealHeight = pattern->GetSingleLineHeight() * - textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE); -#ifndef USE_GRAPHIC_TEXT_GINE - idealWidth = paragraph_->GetLongestLine(); -#else - idealWidth = paragraph_->GetActualWidth(); -#endif - } - if (counterParagraph_ && idealHeight < useHeight) { - pattern->SetISCounterIdealHeight(true); - idealHeight = idealHeight - counterParagraph_->GetHeight(); - } - textRect_.SetSize( - SizeF(idealWidth, paragraph_->GetHeight())); - return SizeF(idealWidth, std::min(idealHeight, useHeight)); - } - // check password image size. - if (!showPasswordIcon || !isPasswordType) { -#ifndef USE_GRAPHIC_TEXT_GINE - textRect_.SetSize(SizeF(static_cast(paragraph_->GetLongestLine()), preferredHeight)); -#else - textRect_.SetSize(SizeF(static_cast(paragraph_->GetActualWidth()), preferredHeight)); -#endif - imageRect_.Reset(); - if (textFieldLayoutProperty->GetWidthAutoValue(false)) { - if (LessOrEqual(contentConstraint.minSize.Width(), 0.0f)) { - idealWidth = std::clamp(textRect_.GetSize().Width(), 0.0f, contentConstraint.maxSize.Width()); - } else if (LessOrEqual(textRect_.Width(), 0.0f)) { - idealWidth = contentConstraint.minSize.Width(); - } else { - idealWidth = - std::clamp(textRect_.Width(), contentConstraint.minSize.Width(), contentConstraint.maxSize.Width()); - } - } - return SizeF(idealWidth, std::min(preferredHeight, idealHeight)); + auto inlineIdealHieght = idealSize.Height(); + if (pattern->IsFocus()) { + // The maximum height of the inline mode defaults to a maximum of three rows. + inlineIdealHieght = + pattern->GetSingleLineHeight() * textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE); } - // password type size. - imageRect_.SetSize(SizeF(imageSize, imageSize)); - if (pattern->GetTextObscured() && pattern->GetHidePasswordIconCtx()) { - pattern->GetHidePasswordIconCtx()->MakeCanvasImage(imageRect_.GetSize(), true, ImageFit::NONE); - } else if (!pattern->GetTextObscured() && pattern->GetShowPasswordIconCtx()) { - pattern->GetShowPasswordIconCtx()->MakeCanvasImage(imageRect_.GetSize(), true, ImageFit::NONE); - } - preferredHeight = std::min(static_cast(paragraph_->GetHeight()), idealHeight); -#ifndef USE_GRAPHIC_TEXT_GINE - textRect_.SetSize(SizeF(static_cast(paragraph_->GetLongestLine()), static_cast(preferredHeight))); -#else - textRect_.SetSize(SizeF(static_cast(paragraph_->GetActualWidth()), static_cast(preferredHeight))); -#endif - return SizeF(idealWidth - imageHotZoneWidth, std::min(idealHeight, preferredHeight)); + return SizeF( + paragraph_->GetMaxWidth(), std::min(inlineIdealHieght, std::max(preferredHeight_, paragraph_->GetHeight()))); } -void TextFieldLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +SizeF TextFieldLayoutAlgorithm::PlaceHolderMeasureContent(const SizeF& idealSize, float imageWidth) { - // update child position. - auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); - auto frameNode = layoutWrapper->GetHostNode(); - CHECK_NULL_VOID(frameNode); - auto pattern = frameNode->GetPattern(); - CHECK_NULL_VOID(pattern); - const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); - CHECK_NULL_VOID(content); - auto contentSize = content->GetRect().GetSize(); - auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); - CHECK_NULL_VOID(layoutProperty); - auto context = layoutWrapper->GetHostNode()->GetContext(); - CHECK_NULL_VOID(context); - parentGlobalOffset_ = layoutWrapper->GetHostNode()->GetPaintRectOffset() - context->GetRootRect().GetOffset(); - auto align = Alignment::CENTER; - bool hasAlign = false; - if (layoutWrapper->GetLayoutProperty()->GetPositionProperty()) { - align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align); - hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value(); - } - // Update content position. - OffsetF contentOffset = Alignment::GetAlignPosition(size, contentSize, align); - if (pattern->IsTextArea()) { - auto isInlineStyle = pattern->IsNormalInlineState(); - if (hasAlign) { - if (isInlineStyle) { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX(), contentOffset.GetY())); - } else { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), - contentOffset.GetY() + pattern->GetBorderTop())); - } + paragraph_->Layout(idealSize.Width() - imageWidth); + textRect_.SetSize(SizeF(paragraph_->GetLongestLine(), paragraph_->GetHeight())); - OffsetF textRectOffSet = Alignment::GetAlignPosition(size, textRect_.GetSize(), align); - if (LessOrEqual(textRect_.Height(), content->GetRect().Height())) { - textRect_.SetOffset(OffsetF(pattern->GetTextRect().GetOffset().GetX(), textRectOffSet.GetY())); - } else { - textRect_.SetOffset(pattern->GetTextRect().GetOffset()); - } - } else { - if (isInlineStyle) { - content->SetOffset(pattern->GetUtilPadding().Offset()); - } else { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), - pattern->GetUtilPadding().Offset().GetY() + pattern->GetBorderTop())); - } - textRect_.SetOffset(pattern->GetTextRect().GetOffset()); - } - return; - } - content->SetOffset(OffsetF(pattern->GetPaddingLeft(), contentOffset.GetY())); - // if handler is moving, no need to adjust text rect in pattern - auto isUsingMouse = pattern->GetMouseStatus() == MouseStatus::MOVE || - pattern->GetMouseStatus() == MouseStatus::RELEASED || pattern->GetIsMousePressed(); - auto needForceCheck = - ((pattern->GetCaretUpdateType() == CaretUpdateType::INPUT || - pattern->GetCaretUpdateType() == CaretUpdateType::DEL || pattern->GetTextRectWillChange()) && - (paragraphWidth_ <= contentSize.Width())) || - pattern->GetCaretUpdateType() == CaretUpdateType::ICON_PRESSED || - pattern->GetCaretUpdateType() == CaretUpdateType::VISIBLE_PASSWORD_ICON || - layoutProperty->GetTextAlignChangedValue(false); - auto needToKeepTextRect = isUsingMouse || !needForceCheck; - if (needToKeepTextRect) { - textRect_.SetOffset(pattern->GetTextRect().GetOffset()); - } - auto paintProperty = pattern->GetPaintProperty(); - CHECK_NULL_VOID(paintProperty); - if (!pattern->IsTextArea() && !needToKeepTextRect) { - auto textOffset = Alignment::GetAlignPosition(contentSize, textRect_.GetSize(), Alignment::CENTER_LEFT); - // adjust text rect to the basic padding - auto textRectOffsetX = pattern->GetPaddingLeft() + pattern->GetBorderLeft(); - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { - textRectOffsetX = pattern->GetPaddingLeft(); - } - auto isEmptyTextEditValue = pattern->GetTextEditingValue().text.empty(); - auto isInlineStyle = pattern->IsNormalInlineState(); - if (!isEmptyTextEditValue && !isInlineStyle) { - switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { - case TextAlign::START: - break; - case TextAlign::CENTER: - textRectOffsetX += (contentSize.Width() - textRect_.Width()) * 0.5f; - break; - case TextAlign::END: - textRectOffsetX += contentSize.Width() - textRect_.Width(); - break; - default: - break; - } - } - textRect_.SetOffset(OffsetF(textRectOffsetX, textOffset.GetY())); + auto contentWidth = idealSize.Width() - imageWidth; + if (autoWidth_) { + contentWidth = std::min(contentWidth, paragraph_->GetLongestLine()); } + return SizeF(contentWidth, std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); +} - // update image rect. - if (!imageRect_.IsEmpty()) { - auto imageOffset = Alignment::GetAlignPosition(size, imageRect_.GetSize(), Alignment::CENTER_RIGHT); - imageOffset.AddX(-pattern->GetIconRightOffset()); - imageRect_.SetOffset(imageOffset); - } +SizeF TextFieldLayoutAlgorithm::TextAreaMeasureContent(const SizeF& idealSize) +{ + paragraph_->Layout(idealSize.Width()); + textRect_.SetSize(SizeF(idealSize.Width(), paragraph_->GetHeight())); + return SizeF(idealSize.Width(), std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); +} - UpdateUnitLayout(layoutWrapper); +SizeF TextFieldLayoutAlgorithm::TextInputMeasureConetnt(const SizeF& idealSize, float imageWidth) +{ + paragraph_->Layout(std::numeric_limits::infinity()); + paragraph_->Layout(std::ceil(paragraph_->GetLongestLine())); + textRect_.SetSize(SizeF(static_cast(paragraph_->GetLongestLine()), paragraph_->GetHeight())); + auto contentWidth = idealSize.Width() - imageWidth; + if (autoWidth_) { + contentWidth = std::min(contentWidth, paragraph_->GetLongestLine()); + } + return SizeF(contentWidth, std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); +} + +void TextFieldLayoutAlgorithm::ErrorTextMeasureContent(const std::string& content, const RefPtr& theme) +{ + // errorParagraph Layout. + CreateErrorParagraph(content, theme); + if (errorParagraph_) { + errorParagraph_->Layout(std::numeric_limits::infinity()); + } } void TextFieldLayoutAlgorithm::UpdateTextStyle(const RefPtr& frameNode, @@ -634,217 +302,85 @@ void TextFieldLayoutAlgorithm::FontRegisterCallback( } } +ParagraphStyle TextFieldLayoutAlgorithm::GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const +{ + return { .direction = GetTextDirection(content), + .maxLines = textStyle.GetMaxLines(), + .fontLocale = Localization::GetInstance()->GetFontLocale(), + .wordBreak = textStyle.GetWordBreak(), + .textOverflow = textStyle.GetTextOverflow(), + .fontSize = textStyle.GetFontSize().ConvertToPx() }; +} + void TextFieldLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, std::string content, bool needObscureText, int32_t nakedCharPosition, bool disableTextAlign) { - RSParagraphStyle paraStyle; -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.textDirection_ = ToRSTextDirection(GetTextDirection(content)); -#else - paraStyle.textDirection = ToRSTextDirection(GetTextDirection(content)); -#endif + auto paraStyle = GetParagraphStyle(textStyle, content); if (!disableTextAlign) { -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.textAlign_ = ToRSTextAlign(textStyle.GetTextAlign()); -#else - paraStyle.textAlign = ToRSTextAlign(textStyle.GetTextAlign()); -#endif - } -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.maxLines_ = textStyle.GetMaxLines(); - paraStyle.locale_ = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType_ = ToRSWordBreakType(textStyle.GetWordBreak()); - paraStyle.fontSize_ = textStyle.GetFontSize().ConvertToPx(); - auto fontFamilies = textStyle.GetFontFamilies(); - if (!fontFamilies.empty()) { - paraStyle.fontFamily_ = fontFamilies.at(0); - } -#else - paraStyle.maxLines = textStyle.GetMaxLines(); - paraStyle.locale = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType = ToRSWordBreakType(textStyle.GetWordBreak()); - paraStyle.fontSize = textStyle.GetFontSize().ConvertToPx(); - auto fontFamilies = textStyle.GetFontFamilies(); - if (!fontFamilies.empty()) { - paraStyle.fontFamily = fontFamilies.at(0); + paraStyle.align = textStyle.GetTextAlign(); } -#endif - if (textStyle.GetTextOverflow() == TextOverflow::ELLIPSIS) { -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.ellipsis_ = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS); -#else - paraStyle.ellipsis = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS); -#endif - } -#ifndef USE_GRAPHIC_TEXT_GINE - auto builder = RSParagraphBuilder::CreateRosenBuilder(paraStyle, RSFontCollection::GetInstance(false)); -#else - auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create()); -#endif - builder->PushStyle(ToRSTextStyle(PipelineContext::GetCurrentContext(), textStyle)); + paragraph_ = Paragraph::Create(paraStyle, FontCollection::Current()); + CHECK_NULL_VOID(paragraph_); + paragraph_->PushStyle(textStyle); StringUtils::TransformStrCase(content, static_cast(textStyle.GetTextCase())); -#ifndef USE_GRAPHIC_TEXT_GINE - auto displayText = TextFieldPattern::CreateDisplayText(content, nakedCharPosition, needObscureText); - builder->AddText(displayText); -#else auto displayText = TextFieldPattern::CreateDisplayText(content, nakedCharPosition, needObscureText); - builder->AppendText(displayText); -#endif - -#ifndef USE_GRAPHIC_TEXT_GINE - builder->Pop(); - auto paragraph = builder->Build(); -#else - builder->PopStyle(); - auto paragraph = builder->CreateTypography(); -#endif - paragraph_.reset(paragraph.release()); + paragraph_->AddText(displayText); + paragraph_->Build(); } -void TextFieldLayoutAlgorithm::CreateParagraph(const std::vector& textStyles, - const std::vector& contents, const std::string& content, bool needObscureText, bool disableTextAlign) +void TextFieldLayoutAlgorithm::CreateParagraph(const TextStyle& textStyle, const std::vector& contents, + const std::string& content, bool needObscureText, bool disableTextAlign) { - auto textStyle = textStyles.begin(); - RSParagraphStyle paraStyle; -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.textDirection_ = ToRSTextDirection(GetTextDirection(content)); -#else - paraStyle.textDirection = ToRSTextDirection(GetTextDirection(content)); -#endif + TextStyle dragTextStyle = textStyle; + Color color = textStyle.GetTextColor().ChangeAlpha(DRAGGED_TEXT_OPACITY); + dragTextStyle.SetTextColor(color); + std::vector textStyles { textStyle, dragTextStyle, textStyle }; + + auto style = textStyles.begin(); + ParagraphStyle paraStyle { .direction = GetTextDirection(content), + .maxLines = style->GetMaxLines(), + .fontLocale = Localization::GetInstance()->GetFontLocale(), + .wordBreak = style->GetWordBreak(), + .textOverflow = style->GetTextOverflow(), + .fontSize = style->GetFontSize().ConvertToPx() }; if (!disableTextAlign) { -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.textAlign_ = ToRSTextAlign(textStyle->GetTextAlign()); -#else - paraStyle.textAlign = ToRSTextAlign(textStyle->GetTextAlign()); -#endif + paraStyle.align = style->GetTextAlign(); } -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.maxLines_ = textStyle->GetMaxLines(); - paraStyle.locale_ = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType_ = ToRSWordBreakType(textStyle->GetWordBreak()); - paraStyle.fontSize_ = textStyle->GetFontSize().ConvertToPx(); - auto fontFamilies = textStyle->GetFontFamilies(); - if (!fontFamilies.empty()) { - paraStyle.fontFamily_ = fontFamilies.at(0); - } -#else - paraStyle.maxLines = textStyle->GetMaxLines(); - paraStyle.locale = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType = ToRSWordBreakType(textStyle->GetWordBreak()); - paraStyle.fontSize = textStyle->GetFontSize().ConvertToPx(); - paraStyle.fontFamily = textStyle->GetFontFamilies().at(0); -#endif - if (textStyle->GetTextOverflow() == TextOverflow::ELLIPSIS) { -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.ellipsis_ = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS); -#else - paraStyle.ellipsis = StringUtils::Str8ToStr16(StringUtils::ELLIPSIS); -#endif - } -#ifndef USE_GRAPHIC_TEXT_GINE - auto builder = RSParagraphBuilder::CreateRosenBuilder(paraStyle, RSFontCollection::GetInstance(false)); -#else - auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create()); -#endif + paragraph_ = Paragraph::Create(paraStyle, FontCollection::Current()); + CHECK_NULL_VOID(paragraph_); for (size_t i = 0; i < contents.size(); i++) { std::string splitStr = contents[i]; if (splitStr.empty()) { continue; } auto& style = textStyles[i]; - builder->PushStyle(ToRSTextStyle(PipelineContext::GetCurrentContext(), style)); + paragraph_->PushStyle(style); StringUtils::TransformStrCase(splitStr, static_cast(style.GetTextCase())); if (needObscureText) { -#ifndef USE_GRAPHIC_TEXT_GINE - builder->AddText( - TextFieldPattern::CreateObscuredText(static_cast(StringUtils::ToWstring(splitStr).length()))); -#else - builder->AppendText( + paragraph_->AddText( TextFieldPattern::CreateObscuredText(static_cast(StringUtils::ToWstring(splitStr).length()))); -#endif } else { -#ifndef USE_GRAPHIC_TEXT_GINE - builder->AddText(StringUtils::Str8ToStr16(splitStr)); -#else - builder->AppendText(StringUtils::Str8ToStr16(splitStr)); -#endif + paragraph_->AddText(StringUtils::Str8ToStr16(splitStr)); } + paragraph_->PopStyle(); } -#ifndef USE_GRAPHIC_TEXT_GINE - builder->Pop(); - - auto paragraph = builder->Build(); -#else - builder->PopStyle(); - auto paragraph = builder->CreateTypography(); -#endif - paragraph_.reset(paragraph.release()); -} - -void TextFieldLayoutAlgorithm::CreateCounterParagraph( - int32_t textLength, int32_t maxLength, const RefPtr& theme) -{ - CHECK_NULL_VOID(theme); - TextStyle countTextStyle = (textLength != maxLength) ? theme->GetCountTextStyle() : theme->GetOverCountTextStyle(); - std::string counterText = std::to_string(textLength) + "/" + std::to_string(maxLength); - RSParagraphStyle paraStyle; -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.fontSize_ = countTextStyle.GetFontSize().ConvertToPx(); - paraStyle.textAlign_ = ToRSTextAlign(TextAlign::END); - paraStyle.maxLines_ = COUNTER_TEXT_MAXLINE; - auto builder = RSParagraphBuilder::CreateRosenBuilder(paraStyle, RSFontCollection::GetInstance(false)); -#else - paraStyle.fontSize = countTextStyle.GetFontSize().ConvertToPx(); - paraStyle.textAlign = ToRSTextAlign(TextAlign::END); - paraStyle.maxLines = COUNTER_TEXT_MAXLINE; - auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create()); -#endif - builder->PushStyle(ToRSTextStyle(PipelineContext::GetCurrentContext(), countTextStyle)); - StringUtils::TransformStrCase(counterText, static_cast(countTextStyle.GetTextCase())); -#ifndef USE_GRAPHIC_TEXT_GINE - builder->AddText(StringUtils::Str8ToStr16(counterText)); - builder->Pop(); -#else - builder->AppendText(StringUtils::Str8ToStr16(counterText)); - builder->PopStyle(); -#endif - -#ifndef USE_GRAPHIC_TEXT_GINE - auto paragraph = builder->Build(); -#else - auto paragraph = builder->CreateTypography(); -#endif - counterParagraph_.reset(paragraph.release()); + paragraph_->Build(); } void TextFieldLayoutAlgorithm::CreateErrorParagraph(const std::string& content, const RefPtr& theme) { CHECK_NULL_VOID(theme); TextStyle errorTextStyle = theme->GetErrorTextStyle(); - std::string counterText = content; - RSParagraphStyle paraStyle; -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.fontSize_ = errorTextStyle.GetFontSize().ConvertToPx(); - paraStyle.textAlign_ = ToRSTextAlign(TextAlign::START); - auto builder = RSParagraphBuilder::CreateRosenBuilder(paraStyle, RSFontCollection::GetInstance(false)); -#else - paraStyle.fontSize = errorTextStyle.GetFontSize().ConvertToPx(); - paraStyle.textAlign = ToRSTextAlign(TextAlign::START); - auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create()); -#endif - builder->PushStyle(ToRSTextStyle(PipelineContext::GetCurrentContext(), errorTextStyle)); - StringUtils::TransformStrCase(counterText, static_cast(errorTextStyle.GetTextCase())); -#ifndef USE_GRAPHIC_TEXT_GINE - builder->AddText(StringUtils::Str8ToStr16(counterText)); - builder->Pop(); - - auto paragraph = builder->Build(); -#else - builder->AppendText(StringUtils::Str8ToStr16(counterText)); - builder->PopStyle(); - auto paragraph = builder->CreateTypography(); -#endif - errorParagraph_.reset(paragraph.release()); + std::string errorText = content; + ParagraphStyle paraStyle { .align = TextAlign::START, + .fontLocale = Localization::GetInstance()->GetFontLocale(), + .fontSize = errorTextStyle.GetFontSize().ConvertToPx() }; + errorParagraph_ = Paragraph::Create(paraStyle, FontCollection::Current()); + CHECK_NULL_VOID(errorParagraph_); + errorParagraph_->PushStyle(errorTextStyle); + StringUtils::TransformStrCase(errorText, static_cast(errorTextStyle.GetTextCase())); + errorParagraph_->AddText(StringUtils::Str8ToStr16(errorText)); + errorParagraph_->Build(); } TextDirection TextFieldLayoutAlgorithm::GetTextDirection(const std::string& content) @@ -863,17 +399,12 @@ TextDirection TextFieldLayoutAlgorithm::GetTextDirection(const std::string& cont return textDirection; } -const std::shared_ptr& TextFieldLayoutAlgorithm::GetParagraph() +const RefPtr& TextFieldLayoutAlgorithm::GetParagraph() const { return paragraph_; } -const std::shared_ptr& TextFieldLayoutAlgorithm::GetCounterParagraph() const -{ - return counterParagraph_; -} - -const std::shared_ptr& TextFieldLayoutAlgorithm::GetErrorParagraph() const +const RefPtr& TextFieldLayoutAlgorithm::GetErrorParagraph() const { return errorParagraph_; } @@ -928,7 +459,6 @@ void TextFieldLayoutAlgorithm::UpdateUnitLayout(LayoutWrapper* layoutWrapper) layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::UNSPECIFIED) { auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); CHECK_NULL_VOID(childWrapper); - auto textLayoutProperty = DynamicCast(childWrapper->GetLayoutProperty()); auto textGeometryNode = childWrapper->GetGeometryNode(); CHECK_NULL_VOID(textGeometryNode); auto childFrameSize = textGeometryNode->GetFrameSize(); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h index 6685b376159..ca1c26c284f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h @@ -20,13 +20,10 @@ #include #include "base/geometry/ng/offset_t.h" -#include "base/geometry/rect.h" #include "base/memory/referenced.h" #include "core/components/text_field/textfield_theme.h" #include "core/components_ng/layout/layout_wrapper.h" -#include "core/components_ng/pattern/text/text_styles.h" #include "core/components_ng/pattern/text_field/text_field_layout_property.h" -#include "core/components_ng/render/drawing.h" namespace OHOS::Ace::NG { @@ -41,46 +38,18 @@ public: void OnReset() override { - paragraph_.reset(); + paragraph_->Reset(); } - void Measure(LayoutWrapper* layoutWrapper) override; + const RefPtr& GetParagraph() const; - std::optional MeasureContent( - const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) override; - - void Layout(LayoutWrapper* layoutWrapper) override; - - const std::shared_ptr& GetParagraph(); - - const std::shared_ptr& GetCounterParagraph() const; - const std::shared_ptr& GetErrorParagraph() const; + const RefPtr& GetErrorParagraph() const; const RectF& GetTextRect() const { return textRect_; } - const RectF& GetImageRect() const - { - return imageRect_; - } - - const RectF& GetFrameRect() const - { - return frameRect_; - } - - float GetCaretOffsetX() const - { - return caretOffsetX_; - } - - void SetCaretOffset(float offsetX) - { - caretOffsetX_ = offsetX; - } - const OffsetF& GetParentGlobalOffset() const { return parentGlobalOffset_; @@ -91,27 +60,21 @@ public: return unitWidth_; } - float GetParagraphWidth() const - { - return paragraphWidth_; - } - static TextDirection GetTextDirection(const std::string& content); static void UpdateTextStyle(const RefPtr& frameNode, const RefPtr& layoutProperty, const RefPtr& theme, TextStyle& textStyle, bool isDisabled); static void UpdatePlaceholderTextStyle(const RefPtr& frameNode, - const RefPtr& layoutProperty, const RefPtr& theme, + const RefPtr& layoutProperty, const RefPtr& theme, TextStyle& textStyle, bool isDisabled); -private: +protected: static void FontRegisterCallback(const RefPtr& frameNode, const std::vector& fontFamilies); void CreateParagraph(const TextStyle& textStyle, std::string content, bool needObscureText, - int32_t nakedCharPosition, bool disableTextAlign); - void CreateParagraph(const std::vector& textStyles, const std::vector& contents, - const std::string& content, bool needObscureText, bool disableTextAlign); - void CreateCounterParagraph(int32_t textLength, int32_t maxLength, const RefPtr& theme); + int32_t nakedCharPosition, bool disableTextAlign = false); + void CreateParagraph(const TextStyle& textStyle, const std::vector& contents, + const std::string& content, bool needObscureText, bool disableTextAlign = false); void CreateErrorParagraph(const std::string& content, const RefPtr& theme); bool CreateParagraphAndLayout( const TextStyle& textStyle, const std::string& content, const LayoutConstraintF& contentConstraint); @@ -123,20 +86,29 @@ private: float GetTextFieldDefaultHeight(); float GetTextFieldDefaultImageHeight(); + void ConstructTextStyles( + const RefPtr& frameNode, TextStyle& textStyle, std::string& textContent, bool& showPlaceHolder); + void ErrorTextMeasureContent(const std::string& content, const RefPtr& theme); + int32_t ConvertTouchOffsetToCaretPosition(const Offset& localOffset); void UpdateUnitLayout(LayoutWrapper* layoutWrapper); + ParagraphStyle GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const; + + SizeF CalculateConstraintSize(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); + std::optional InlineMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, const SizeF& idealSize); + SizeF PlaceHolderMeasureContent(const SizeF& idealSize, float imageWidth = 0.0f); + SizeF TextInputMeasureConetnt(const SizeF& idealSize, float imageWidth); + SizeF TextAreaMeasureContent(const SizeF& idealSize); - std::shared_ptr paragraph_; - std::shared_ptr counterParagraph_; - std::shared_ptr errorParagraph_; - RectF frameRect_; + RefPtr paragraph_; + RefPtr errorParagraph_; RectF textRect_; - RectF imageRect_; OffsetF parentGlobalOffset_; - float paragraphWidth_ = 0.0f; + float preferredHeight_ = 0.0f; - float caretOffsetX_ = 0.0f; float unitWidth_ = 0.0f; + bool autoWidth_ = false; ACE_DISALLOW_COPY_AND_MOVE(TextFieldLayoutAlgorithm); }; diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h index 8dec35c0eab..71f8949bc9d 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h @@ -86,13 +86,13 @@ public: ACE_DEFINE_PROPERTY_GROUP(FontStyle, FontStyle); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, FontSize, Dimension, PROPERTY_UPDATE_MEASURE); - ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, TextColor, Color, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, TextColor, Color, PROPERTY_UPDATE_MEASURE_SELF); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, ItalicFontStyle, Ace::FontStyle, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, FontWeight, FontWeight, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(FontStyle, FontFamily, std::vector, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_GROUP(TextLineStyle, TextLineStyle); - ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, TextAlign, TextAlign, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, TextAlign, TextAlign, PROPERTY_UPDATE_MEASURE_SELF); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, MaxLength, uint32_t, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, MaxLines, uint32_t, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, std::string, PROPERTY_UPDATE_MEASURE); @@ -101,7 +101,7 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM( PlaceholderFontStyle, FontSize, PlaceholderFontSize, Dimension, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM( - PlaceholderFontStyle, TextColor, PlaceholderTextColor, Color, PROPERTY_UPDATE_MEASURE); + PlaceholderFontStyle, TextColor, PlaceholderTextColor, Color, PROPERTY_UPDATE_MEASURE_SELF); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM( PlaceholderFontStyle, ItalicFontStyle, PlaceholderItalicFontStyle, Ace::FontStyle, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM( @@ -138,7 +138,7 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PreferredTextLineHeightNeedToUpdate, bool, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PreferredPlaceholderLineHeightNeedToUpdate, bool, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(LastValue, std::string, PROPERTY_UPDATE_MEASURE); - ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(NeedFireOnChange, bool, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(NeedFireOnChange, bool, PROPERTY_UPDATE_NORMAL); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShowPasswordSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(HidePasswordSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_MEASURE); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp index b798345a269..08f04aa57eb 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp @@ -21,11 +21,13 @@ #include "base/memory/referenced.h" #include "base/utils/utils.h" #include "core/common/ime/text_edit_controller.h" +#include "core/common/ime/text_input_type.h" #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/pattern/text_field/text_field_event_hub.h" #include "core/components_ng/pattern/text_field/text_field_layout_property.h" #include "core/components_ng/pattern/text_field/text_field_paint_property.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" +#include "core/components_ng/pattern/text_field/text_input_response_area.h" #include "core/components_v2/inspector/inspector_constants.h" namespace OHOS::Ace::NG { @@ -40,12 +42,12 @@ void TextFieldModelNG::CreateNode( auto textFieldLayoutProperty = frameNode->GetLayoutProperty(); CHECK_NULL_VOID(textFieldLayoutProperty); auto pattern = frameNode->GetPattern(); - auto textEditingValue = pattern->GetTextEditingValue(); + auto textValue = pattern->GetTextValue(); if (SystemProperties::GetDebugEnabled()) { LOGI("TextFieldModelNG::GetOrCreateNode with text %{public}s, current text %{public}s", - value.value_or("NA").c_str(), textEditingValue.text.c_str()); + value.value_or("NA").c_str(), textValue.c_str()); } - if (value.has_value() && value.value() != textEditingValue.text) { + if (value.has_value() && value.value() != textValue) { pattern->InitEditingValueText(value.value()); } textFieldLayoutProperty->UpdatePlaceholder(placeholder.value_or("")); @@ -152,14 +154,6 @@ void TextFieldModelNG::RequestKeyboardOnFocus(bool needToRequest) pattern->SetNeedToRequestKeyboardOnFocus(needToRequest); } -void TextFieldModelNG::SetTextRectWillChange() -{ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - CHECK_NULL_VOID(frameNode); - auto pattern = frameNode->GetPattern(); - pattern->SetTextRectWillChange(); -} - void TextFieldModelNG::SetType(TextInputType value) { auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); @@ -168,8 +162,20 @@ void TextFieldModelNG::SetType(TextInputType value) if (layoutProperty->HasTextInputType() && layoutProperty->GetTextInputTypeValue() != value) { layoutProperty->UpdateTypeChanged(true); } - SetTextRectWillChange(); ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, TextInputType, value); + auto textFieldPattern = frameNode->GetPattern(); + CHECK_NULL_VOID(textFieldPattern); + auto responseArea = textFieldPattern->GetResponseArea(); + auto passwordResponseArea = AceType::DynamicCast(responseArea); + if (value == TextInputType::VISIBLE_PASSWORD) { + CHECK_NULL_VOID(!passwordResponseArea); + auto responseArea = AceType::MakeRefPtr(); + responseArea->SetObscured(textFieldPattern->GetTextObscured()); + textFieldPattern->SetResponseArea(responseArea); + } else { + CHECK_NULL_VOID(passwordResponseArea); + textFieldPattern->SetResponseArea(nullptr); + } } void TextFieldModelNG::SetPlaceholderColor(const Color& value) @@ -219,10 +225,9 @@ void TextFieldModelNG::SetCaretPosition(const int32_t& value) CHECK_NULL_VOID(frameNode); auto layoutProperty = frameNode->GetLayoutProperty(); auto pattern = frameNode->GetPattern(); - auto caretPosition = layoutProperty->GetPlaceholderValue() == "" ? value : 0; + auto caretPosition = layoutProperty->GetPlaceholderValue().empty() ? value : 0; ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, CaretPosition, caretPosition); pattern->SetCaretPosition(caretPosition); - pattern->UpdateCaretPositionByTextEdit(); } void TextFieldModelNG::SetSelectedBackgroundColor(const Color& value) @@ -258,7 +263,6 @@ void TextFieldModelNG::SetMaxLines(uint32_t value) } void TextFieldModelNG::SetFontSize(const Dimension& value) { - SetTextRectWillChange(); ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, FontSize, value); ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, PreferredTextLineHeightNeedToUpdate, true); } @@ -306,9 +310,6 @@ void TextFieldModelNG::SetShowPasswordIcon(bool value) CHECK_NULL_VOID(layoutProperty); auto pattern = frameNode->GetPattern(); CHECK_NULL_VOID(pattern); - if (layoutProperty->GetShowPasswordIcon().has_value() && layoutProperty->GetShowPasswordIconValue() != value) { - pattern->ShowPasswordIconChange(); - } ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, ShowPasswordIcon, value); } @@ -403,21 +404,13 @@ void TextFieldModelNG::SetPasswordIcon(const PasswordIcon& passwordIcon) CHECK_NULL_VOID(frameNode); auto pattern = frameNode->GetPattern(); CHECK_NULL_VOID(pattern); - if (passwordIcon.showResult == "") { - pattern->SetShowUserDefinedIcon(false); - } else { + if (passwordIcon.showResult != "") { ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, ShowPasswordSourceInfo, ImageSourceInfo(passwordIcon.showResult, passwordIcon.showBundleName, passwordIcon.showModuleName)); - pattern->SetShowUserDefinedIcon(true); - pattern->SetShowUserDefinedIconSrc(passwordIcon.showResult); } - if (passwordIcon.hideResult == "") { - pattern->SetHideUserDefinedIcon(false); - } else { + if (passwordIcon.hideResult != "") { ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, HidePasswordSourceInfo, ImageSourceInfo(passwordIcon.hideResult, passwordIcon.hideBundleName, passwordIcon.hideModuleName)); - pattern->SetHideUserDefinedIcon(true); - pattern->SetHideUserDefinedIconSrc(passwordIcon.hideResult); } } @@ -434,7 +427,15 @@ void TextFieldModelNG::SetShowUnit(std::function&& unitFunction) unitNode = NG::ViewStackProcessor::GetInstance()->Finish(); } if (unitNode) { - pattern->SetUnitNode(unitNode); + auto responseArea = pattern->GetResponseArea(); + auto unitResponseArea = AceType::DynamicCast(responseArea); + if (unitResponseArea) { + unitResponseArea->SetUnitNode(unitNode); + } else { + unitResponseArea = AceType::MakeRefPtr(unitNode); + pattern->SetResponseArea(unitResponseArea); + } + frameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } } @@ -447,6 +448,16 @@ void TextFieldModelNG::SetShowError(const std::string& errorText, bool visible) void TextFieldModelNG::SetShowCounter(bool value) { ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, ShowCounter, value); + + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + if(value) { + pattern->AddCounterNode(); + } else { + pattern->ClearCounterNode(); + } } void TextFieldModelNG::SetBarState(OHOS::Ace::DisplayMode value) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp index 99f39a716f3..336175c5575 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp @@ -38,10 +38,11 @@ TextFieldOverlayModifier::TextFieldOverlayModifier( cursorOffset_ = AceType::MakeRefPtr(textFieldPattern->GetCaretOffset()); frameSize_ = AceType::MakeRefPtr(SizeF()); currentOffset_ = AceType::MakeRefPtr(0.0f); - flag_ = AceType::MakeRefPtr(0); underlineWidth_ = AceType::MakeRefPtr(0.0f); underlineColor_ = AceType::MakeRefPtr(Color()); - showCounter_ = AceType::MakeRefPtr(false); + changeSelectedRects_ = AceType::MakeRefPtr(false); + firstHandleOffset_ = AceType::MakeRefPtr(OffsetF()); + secondHandleOffset_ = AceType::MakeRefPtr(OffsetF()); AttachProperty(cursorColor_); AttachProperty(cursorWidth_); @@ -52,10 +53,21 @@ TextFieldOverlayModifier::TextFieldOverlayModifier( AttachProperty(cursorOffset_); AttachProperty(frameSize_); AttachProperty(currentOffset_); - AttachProperty(flag_); AttachProperty(underlineWidth_); AttachProperty(underlineColor_); - AttachProperty(showCounter_); + AttachProperty(changeSelectedRects_); + AttachProperty(firstHandleOffset_); + AttachProperty(secondHandleOffset_); +} + +void TextFieldOverlayModifier::SetFirstHandleOffset(const OffsetF& offset) +{ + firstHandleOffset_->Set(offset); +} + +void TextFieldOverlayModifier::SetSecondHandleOffset(const OffsetF& offset) +{ + secondHandleOffset_->Set(offset); } void TextFieldOverlayModifier::onDraw(DrawingContext& context) @@ -76,13 +88,15 @@ void TextFieldOverlayModifier::PaintUnderline(RSCanvas& canvas) const if (!(layoutProperty->GetShowUnderlineValue(false) && textFieldPattern->IsUnspecifiedOrTextType())) { return; } - auto textRect = textFieldPattern->GetContentRect(); + auto contentRect = textFieldPattern->GetContentRect(); auto textFrameRect = textFieldPattern->GetFrameRect(); + auto responseArea = textFieldPattern->GetResponseArea(); + auto responseAreaWidth = responseArea ? responseArea->GetAreaRect().Width() : 0.0f; Point leftPoint, rightPoint; - leftPoint.SetX(textRect.Left()); - leftPoint.SetY(textFrameRect.Bottom() - textFrameRect.Top()); - rightPoint.SetX(textRect.Right()); - rightPoint.SetY(textFrameRect.Bottom() - textFrameRect.Top()); + leftPoint.SetX(contentRect.Left()); + leftPoint.SetY(textFrameRect.Height()); + rightPoint.SetX(contentRect.Right() + responseAreaWidth); + rightPoint.SetY(textFrameRect.Height()); RSPen pen; pen.SetColor(ToRSColor(underlineColor_->Get())); pen.SetWidth(underlineWidth_->Get()); @@ -99,9 +113,6 @@ void TextFieldOverlayModifier::PaintSelection(DrawingContext& context) const canvas.Save(); auto textFieldPattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(textFieldPattern); - if (!textFieldPattern->IsSelected()) { - return; - } auto pipelineContext = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipelineContext); auto themeManager = pipelineContext->GetThemeManager(); @@ -111,23 +122,16 @@ void TextFieldOverlayModifier::PaintSelection(DrawingContext& context) const brush.SetAntiAlias(true); brush.SetColor(ToRSColor(selectedColor_->Get())); canvas.AttachBrush(brush); - auto contentOffset = textFieldPattern->GetContentRect().GetOffset(); - auto paintOffset = contentOffset - OffsetF(0.0f, textFieldPattern->GetBaseLineOffset()); + auto paintOffset = textFieldPattern->GetContentRect().GetOffset(); auto textBoxes = textFieldPattern->GetTextBoxes(); auto textRect = textFieldPattern->GetTextRect(); bool isTextArea = textFieldPattern->IsTextArea(); float clipRectHeight = 0.0f; - if (showCounter_->Get() && textFieldPattern->GetCounterParagraph() && - !textFieldPattern->GetIsCounterIdealHeight()) { - clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height() - textFieldPattern->GetCountHeight(); - } else { - clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height(); - } + clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height(); RSRect clipInnerRect; if (inputStyle_ == InputStyle::DEFAULT || isTextArea) { - clipInnerRect = RSRect( - paintOffset.GetX(), paintOffset.GetY(), paintOffset.GetX() + contentSize_->Get().Width() + - textFieldPattern->GetInlinePadding(), clipRectHeight); + clipInnerRect = RSRect(paintOffset.GetX(), paintOffset.GetY(), + paintOffset.GetX() + contentSize_->Get().Width() + textFieldPattern->GetInlinePadding(), clipRectHeight); canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT); } else { clipInnerRect = RSRect(paintOffset.GetX(), 0.0f, paintOffset.GetX() + contentSize_->Get().Width(), @@ -136,25 +140,14 @@ void TextFieldOverlayModifier::PaintSelection(DrawingContext& context) const } // for default style, selection height is equal to the content height for (const auto& textBox : textBoxes) { -#ifndef USE_GRAPHIC_TEXT_GINE - canvas.DrawRect(RSRect(textBox.rect_.GetLeft() + (isTextArea ? contentOffset.GetX() : textRect.GetX()), - inputStyle_ == InputStyle::DEFAULT || isTextArea - ? (textBox.rect_.GetTop() + (isTextArea ? textRect.GetY() : contentOffset.GetY())) - : 0.0f, - textBox.rect_.GetRight() + (isTextArea ? contentOffset.GetX() : textRect.GetX()), + canvas.DrawRect(RSRect(textBox.Left() + (isTextArea ? contentOffset_->Get().GetX() : textRect.GetX()), inputStyle_ == InputStyle::DEFAULT || isTextArea - ? (textBox.rect_.GetBottom() + (isTextArea ? textRect.GetY() : contentOffset.GetY())) - : textFieldPattern->GetFrameRect().Height())); -#else - canvas.DrawRect(RSRect(textBox.rect.GetLeft() + (isTextArea ? contentOffset.GetX() : textRect.GetX()), - inputStyle_ == InputStyle::DEFAULT || isTextArea - ? (textBox.rect.GetTop() + (isTextArea ? textRect.GetY() : contentOffset.GetY())) + ? (textBox.Top() + (isTextArea ? textRect.GetY() : contentOffset_->Get().GetY())) : 0.0f, - textBox.rect.GetRight() + (isTextArea ? contentOffset.GetX() : textRect.GetX()), + textBox.Right() + (isTextArea ? contentOffset_->Get().GetX() : textRect.GetX()), inputStyle_ == InputStyle::DEFAULT || isTextArea - ? (textBox.rect.GetBottom() + (isTextArea ? textRect.GetY() : contentOffset.GetY())) + ? (textBox.Bottom() + (isTextArea ? textRect.GetY() : contentOffset_->Get().GetY())) : textFieldPattern->GetFrameRect().Height())); -#endif } canvas.Restore(); } @@ -172,24 +165,19 @@ void TextFieldOverlayModifier::PaintCursor(DrawingContext& context) const brush.SetAntiAlias(true); brush.SetColor(ToRSColor(cursorColor_->Get())); canvas.AttachBrush(brush); - auto paintOffset = contentOffset_->Get() - OffsetF(0.0f, textFieldPattern->GetBaseLineOffset()); + auto paintOffset = contentOffset_->Get(); float clipRectHeight = 0.0f; - if (showCounter_->Get() && textFieldPattern->GetCounterParagraph() && - !textFieldPattern->GetIsCounterIdealHeight()) { - clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height() - textFieldPattern->GetCountHeight(); - } else { - clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height(); - } + clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height(); RSRect clipInnerRect(paintOffset.GetX(), paintOffset.GetY(), // add extra clip space for cases such as auto width - paintOffset.GetX() + contentSize_->Get().Width() + cursorWidth_->Get() * 2.0f - - textFieldPattern->GetUnitWidth(), clipRectHeight); + paintOffset.GetX() + contentSize_->Get().Width() + cursorWidth_->Get() * 2.0f, + clipRectHeight); auto layoutProperty = textFieldPattern->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); canvas.ClipRect(clipInnerRect, RSClipOp::INTERSECT); auto caretRect = textFieldPattern->GetCaretRect(); - canvas.DrawRect(RSRect(cursorOffset_->Get().GetX(), caretRect.GetY(), - cursorOffset_->Get().GetX() + static_cast(cursorWidth_->Get()), caretRect.GetY() + caretRect.Height())); + canvas.DrawRect(RSRect(caretRect.GetX(), caretRect.GetY(), + caretRect.GetX() + static_cast(cursorWidth_->Get()), caretRect.GetY() + caretRect.Height())); canvas.DetachBrush(); canvas.Restore(); } @@ -260,11 +248,6 @@ void TextFieldOverlayModifier::SetCurrentOffset(float value) currentOffset_->Set(value); } -void TextFieldOverlayModifier::SetRedrawFlag(int32_t value) -{ - flag_->Set(value); -} - void TextFieldOverlayModifier::SetUnderlineWidth(float value) { underlineWidth_->Set(value); @@ -275,13 +258,15 @@ void TextFieldOverlayModifier::SetUnderlineColor(const Color& value) underlineColor_->Set(value); } -void TextFieldOverlayModifier::SetShowCounter(bool value) +void TextFieldOverlayModifier::SetScrollBar(const RefPtr& scrollBar) { - showCounter_->Set(value); + scrollBar_ = scrollBar; } -void TextFieldOverlayModifier::SetScrollBar(const RefPtr& scrollBar) +void TextFieldOverlayModifier::SetChangeSelectedRects(bool value) { - scrollBar_ = scrollBar; + if (value) { + changeSelectedRects_->Set(!changeSelectedRects_->Get()); + } } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h index c7c0a8f4e24..76ddc28b3ca 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h @@ -16,6 +16,7 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_OVERLAY_MODIFIER_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_OVERLAY_MODIFIER_H +#include #include "base/memory/ace_type.h" #include "core/components/common/properties/color.h" #include "core/components_ng/base/modifier.h" @@ -51,9 +52,11 @@ public: void PaintUnderline(RSCanvas& canvas) const; void SetUnderlineColor(const Color& value); void SetUnderlineWidth(float underlineWidth); - void SetShowCounter(bool value); void SetRedrawFlag(int32_t value); void SetScrollBar(const RefPtr& scrollBar); + void SetChangeSelectedRects(bool value); + void SetFirstHandleOffset(const OffsetF& offset); + void SetSecondHandleOffset(const OffsetF& offset); private: void PaintSelection(DrawingContext& context) const; @@ -71,13 +74,14 @@ private: RefPtr cursorVisible_; RefPtr contentSize_; RefPtr contentOffset_; + RefPtr firstHandleOffset_; + RefPtr secondHandleOffset_; RefPtr currentOffset_; - RefPtr flag_; RefPtr underlineWidth_; RefPtr underlineColor_; InputStyle inputStyle_ = InputStyle::DEFAULT; RefPtr frameSize_; - RefPtr showCounter_; + RefPtr changeSelectedRects_; ACE_DISALLOW_COPY_AND_MOVE(TextFieldOverlayModifier); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp index 7b4e64bcf48..471dbe4977b 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp @@ -29,6 +29,7 @@ #include "core/components_ng/pattern/pattern.h" #include "core/components_ng/pattern/search/search_event_hub.h" #include "core/components_ng/pattern/search/search_pattern.h" +#include "core/components_ng/pattern/search/search_text_field.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" #include "core/components_ng/property/measure_utils.h" #include "core/components_ng/render/canvas_image.h" @@ -67,13 +68,13 @@ void TextFieldPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper) auto textFieldLayoutProperty = textFieldPattern->GetLayoutProperty(); CHECK_NULL_VOID(textFieldLayoutProperty); - auto textEditingValue = textFieldPattern->GetTextEditingValue(); + auto textValue = textFieldPattern->GetTextValue(); auto isPasswordType = textFieldLayoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD; auto showPlaceHolder = textFieldLayoutProperty->GetValueValue("").empty(); auto needObscureText = isPasswordType && textFieldPattern->GetTextObscured() && !showPlaceHolder; - auto text = TextFieldPattern::CreateDisplayText( - textEditingValue.text, textFieldPattern->GetNakedCharPosition(), needObscureText); + auto text = + TextFieldPattern::CreateDisplayText(textValue, textFieldPattern->GetNakedCharPosition(), needObscureText); auto displayText = StringUtils::Str16ToStr8(text); textFieldContentModifier_->SetTextValue(displayText); textFieldContentModifier_->SetPlaceholderValue(textFieldPattern->GetPlaceHolder()); @@ -86,13 +87,12 @@ void TextFieldPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper) if (textFieldContentModifier_->GetTextRectX() != currentTextRectOffsetX || (textFieldPattern->IsTextArea() ? textFieldContentModifier_->GetTextRectY() : textFieldContentModifier_->GetContentOffsetY()) != currentTextRectOffsetY) { - // If the parent node is a Search, the Search callback is executed. - if (textFieldPattern->IsSearchParentNode()) { + auto searchField = DynamicCast(textFieldPattern); + if (searchField) { auto parentFrameNode = AceType::DynamicCast(frameNode->GetParent()); auto searchPattern = parentFrameNode->GetPattern(); CHECK_NULL_VOID(searchPattern); auto textFieldOffset = searchPattern->GetTextFieldOffset(); - auto eventHub = parentFrameNode->GetEventHub(); currentTextRectOffsetX += textFieldOffset.GetX(); currentTextRectOffsetY += textFieldOffset.GetY(); } @@ -107,14 +107,11 @@ void TextFieldPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper) auto layoutProperty = frameNode->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); textFieldContentModifier_->SetTextObscured(textFieldPattern->GetTextObscured()); - textFieldContentModifier_->SetShowCounter(layoutProperty->GetShowCounterValue(false) && - layoutProperty->HasMaxLength() && !textFieldPattern->IsNormalInlineState()); - textFieldContentModifier_->SetShowErrorState(layoutProperty->GetShowErrorTextValue(false) && + textFieldContentModifier_->SetShowErrorState( + layoutProperty->GetShowErrorTextValue(false) && paintProperty->GetInputStyleValue(InputStyle::DEFAULT) != InputStyle::INLINE); textFieldContentModifier_->SetErrorTextValue(layoutProperty->GetErrorTextValue("")); textFieldContentModifier_->SetShowUnderlineState(layoutProperty->GetShowUnderlineValue(false)); - textFieldContentModifier_->SetShowPasswordIcon(textFieldPattern->GetShowResultImageSrc()); - textFieldContentModifier_->SetHidePasswordIcon(textFieldPattern->GetHideResultImageSrc()); auto pipeline = frameNode->GetContext(); CHECK_NULL_VOID(pipeline); auto theme = pipeline->GetTheme(); @@ -161,7 +158,6 @@ void TextFieldPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper) textFieldOverlayModifier_->SetCursorColor(cursorColor); auto selectedColor = paintProperty->GetSelectedBackgroundColorValue(theme->GetSelectedColor()); textFieldOverlayModifier_->SetSelectedBackGroundColor(selectedColor); - textFieldOverlayModifier_->SetRedrawFlag(textFieldPattern->GetDrawOverlayFlag()); if (paintProperty->GetCursorWidth().has_value()) { float cursorWidth = static_cast(paintProperty->GetCursorWidthValue().ConvertToPx()); textFieldOverlayModifier_->SetCursorWidth(cursorWidth); @@ -172,11 +168,7 @@ void TextFieldPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper) CHECK_NULL_VOID(frameNode); auto layoutProperty = frameNode->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - textFieldOverlayModifier_->SetShowCounter(layoutProperty->GetShowCounterValue(false) && - layoutProperty->HasMaxLength() && !textFieldPattern->IsNormalInlineState()); - if (textFieldPattern->GetSelectMode() != SelectionMode::NONE) { - textFieldPattern->MarkRedrawOverlay(); - } + textFieldOverlayModifier_->SetChangeSelectedRects(textFieldPattern->NeedPaintSelect()); UpdateScrollBar(); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.h b/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.h index 4f63c970983..19898ef6855 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.h @@ -62,6 +62,8 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(BackgroundColor, Color, PROPERTY_UPDATE_RENDER); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(PressBgColor, Color, PROPERTY_UPDATE_RENDER); ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(HoverBgColor, Color, PROPERTY_UPDATE_RENDER); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(FirstHandleInfo, HandleInfoNG, PROPERTY_UPDATE_RENDER); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(SecondHandleInfo, HandleInfoNG, PROPERTY_UPDATE_RENDER); private: ACE_DISALLOW_COPY_AND_MOVE(TextFieldPaintProperty); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 06dc4a8bdb0..50da04e93f9 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -19,11 +19,13 @@ #include #include #include +#include #include #include #include "base/geometry/dimension.h" #include "base/geometry/ng/offset_t.h" +#include "base/geometry/ng/rect_t.h" #include "base/geometry/offset.h" #include "base/i18n/localization.h" #include "base/log/dump_log.h" @@ -43,8 +45,13 @@ #include "core/components/text_field/textfield_theme.h" #include "core/components/theme/icon_theme.h" #include "core/components_ng/image_provider/image_loading_context.h" +#include "core/components_ng/pattern/overlay/modal_style.h" #include "core/components_ng/pattern/search/search_event_hub.h" #include "core/components_ng/pattern/search/search_pattern.h" +#include "core/components_ng/pattern/select_overlay/select_overlay_property.h" +#include "core/components_ng/pattern/text/text_base.h" +#include "core/components_ng/pattern/text/text_pattern.h" +#include "core/components_ng/pattern/text/text_styles.h" #include "core/components_ng/pattern/text_drag/text_drag_pattern.h" #include "core/components_ng/pattern/text_field/text_field_controller.h" #include "core/components_ng/pattern/text_field/text_field_event_hub.h" @@ -98,6 +105,8 @@ const std::string EMAIL_WHITE_LIST = "[\\w.\\@]"; const std::string URL_WHITE_LIST = "[a-zA-z]+://[^\\s]*"; const std::string SHOW_PASSWORD_SVG = "SYS_SHOW_PASSWORD_SVG"; const std::string HIDE_PASSWORD_SVG = "SYS_HIDE_PASSWORD_SVG"; +const std::string CLIPBOARD_HAS_DATA = "HAS_DATA"; +const std::string SELECT_OVERLAY_MENU_IS_SHOW = "MENU_IS_SHOW"; void SwapIfLarger(int32_t& a, int32_t& b) { @@ -106,28 +115,6 @@ void SwapIfLarger(int32_t& a, int32_t& b) } } -void RemoveErrorTextFromValue(const std::string& value, const std::string& errorText, std::string& result) -{ - int32_t valuePtr = 0; - int32_t errorTextPtr = 0; - auto valueSize = static_cast(value.length()); - auto errorTextSize = static_cast(errorText.length()); - while (errorTextPtr < errorTextSize) { - while (value[valuePtr] != errorText[errorTextPtr] && valuePtr < valueSize) { - result += value[valuePtr]; - valuePtr++; - } - // no more text left to remove in value - if (valuePtr >= valueSize) { - return; - } - // increase both value ptr and error text ptr if char in value is removed - valuePtr++; - errorTextPtr++; - } - result += value.substr(valuePtr); -} - std::string ConvertFontFamily(const std::vector& fontFamily) { std::string result; @@ -199,6 +186,9 @@ TextFieldPattern::TextFieldPattern() : twinklingInterval_(TWINKLING_INTERVAL_MS) !PipelineBase::GetCurrentContext()->IsFocusWindowIdSetted()) { needToRequestKeyboardOnFocus_ = true; } + contentController_ = MakeRefPtr(WeakClaim(this)); + selectController_ = MakeRefPtr(WeakClaim(this)); + selectController_->InitContentController(contentController_); } TextFieldPattern::~TextFieldPattern() @@ -224,29 +214,6 @@ TextFieldPattern::~TextFieldPattern() } } -void TextFieldPattern::BeforeCreateLayoutWrapper() -{ - if (caretUpdateType_ == CaretUpdateType::DOUBLE_CLICK) { - UpdateSelectionByDoubleClick(); - MarkRedrawOverlay(); - } else if (caretUpdateType_ == CaretUpdateType::PRESSED || caretUpdateType_ == CaretUpdateType::LONG_PRESSED) { - UpdateCaretByPressOrLongPress(); - MarkRedrawOverlay(); - } else if (caretUpdateType_ == CaretUpdateType::EVENT) { - if (isDoubleClick_) { - // handle double click event only - UpdateSelectionByMouseDoubleClick(); - } else if (isMousePressed_) { - // handle mouse event only - UpdateCaretPositionByMouseMovement(); - } - } - UpdateEditingValueCaretPositionToRecord(); - if (!IsSelected()) { - UpdateSelection(textEditingValue_.caretPosition); - } -} - bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dirty, const DirtySwapConfig& config) { if (config.skipMeasure || dirty->SkipMeasureContent()) { @@ -263,13 +230,10 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir auto textFieldLayoutAlgorithm = DynamicCast(layoutAlgorithmWrapper->GetLayoutAlgorithm()); CHECK_NULL_RETURN(textFieldLayoutAlgorithm, false); auto paragraph = textFieldLayoutAlgorithm->GetParagraph(); + float paragraphWidth = 0.0f; if (paragraph) { paragraph_ = paragraph; - } - auto counterParagraph = textFieldLayoutAlgorithm->GetCounterParagraph(); - if (counterParagraph) { - counterParagraph_ = counterParagraph; - countHeight_ = counterParagraph->GetHeight(); + paragraphWidth = paragraph->GetLongestLine(); } auto errorParagraph = textFieldLayoutAlgorithm->GetErrorParagraph(); if (errorParagraph) { @@ -278,8 +242,6 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir if (!IsDragging()) { dragParagraph_ = paragraph_; } - - auto paragraphWidth = textFieldLayoutAlgorithm->GetParagraphWidth(); auto textRect = textFieldLayoutAlgorithm->GetTextRect(); if (!(needToRefreshSelectOverlay_ && (!NearEqual(paragraphWidth, paragraphWidth_) || !NearEqual(textRect, textRect_))) || @@ -288,49 +250,26 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir } paragraphWidth_ = paragraphWidth; textRect_ = textRect; - imageRect_ = textFieldLayoutAlgorithm->GetImageRect(); - unitWidth_ = textFieldLayoutAlgorithm->GetUnitWidth(); parentGlobalOffset_ = textFieldLayoutAlgorithm->GetParentGlobalOffset(); + UpdateSelectController(); UpdateTextFieldManager(Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()), frameRect_.Height()); - auto textRectNotNeedToChange = UpdateCaretRect(); + AdjustTextInReasonableArea(); + UpdateCaretRect(); UpdateCaretInfoToController(); auto hostLayoutProperty = dirty->GetHostNode() ? dirty->GetHostNode()->GetLayoutProperty() : nullptr; - if (paragraph) { - if (inlineFocusState_ && needApplyInlineSize_ && IsNormalInlineState()) { - CalcSize idealSize; -#ifndef USE_GRAPHIC_TEXT_GINE - auto paragraphWidth = paragraph_->GetLongestLine(); -#else - auto paragraphWidth = paragraph_->GetActualWidth(); -#endif - std::optional width(paragraphWidth + inlinePadding_); - idealSize.SetWidth(width); - hostLayoutProperty->UpdateUserDefinedIdealSize(idealSize); - } - } if (hostLayoutProperty) { hostLayoutProperty->ResetTextAlignChanged(); } if (needToRefreshSelectOverlay_) { - ProcessOverlay(); StopTwinkling(); + ProcessOverlay(); needToRefreshSelectOverlay_ = false; } if (inlineSelectAllFlag_) { HandleOnSelectAll(false, true); inlineSelectAllFlag_ = false; } - if (updateSelectionAfterObscure_) { - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - updateSelectionAfterObscure_ = false; - } - if (textRectWillChange_) { - if (!textSelector_.StartEqualToDest()) { - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - } - textRectWillChange_ = false; - } if (mouseStatus_ == MouseStatus::RELEASED) { mouseStatus_ = MouseStatus::NONE; } @@ -339,62 +278,24 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir } else { SetScrollEnable(GreatNotEqual(textRect_.Width(), contentRect_.Width())); } + UpdateScrollBarOffset(); if (config.frameSizeChange) { if (GetScrollBar() != nullptr) { GetScrollBar()->ScheduleDisappearDelayTask(); } } - if (textRectNotNeedToChange) { - return true; - } - // after new text input or events such as left right key, - // the procedure will be: - // caret position change (such as move left) - // caret get offset from typographic algorithm - // if caret position exceeds constrained content region, adjust both caret position and text rect offset - float dx = AdjustTextRectOffsetX(); - float dy = AdjustTextAreaOffsetY(); - UpdateSelectionOffset(); - if (caretUpdateType_ == CaretUpdateType::HANDLE_MOVE) { - if ((!NearZero(dx) || !NearZero(dy)) && !isSingleHandle_) { - UpdateOtherHandleOnMove(dx, dy); - } - // trigger selection box repaint - MarkRedrawOverlay(); - } else if (caretUpdateType_ == CaretUpdateType::HANDLE_MOVE_DONE) { - SetHandlerOnMoveDone(); - } else if ((!NearZero(dx) || !NearZero(dy)) && SelectOverlayIsOn() && selectionMode_ == SelectionMode::SELECT) { - SelectHandleInfo firstInfo, secondInfo; - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - textSelector_.firstHandleOffset_.AddX(dx); - textSelector_.firstHandleOffset_.AddY(dy); - firstInfo.paintRect = { textSelector_.firstHandleOffset_, handlePaintSize }; - textSelector_.secondHandleOffset_.AddX(dx); - textSelector_.secondHandleOffset_.AddY(dy); - secondInfo.paintRect = { textSelector_.secondHandleOffset_, handlePaintSize }; - selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(firstInfo, secondInfo); - } - UpdateScrollBarOffset(); - caretUpdateType_ = CaretUpdateType::NONE; return true; } bool TextFieldPattern::HasFocus() const { - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, false); - auto focusHub = tmpHost->GetOrCreateFocusHub(); - - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(tmpHost->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); - } + auto focusHub = GetFocusHub(); CHECK_NULL_RETURN(focusHub, false); return focusHub->IsCurrentFocus(); } -void TextFieldPattern::UpdateCaretInfoToController() const +void TextFieldPattern::UpdateCaretInfoToController() const // todo确定更新时机 { CHECK_NULL_VOID(HasFocus()); #if defined(ENABLE_STANDARD_INPUT) @@ -404,46 +305,60 @@ void TextFieldPattern::UpdateCaretInfoToController() const LOGD("UpdateCaretInfoToController, left %{public}f, top %{public}f, width %{public}f, height %{public}f", cursorInfo.left, cursorInfo.top, cursorInfo.width, cursorInfo.height); MiscServices::InputMethodController::GetInstance()->OnCursorUpdate(cursorInfo); - auto value = GetEditingValue(); - LOGD("Start %{public}d, end %{public}d", textSelector_.GetStart(), textSelector_.GetEnd()); + LOGD("Start %{public}d, end %{public}d", selectController_->GetStart(), selectController_->GetEnd()); MiscServices::InputMethodController::GetInstance()->OnSelectionChange( - StringUtils::Str8ToStr16(value.text), textSelector_.GetStart(), textSelector_.GetEnd()); + StringUtils::Str8ToStr16(contentController_->GetTextValue()), selectController_->GetStartIndex(), + selectController_->GetEndIndex()); #else if (HasConnection()) { TextEditingValue value; - value.text = textEditingValue_.text; + value.text = contentController_->GetTextValue(); value.hint = GetPlaceHolder(); - value.selection.Update(textSelector_.baseOffset, textSelector_.destinationOffset); + value.selection.Update(selectController_->GetStartIndex(), selectController_->GetEndIndex()); connection_->SetEditingState(value, GetInstanceId()); } #endif } // return: true if text rect offset will NOT be further changed by caret position -bool TextFieldPattern::UpdateCaretRect() +void TextFieldPattern::UpdateCaretRect() { - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, false); - auto focusHub = tmpHost->GetOrCreateFocusHub(); - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(tmpHost->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); - } + CHECK_NULL_VOID(!selectController_->IsSelected()); + auto focusHub = GetFocusHub(); if (focusHub && !focusHub->IsCurrentFocus()) { CloseSelectOverlay(true); LOGW("Not on focus, cannot update caret"); - return true; + return; } - if (textEditingValue_.text.empty()) { - SetCaretOffsetForEmptyTextOrPositionZero(); - return false; - } + selectController_->UpdateCaretOffset(); + auto caretRect = selectController_->GetCaretRect(); + selectController_->MoveHandleToContentRect(caretRect); +} - UpdateCaretRectByPosition(textEditingValue_.caretPosition); +void TextFieldPattern::AdjustTextInReasonableArea() +{ + auto contentBottomBoundary = contentRect_.GetY() + contentRect_.GetSize().Height(); + if (textRect_.Height() > contentRect_.Height()) { + if (textRect_.GetY() + textRect_.Height() < contentBottomBoundary) { + auto dy = contentBottomBoundary - textRect_.GetY() - textRect_.Height(); + textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); + } + } else { + if (textRect_.GetY() < contentRect_.GetY()) { + auto dy = contentRect_.GetY() - textRect_.GetY(); + textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); + } + } - return caretUpdateType_ == CaretUpdateType::NONE && !textRectWillChange_; + auto contentRightBoundary = contentRect_.GetX() + contentRect_.GetSize().Width(); + if (textRect_.Width() > contentRect_.Width()) { + if (textRect_.GetX() + textRect_.Width() < contentRightBoundary) { + auto dx = contentRightBoundary - textRect_.GetX() - textRect_.Width(); + textRect_.SetLeft(textRect_.GetX() + dx); + } + } } float TextFieldPattern::GetIconSize() @@ -482,86 +397,6 @@ float TextFieldPattern::GetIconRightOffset() return (iconHotZoneSize - iconSize) / 2.0f; } -void TextFieldPattern::CreateSingleHandle(bool animation, bool isMenuShow) -{ - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - isSingleHandle_ = true; - RectF secondHandle; - auto secondHandleMetrics = CalcCursorOffsetByPosition(textEditingValue_.caretPosition, isTouchAtLeftOffset_); - OffsetF secondHandleOffset(secondHandleMetrics.offset.GetX() + parentGlobalOffset_.GetX(), - secondHandleMetrics.offset.GetY() + parentGlobalOffset_.GetY()); - if (textEditingValue_.Empty()) { - auto layoutProperty = tmpHost->GetLayoutProperty(); - auto align = layoutProperty ? layoutProperty->GetTextAlignValue(TextAlign::START) : TextAlign::START; - float offsetX = contentRect_.GetX(); - auto baseWidth = frameRect_.Width(); - auto showingPasswordIcon = (layoutProperty ? layoutProperty->GetShowPasswordIcon().value_or(true) : false) && - (layoutProperty ? layoutProperty->GetTextInputTypeValue( - TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD - : false); - baseWidth -= showingPasswordIcon ? GetIconSize() + GetIconRightOffset() : 0.0f; - switch (align) { - case TextAlign::CENTER: - offsetX = baseWidth * 0.5f; - break; - case TextAlign::END: - offsetX = baseWidth - GetPaddingRight(); - break; - case TextAlign::START: - default: - break; - } - secondHandleOffset = - OffsetF(offsetX + parentGlobalOffset_.GetX(), contentRect_.GetY() + parentGlobalOffset_.GetY()); - } - textSelector_.secondHandleOffset_ = secondHandleOffset; - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - secondHandle.SetOffset(secondHandleOffset); - secondHandle.SetSize(handlePaintSize); - ShowSelectOverlay(std::nullopt, secondHandle, animation, isMenuShow); - selectionMode_ = SelectionMode::NONE; - StartTwinkling(); -} - -bool TextFieldPattern::UpdateCaretByPressOrLongPress() -{ - if (CaretPositionCloseToTouchPosition() && !SelectOverlayIsOn() && - caretUpdateType_ != CaretUpdateType::LONG_PRESSED && !isMousePressed_) { - CreateSingleHandle(true, false); - return true; - } - // caret offset updated by gesture will not cause textRect to change offset - UpdateCaretPositionByPressOffset(); - if (caretUpdateType_ == CaretUpdateType::PRESSED) { - UpdateSelection(textEditingValue_.caretPosition); - if (!GetEditingValue().text.empty() && isFocusedBeforeClick_ && !isMousePressed_) { - CreateSingleHandle(true, false); - } else { - StartTwinkling(); - } - } else if (caretUpdateType_ == CaretUpdateType::LONG_PRESSED) { - // in long press case, we have caret and one handle at pressed location and another handle at -1 or +1 position - ProcessOverlay(true); - } - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - return true; -} - -void TextFieldPattern::UpdateCaretByRightClick() -{ - ProcessOverlay(true); -} - -bool TextFieldPattern::CaretPositionCloseToTouchPosition() -{ - auto xInRange = GreatOrEqual(lastTouchOffset_.GetX(), caretRect_.GetX() - PreferredLineHeight()) && - LessOrEqual(lastTouchOffset_.GetX(), caretRect_.GetX() + PreferredLineHeight()); - auto yInRange = GreatOrEqual(lastTouchOffset_.GetY(), caretRect_.GetY()) && - LessOrEqual(lastTouchOffset_.GetY(), caretRect_.GetY() + PreferredLineHeight()); - return xInRange && yInRange; -} - bool TextFieldPattern::IsTextArea() const { auto tmpHost = GetHost(); @@ -571,374 +406,46 @@ bool TextFieldPattern::IsTextArea() const return layoutProperty->HasMaxLines() ? layoutProperty->GetMaxLinesValue(1) > 1 : true; } -void TextFieldPattern::UpdateDestinationToCaretByEvent() -{ - CHECK_NULL_VOID(isMousePressed_); - UpdateSelection(textSelector_.GetStart(), textEditingValue_.caretPosition); - if (textSelector_.destinationOffset != textSelector_.baseOffset) { - selectionMode_ = SelectionMode::SELECT; - } -} - -void TextFieldPattern::UpdateCaretPositionByLastTouchOffset() -{ - Offset offset = GetLastTouchOffset() - Offset(textRect_.GetX(), textRect_.GetY()); - auto position = ConvertTouchOffsetToCaretPosition(offset); - textEditingValue_.CursorMoveToPosition(position); -} - -// return bool that caret might move out of content rect and need adjust position -bool TextFieldPattern::UpdateCaretPositionByMouseMovement() -{ - if (GetEditingValue().text.empty()) { - caretRect_.SetLeft(textRect_.GetX()); - caretRect_.SetTop(textRect_.GetY()); - selectionMode_ = SelectionMode::NONE; - UpdateSelection(0, 0); - return false; - } - bool needToShiftCaretAndTextRect = false; - // if mouse keep at position out of content rect, caret will keep moving left or right - if (lastTouchOffset_.GetX() < contentRect_.GetX() || - lastTouchOffset_.GetX() > contentRect_.GetX() + contentRect_.Width()) { - needToShiftCaretAndTextRect = true; - } - UpdateCaretPositionByLastTouchOffset(); - UpdateSelection(textSelector_.GetStart(), textEditingValue_.caretPosition); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - selectionMode_ = - textSelector_.destinationOffset == textSelector_.baseOffset ? SelectionMode::NONE : SelectionMode::SELECT; - return needToShiftCaretAndTextRect; -} - -void TextFieldPattern::UpdateSelectionByDoubleClick() -{ - isDoubleClick_ = false; - UpdateCaretPositionByPressOffset(); - ProcessOverlay(true); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); -} - -void TextFieldPattern::UpdateSelectionByMouseDoubleClick() -{ - isDoubleClick_ = false; - if (GetEditingValue().text.empty()) { - selectionMode_ = SelectionMode::NONE; - UpdateSelection(0, 0); - return; - } - UpdateCaretPositionByLastTouchOffset(); - UpdateSelectorByPosition(textEditingValue_.caretPosition); - selectionMode_ = SelectionMode::SELECT; - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); -} - -void TextFieldPattern::UpdateCaretOffsetByEvent() -{ - if (textEditingValue_.text.empty()) { - UpdateSelection(0, 0); - SetCaretOffsetForEmptyTextOrPositionZero(); - return; - } - if (isMousePressed_) { - // handle mouse event only - UpdateCaretPositionByMouseMovement(); - return; - } - if (!IsSelected()) { - UpdateSelection(textEditingValue_.caretPosition); - } - UpdateCaretRectByPosition(textEditingValue_.caretPosition); -} - void TextFieldPattern::UpdateSelectionOffset() { CHECK_NULL_VOID(IsSelected()); - if (textSelector_.baseOffset == textSelector_.destinationOffset) { - textSelector_.selectionBaseOffset.SetX(caretRect_.GetX()); - textSelector_.selectionDestinationOffset.SetX(caretRect_.GetX()); - return; - } - if (selectionMode_ == SelectionMode::SELECT_ALL) { - textSelector_.selectionBaseOffset.SetX(textRect_.GetX()); - textSelector_.selectionDestinationOffset.SetX(textRect_.GetX() + textRect_.Width()); - std::optional firstHandleOption; - std::optional secondHandleOption; - if (textBoxes_.empty()) { - return; - } - if (SelectOverlayIsOn()) { - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; -#ifndef USE_GRAPHIC_TEXT_GINE - auto textBoxLocalOffsetBegin = - OffsetF(textBoxes_.begin()->rect_.GetLeft() + (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()), - textBoxes_.begin()->rect_.GetTop() + (IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) + - BOX_EPSILON); -#else - auto textBoxLocalOffsetBegin = - OffsetF(textBoxes_.begin()->rect.GetLeft() + (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()), - textBoxes_.begin()->rect.GetTop() + (IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) + - BOX_EPSILON); -#endif -#ifndef USE_GRAPHIC_TEXT_GINE - auto textBoxLocalOffsetEnd = - OffsetF(textBoxes_.rbegin()->rect_.GetRight() + (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()), - textBoxes_.rbegin()->rect_.GetTop() + (IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) + - BOX_EPSILON); -#else - auto textBoxLocalOffsetEnd = - OffsetF(textBoxes_.rbegin()->rect.GetRight() + (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()), - textBoxes_.rbegin()->rect.GetTop() + (IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) + - BOX_EPSILON); -#endif - OffsetF firstHandleOffset(textBoxLocalOffsetBegin.GetX() + parentGlobalOffset_.GetX(), - textBoxLocalOffsetBegin.GetY() + parentGlobalOffset_.GetY() - BOX_EPSILON); - textSelector_.firstHandleOffset_ = firstHandleOffset; - RectF firstHandle; - firstHandle.SetOffset(firstHandleOffset); - firstHandle.SetSize(handlePaintSize); - firstHandleOption = firstHandle; - OffsetF secondHandleOffset(textBoxLocalOffsetEnd.GetX() + parentGlobalOffset_.GetX(), - textBoxLocalOffsetEnd.GetY() + parentGlobalOffset_.GetY() - BOX_EPSILON); - textSelector_.secondHandleOffset_ = secondHandleOffset; - RectF secondHandle; - secondHandle.SetOffset(secondHandleOffset); - secondHandle.SetSize(handlePaintSize); - secondHandleOption = secondHandle; - if (firstHandleOption.has_value() || secondHandleOption.has_value()) { - ShowSelectOverlay(firstHandleOption, secondHandleOption, true); - } - } - return; - } -} - -void TextFieldPattern::UpdateCaretPositionByTextEdit() -{ - if (textEditingValue_.text.empty()) { - UpdateSelection(0); - SetCaretOffsetForEmptyTextOrPositionZero(); - return; - } - if (textEditingValue_.caretPosition == 0) { - SetCaretOffsetForEmptyTextOrPositionZero(); - return; - } - UpdateCaretRectByPosition(textEditingValue_.caretPosition); - UpdateSelection(textEditingValue_.caretPosition); -} - -void TextFieldPattern::UpdateCaretRectByPosition(int32_t position) -{ - auto caretMetrics = CalcCursorOffsetByPosition(position, isTouchAtLeftOffset_); - caretRect_.SetLeft(caretMetrics.offset.GetX()); - // add 1.0f here for offsetToParagraphBeginning offsetY is negative when caret position is zero - caretRect_.SetTop(caretMetrics.offset.GetY()); - caretRect_.SetHeight(caretMetrics.height); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - layoutProperty->UpdateCaretPosition(textEditingValue_.caretPosition); -} - -void TextFieldPattern::SetCaretOffsetForEmptyTextOrPositionZero() -{ - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); - caretRect_.SetLeft(IsTextArea() ? contentRect_.Left() : textRect_.GetX()); - caretRect_.SetTop(IsTextArea() ? textRect_.GetY() : contentRect_.Top()); - caretRect_.SetHeight(PreferredLineHeight()); - switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { - case TextAlign::START: - caretRect_.SetLeft(textRect_.GetX()); - return; - case TextAlign::CENTER: - caretRect_.SetLeft(static_cast(contentRect_.GetX()) + contentRect_.Width() / 2.0f); - return; - case TextAlign::END: - caretRect_.SetLeft(static_cast(contentRect_.GetX()) + contentRect_.Width() - - static_cast(CURSOR_WIDTH.ConvertToPx())); - return; - default: - caretRect_.SetLeft(textRect_.GetX()); - return; - } -} - -void TextFieldPattern::UpdateCaretPositionByPressOffset() -{ - if (GetEditingValue().text.empty()) { - textEditingValue_.CursorMoveToPosition(0); - return; - } - UpdateCaretPositionByLastTouchOffset(); - - selectionMode_ = SelectionMode::NONE; -} - -CaretMetricsF TextFieldPattern::CalcCursorOffsetByPosition(int32_t position, bool isStart) -{ - // this function will calculate caret offset and height by caret position - auto tmpHost = GetHost(); - CaretMetricsF result; - CHECK_NULL_RETURN(tmpHost, result); - CaretMetricsF resultDownstream; - CaretMetricsF resultUpstream; - auto isSuccessDownstream = ComputeOffsetForCaretDownstream(position, resultDownstream); - auto isSuccessUpstream = ComputeOffsetForCaretUpstream(position, resultUpstream); - LOGD("position : %{public}d resultDownstream: %{public}s resultUpstream: %{public}s", position, - resultDownstream.offset.ToString().c_str(), resultUpstream.offset.ToString().c_str()); - if (!(isSuccessDownstream || isSuccessUpstream)) { - if (IsTextArea()) { - auto offsetX = contentRect_.GetX(); - auto layoutProperty = tmpHost->GetLayoutProperty(); - switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { - case TextAlign::CENTER: - offsetX = static_cast(contentRect_.GetX()) + contentRect_.Width() / 2.0f; - break; - case TextAlign::END: - offsetX = static_cast(contentRect_.GetX()) + contentRect_.Width() - - static_cast(CURSOR_WIDTH.ConvertToPx()); - break; - default: - break; - } - result.offset = OffsetF(offsetX, contentRect_.GetY()); - } else { - result.offset = OffsetF(textRect_.GetX(), contentRect_.GetY()); - } -#ifndef USE_GRAPHIC_TEXT_GINE - result.height = textBoxes_.empty() ? PreferredLineHeight() : textBoxes_.begin()->rect_.GetHeight(); -#else - result.height = textBoxes_.empty() ? PreferredLineHeight() : textBoxes_.begin()->rect.GetHeight(); -#endif - return result; - } - if (isSuccessDownstream && isStart && resultUpstream.offset.GetY() < resultDownstream.offset.GetY()) { - result = resultDownstream; - } else if (isSuccessUpstream && !isStart && resultUpstream.offset.GetY() < resultDownstream.offset.GetY()) { - result = resultUpstream; - } else { - if (isSuccessDownstream) { - result = resultDownstream; - } else { - result = resultUpstream; - } - } - LOGD("result stream: %{public}s ", result.ToString().c_str()); - result.offset.AddX(IsTextArea() ? contentRect_.GetX() : textRect_.GetX()); - result.offset.AddY(IsTextArea() ? textRect_.GetY() : contentRect_.GetY()); - return result; + selectController_->CalculateHandleOffset(); } -float TextFieldPattern::AdjustTextRectOffsetX() +void TextFieldPattern::CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) { - auto cursorWidth = caretRect_.Width(); - auto contentLeftBoundary = contentRect_.GetX(); - auto contentRightBoundary = contentRect_.GetX() + contentRect_.GetSize().Width() - unitWidth_; - if (IsTextArea() || textEditingValue_.text.empty()) { - caretRect_.SetLeft(std::clamp( - caretRect_.GetX(), contentLeftBoundary, std::max(contentLeftBoundary, contentRightBoundary - cursorWidth))); - return 0.0f; - } - float textDx = 0.0f; - if (textRect_.Width() > contentRect_.Width()) { - if (textRect_.GetX() + textRect_.Width() < contentRightBoundary) { - textDx = contentRightBoundary - textRect_.GetX() - textRect_.Width(); - caretRect_.SetLeft(caretRect_.GetX() + textDx); - textRect_.SetLeft(textRect_.GetX() + textDx); - } - } - // text rect length exceeds content length, but cursor is still in the region - if (CursorInContentRegion()) { - return textDx; - } - auto offsetToParagraphBeginning = caretRect_.GetX() - textRect_.GetX(); - float dx = 0.0f; - if (caretRect_.GetX() < contentLeftBoundary) { - dx = contentLeftBoundary - caretRect_.GetX(); - caretRect_.SetLeft(caretRect_.GetX() + dx); - textRect_.SetLeft(caretRect_.GetX() - offsetToParagraphBeginning); - } else if (caretRect_.GetX() + cursorWidth > contentRightBoundary) { - dx = (contentRightBoundary - static_cast(cursorWidth)) - caretRect_.GetX(); - caretRect_.SetLeft(caretRect_.GetX() + dx); - textRect_.SetLeft(caretRect_.GetX() - offsetToParagraphBeginning); - } - dx += textDx; - return dx; -} - -float TextFieldPattern::AdjustTextAreaOffsetY() -{ - if (!IsTextArea()) { - return 0.0f; - } - float textDy = 0.0f; - auto contentBottomBoundary = contentRect_.GetY() + contentRect_.GetSize().Height(); - if (textRect_.Height() > contentRect_.Height()) { - if (textRect_.GetY() + textRect_.Height() < contentBottomBoundary) { - textDy = contentBottomBoundary - textRect_.GetY() - textRect_.Height(); - caretRect_.SetTop(caretRect_.GetY() + textDy); - textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + textDy)); - } - } else { - if (textRect_.GetY() < contentRect_.GetY()) { - textDy = contentRect_.GetY() - textRect_.GetY(); - caretRect_.SetTop(caretRect_.GetY() + textDy); - textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + textDy)); - } - } - - if (caretRect_.GetY() < contentRect_.GetY()) { - auto dy = contentRect_.GetY() - caretRect_.GetY(); - caretRect_.SetTop(caretRect_.GetY() + dy); - textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); - return dy + textDy; - } - auto dy = contentRect_.GetY() + GetBorderTop() + contentRect_.Height() - (caretRect_.Height() + caretRect_.GetY()); - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN) || IsNormalInlineState()) { - dy = contentRect_.GetY() + contentRect_.Height() - (caretRect_.Height() + caretRect_.GetY()); - } - // caret does not exceed bottom boundary, still need to check against safeArea - if (GreatOrEqual(dy, 0.0f)) { - return FitCursorInSafeArea() + textDy; - } - caretRect_.SetTop(caretRect_.GetY() + dy - BOX_EPSILON * 2); - textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy - BOX_EPSILON * 2)); - return dy + textDy; + paragraph_->CalcCaretMetricsByPosition(extent, caretCaretMetric, textAffinity); + LOGD("result stream : %{public}s , textAffinity: %{public}d", result.ToString().c_str(), textAffinity); + caretCaretMetric.offset.AddX(textRect_.GetX()); + caretCaretMetric.offset.AddY(textRect_.GetY()); } bool TextFieldPattern::CursorInContentRegion() { if (IsTextArea()) { - return GreatOrEqual(caretRect_.Top(), contentRect_.GetY()) && - LessOrEqual( - caretRect_.Top() + GetTextOrPlaceHolderFontSize(), contentRect_.GetY() + contentRect_.Height()); + return GreatOrEqual(selectController_->GetCaretRect().GetY(), contentRect_.GetY()) && + LessOrEqual(selectController_->GetCaretRect().GetY() + GetTextOrPlaceHolderFontSize(), + contentRect_.GetY() + contentRect_.Height()); } - return GreatOrEqual(caretRect_.GetX(), contentRect_.GetX()) && - LessOrEqual( - caretRect_.GetX() + CURSOR_WIDTH.ConvertToPx(), contentRect_.GetX() + contentRect_.Width() - unitWidth_); + return GreatOrEqual(selectController_->GetCaretRect().GetX(), contentRect_.GetX()) && + LessOrEqual(selectController_->GetCaretRect().GetX() + CURSOR_WIDTH.ConvertToPx(), + contentRect_.GetX() + contentRect_.Width()); } float TextFieldPattern::FitCursorInSafeArea() { - if (caretUpdateType_ != CaretUpdateType::INPUT) { - return 0.0f; - } - // check if caret is below safeArea auto pipeline = PipelineContext::GetCurrentContext(); auto safeAreaBottom = pipeline->GetSafeArea().bottom_; safeAreaBottom = safeAreaBottom.Combine(pipeline->GetSafeAreaManager()->GetKeyboardInset()); CHECK_NULL_RETURN(safeAreaBottom.IsValid(), 0.0f); // get global height of caret auto host = GetHost(); - auto globalBottom = host->GetPaintRectOffset().GetY() + caretRect_.Bottom(); + auto globalBottom = host->GetPaintRectOffset().GetY() + selectController_->GetCaretRect().Bottom(); if (globalBottom > safeAreaBottom.start) { auto dy = safeAreaBottom.start - globalBottom; - caretRect_.SetTop(caretRect_.GetY() + dy); textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); + selectController_->UpdateCaretOffset(); return dy; } return 0.0f; @@ -957,11 +464,7 @@ void TextFieldPattern::OnScrollEndCallback() if (scrollBar) { scrollBar->ScheduleDisappearDelayTask(); } - auto selectOverlayProxy = GetSelectOverlay(); - CHECK_NULL_VOID(selectOverlayProxy); - if (originalIsMenuShow_) { - selectOverlayProxy->ShowOrHiddenMenu(false); - } + UpdateSelectMenuVisibility(true); } void TextFieldPattern::OnTextAreaScroll(float offset) @@ -975,334 +478,62 @@ void TextFieldPattern::OnTextAreaScroll(float offset) } else if (textRect_.GetY() + textRect_.Height() + offset < contentRect_.GetY() + contentRect_.Height()) { offset = contentRect_.GetY() + contentRect_.Height() - textRect_.GetY() - textRect_.Height(); } - caretRect_.SetTop(caretRect_.GetY() + offset); currentOffset_ = textRect_.GetY() + offset; - textRect_.SetOffset(OffsetF(textRect_.GetX(), currentOffset_)); - if (SelectOverlayIsOn()) { - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - textSelector_.secondHandleOffset_.SetY(textSelector_.secondHandleOffset_.GetY() + offset); - std::optional secondHandle = RectF(textSelector_.secondHandleOffset_, handlePaintSize); - auto secondHandleHeight = 0.0f; - auto secondHandleOffset = textSelector_.secondHandleOffset_ - parentGlobalOffset_; - if (GreatOrEqual(offset, 0.0f) && GreatNotEqual(secondHandleOffset.GetY(), contentRect_.GetY())) { - secondHandleHeight = secondHandle->Height(); - } - if (LessNotEqual(offset, 0.0f) && GreatNotEqual(secondHandleOffset.GetY() + secondHandle->Height(), - contentRect_.GetY() + contentRect_.Height())) { - secondHandleHeight = secondHandle->Height(); - } - std::optional firstHandle; - auto firstHandleHeight = 0.0f; - if (!isSingleHandle_) { - textSelector_.firstHandleOffset_.SetY(textSelector_.firstHandleOffset_.GetY() + offset); - firstHandle = { textSelector_.firstHandleOffset_, handlePaintSize }; - auto firstHandleOffset = textSelector_.firstHandleOffset_ - parentGlobalOffset_; - if (GreatOrEqual(offset, 0.0f) && GreatNotEqual(firstHandleOffset.GetY(), contentRect_.GetY())) { - firstHandleHeight = firstHandle->Height(); - } - if (LessNotEqual(offset, 0.0f) && GreatNotEqual(firstHandleOffset.GetY() + firstHandle->Height(), - contentRect_.GetY() + contentRect_.Height())) { - firstHandleHeight = firstHandle->Height(); - } - } - SelectHandleInfo firstHandleInfo; - SelectHandleInfo secondHandleInfo; - firstHandleInfo.paintRect = - RectF(firstHandle->Left(), firstHandle->Top(), firstHandle->Width(), firstHandle->Height()); - secondHandleInfo.paintRect = - RectF(secondHandle->Left(), secondHandle->Top(), secondHandle->Width(), secondHandle->Height()); - if (firstHandle.has_value()) { - firstHandleInfo.isShow = CheckHandleVisible(firstHandle.value()); - } - if (secondHandle.has_value()) { - secondHandleInfo.isShow = CheckHandleVisible(secondHandle.value()); - } - if (!isSingleHandle_) { - selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(firstHandleInfo, secondHandleInfo); - } else { - selectOverlayProxy_->UpdateSecondSelectHandleInfo(secondHandleInfo); - } - } - UpdateScrollBarOffset(); -} - -void TextFieldPattern::OnTextInputScroll(float offset) -{ - if (IsTextArea() || textRect_.Width() <= contentRect_.Width()) { - return; - } - if (textRect_.GetX() + offset > contentRect_.GetX()) { - offset = contentRect_.GetX() - textRect_.GetX(); - } else if (textRect_.GetX() + textRect_.Width() + offset < contentRect_.GetX() + contentRect_.Width()) { - offset = contentRect_.GetX() + contentRect_.Width() - textRect_.GetX() - textRect_.Width(); - } - caretRect_.SetLeft(caretRect_.GetX() + offset); - currentOffset_ = textRect_.GetX() + offset; - textRect_.SetOffset(OffsetF(currentOffset_, textRect_.GetY())); - if (SelectOverlayIsOn()) { - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - textSelector_.secondHandleOffset_.SetX(textSelector_.secondHandleOffset_.GetX() + offset); - std::optional secondHandle = RectF(textSelector_.secondHandleOffset_, handlePaintSize); - std::optional firstHandle; - if (!isSingleHandle_) { - textSelector_.firstHandleOffset_.SetX(textSelector_.firstHandleOffset_.GetX() + offset); - firstHandle = { textSelector_.firstHandleOffset_, handlePaintSize }; - } - SelectHandleInfo firstHandleInfo; - SelectHandleInfo secondHandleInfo; - firstHandleInfo.paintRect = - RectF(firstHandle->Left(), firstHandle->Top(), firstHandle->Width(), firstHandle->Height()); - secondHandleInfo.paintRect = - RectF(secondHandle->Left(), secondHandle->Top(), secondHandle->Width(), secondHandle->Height()); - CheckHandles(firstHandle, secondHandle); - if (!firstHandle.has_value()) { - firstHandleInfo.isShow = false; - } - if (!secondHandle.has_value()) { - secondHandleInfo.isShow = false; - } - if (!isSingleHandle_) { - selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(firstHandleInfo, secondHandleInfo); - } else { - selectOverlayProxy_->UpdateSecondSelectHandleInfo(secondHandleInfo); - } - } - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); -} - -#ifndef USE_GRAPHIC_TEXT_GINE -void TextFieldPattern::GetTextRectsInRange( - int32_t base, int32_t destination, std::vector& textBoxes) -#else -void TextFieldPattern::GetTextRectsInRange(int32_t base, int32_t destination, std::vector& textBoxes) -#endif -{ - SwapIfLarger(base, destination); - if (!paragraph_) { - return; - } - -#ifndef USE_GRAPHIC_TEXT_GINE - textBoxes = paragraph_->GetRectsForRange( - base, destination, RSTypographyProperties::RectHeightStyle::MAX, RSTypographyProperties::RectWidthStyle::TIGHT); -#else - textBoxes = paragraph_->GetTextRectsByBoundary( - base, destination, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - if (textBoxes.size() == 1 && caretUpdateType_ == CaretUpdateType::LONG_PRESSED) { - Offset offset = GetLastTouchOffset() - Offset(textRect_.GetX(), textRect_.GetY()); -#ifndef USE_GRAPHIC_TEXT_GINE - if (offset.GetX() < textBoxes[0].rect_.GetLeft() || offset.GetY() < textBoxes[0].rect_.GetTop()) { - int32_t start = 0; - int32_t end = 0; - GetWordBoundaryPositon(base - 1, start, end); - auto tmp = paragraph_->GetRectsForRange(start, end, RSTypographyProperties::RectHeightStyle::MAX, - RSTypographyProperties::RectWidthStyle::TIGHT); -#else - if (offset.GetX() < textBoxes[0].rect.GetLeft() || offset.GetY() < textBoxes[0].rect.GetTop()) { - int32_t start = 0; - int32_t end = 0; - GetWordBoundaryPositon(base - 1, start, end); - auto tmp = paragraph_->GetTextRectsByBoundary( - start, end, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - if (tmp.size() != 1) { - return; - } - if (LastTouchIsInSelectRegion(tmp)) { - textBoxes = tmp; -#ifndef USE_GRAPHIC_TEXT_GINE - textSelector_.Update(start, end); - if (textEditingValue_.caretPosition != end) { - textEditingValue_.caretPosition = end; - } -#else - UpdateSelectorByPosition(base - 1); -#endif - } - } - } -} - -bool TextFieldPattern::ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result) -{ - CHECK_NULL_RETURN(paragraph_, false); - auto wideText = textEditingValue_.GetWideText(); - if (!IsTextArea() && static_cast(extent) >= wideText.length()) { - return false; - } - - result.Reset(); - const int32_t graphemeClusterLength = 1; - const int32_t next = extent + graphemeClusterLength; -#ifndef USE_GRAPHIC_TEXT_GINE - auto textBoxes = paragraph_->GetRectsForRange( - extent, next, RSTypographyProperties::RectHeightStyle::MAX, RSTypographyProperties::RectWidthStyle::TIGHT); -#else - auto textBoxes = paragraph_->GetTextRectsByBoundary( - extent, next, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - - if (textBoxes.empty()) { - LOGD("Box empty"); - return false; - } - - const auto& textBox = *textBoxes.begin(); - auto lastStringBeforeCursor = wideText.substr( - std::clamp(textEditingValue_.caretPosition - 1, 0, static_cast(wideText.length()) - 1), 1); - // Caret is within width of the downstream glyphs. - if (lastStringBeforeCursor == WIDE_NEWLINE && - (caretUpdateType_ == CaretUpdateType::INPUT || caretUpdateType_ == CaretUpdateType::DEL)) { - result.offset.SetX(MakeEmptyOffset().GetX()); -#ifndef USE_GRAPHIC_TEXT_GINE - result.offset.SetY(textBox.rect_.GetTop()); - result.height = textBox.rect_.GetHeight(); -#else - result.offset.SetY(textBox.rect.GetTop()); - result.height = textBox.rect.GetHeight(); -#endif - return true; + textRect_.SetOffset(OffsetF(textRect_.GetX(), currentOffset_)); + if (SelectOverlayIsOn()) { + selectController_->UpdateSecondHandleOffset(); + if (!IsSingleHandle()) { + selectController_->UpdateFirstHandleOffset(); + UpdateDoubleHandlePosition(); + } else { + UpdateSecondHandlePosition(); + selectController_->UpdateCaretOffset(); + } + } else { + selectController_->UpdateCaretOffset(); } - - // Caret is within width of the downstream glyphs. -#ifndef USE_GRAPHIC_TEXT_GINE - float offsetX = textBox.rect_.GetLeft(); -#else - float offsetX = textBox.rect.GetLeft(); -#endif - result.offset.SetX(offsetX); -#ifndef USE_GRAPHIC_TEXT_GINE - result.offset.SetY(textBox.rect_.GetTop()); - result.height = textBox.rect_.GetHeight(); -#else - result.offset.SetY(textBox.rect.GetTop()); - result.height = textBox.rect.GetHeight(); -#endif - return true; + UpdateScrollBarOffset(); } -bool TextFieldPattern::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result) const +void TextFieldPattern::OnTextInputScroll(float offset) { - auto text = textEditingValue_.text; - auto wideText = textEditingValue_.GetWideText(); - if (!paragraph_ || wideText.empty() || textEditingValue_.caretPosition == 0 || - textEditingValue_.caretPosition > static_cast(wideText.length())) { - return false; + if (IsTextArea() || textRect_.Width() <= contentRect_.Width()) { + return; } - - char16_t prevChar = 0; - if (static_cast(extent) <= textEditingValue_.GetWideText().length()) { - prevChar = text[std::max(0, extent - 1)]; + if (textRect_.GetX() + offset > contentRect_.GetX()) { + offset = contentRect_.GetX() - textRect_.GetX(); + } else if (textRect_.GetX() + textRect_.Width() + offset < contentRect_.GetX() + contentRect_.Width()) { + offset = contentRect_.GetX() + contentRect_.Width() - textRect_.GetX() - textRect_.Width(); } - - result.Reset(); - int32_t graphemeClusterLength = StringUtils::NotInUtf16Bmp(prevChar) ? 2 : 1; - int32_t prev = extent - graphemeClusterLength; -#ifndef USE_GRAPHIC_TEXT_GINE - auto boxes = paragraph_->GetRectsForRange( - prev, extent, RSTypographyProperties::RectHeightStyle::MAX, RSTypographyProperties::RectWidthStyle::TIGHT); -#else - auto boxes = paragraph_->GetTextRectsByBoundary( - prev, extent, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - while (boxes.empty() && !textEditingValue_.text.empty()) { - graphemeClusterLength *= 2; - prev = extent - graphemeClusterLength; - if (prev < 0) { -#ifndef USE_GRAPHIC_TEXT_GINE - boxes = paragraph_->GetRectsForRange( - 0, extent, RSTypographyProperties::RectHeightStyle::MAX, RSTypographyProperties::RectWidthStyle::TIGHT); -#else - boxes = paragraph_->GetTextRectsByBoundary( - 0, extent, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - break; + currentOffset_ = textRect_.GetX() + offset; + textRect_.SetOffset(OffsetF(currentOffset_, textRect_.GetY())); + if (SelectOverlayIsOn()) { + selectController_->UpdateSecondHandleOffset(); + if (!IsSingleHandle()) { + selectController_->UpdateFirstHandleOffset(); + UpdateDoubleHandlePosition(); + } else { + UpdateSecondHandlePosition(); } -#ifndef USE_GRAPHIC_TEXT_GINE - boxes = paragraph_->GetRectsForRange( - prev, extent, RSTypographyProperties::RectHeightStyle::MAX, RSTypographyProperties::RectWidthStyle::TIGHT); -#else - boxes = paragraph_->GetTextRectsByBoundary( - prev, extent, RSTextRectHeightStyle::COVER_TOP_AND_BOTTOM, RSTextRectWidthStyle::TIGHT); -#endif - } - if (boxes.empty()) { - LOGD("Empty box"); - return false; - } - - const auto& textBox = *boxes.begin(); - auto caretPosition = textEditingValue_.caretPosition; - auto maxPos = static_cast(wideText.length()) - 1; - auto lastStringBeforeCursor = wideText.substr(std::clamp(caretPosition - 1, 0, maxPos), 1); - // Caret is within width of the downstream glyphs. - if (lastStringBeforeCursor == WIDE_NEWLINE && - (caretUpdateType_ == CaretUpdateType::INPUT || caretUpdateType_ == CaretUpdateType::DEL)) { - result.offset.SetX(MakeEmptyOffset().GetX()); -#ifndef USE_GRAPHIC_TEXT_GINE - result.offset.SetY(textBox.rect_.GetBottom()); - result.height = textBox.rect_.GetHeight(); -#else - result.offset.SetY(textBox.rect.GetBottom()); - result.height = textBox.rect.GetHeight(); -#endif - return true; + } else { + selectController_->UpdateCaretOffset(); } -#ifndef USE_GRAPHIC_TEXT_GINE - result.offset.SetX(textBox.rect_.GetRight()); - result.offset.SetY(textBox.rect_.GetTop()); - result.height = textBox.rect_.GetHeight(); -#else - result.offset.SetX(textBox.rect.GetRight()); - result.offset.SetY(textBox.rect.GetTop()); - result.height = textBox.rect.GetHeight(); -#endif - return true; -} - -OffsetF TextFieldPattern::MakeEmptyOffset() const -{ auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, {}); - auto layoutProperty = tmpHost->GetLayoutProperty(); - CHECK_NULL_RETURN(layoutProperty, {}); - switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { - case TextAlign::CENTER: - return OffsetF(contentRect_.Width() * 0.5f, 0.0f); - case TextAlign::END: - return OffsetF(contentRect_.Width(), 0.0f); - case TextAlign::START: - default: - return {}; - } + CHECK_NULL_VOID(tmpHost); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } int32_t TextFieldPattern::ConvertTouchOffsetToCaretPosition(const Offset& localOffset) { CHECK_NULL_RETURN(paragraph_, 0); -#ifndef USE_GRAPHIC_TEXT_GINE - return static_cast(paragraph_->GetGlyphPositionAtCoordinate(localOffset.GetX(), localOffset.GetY()).pos_); -#else - return static_cast(paragraph_->GetGlyphIndexByCoordinate(localOffset.GetX(), localOffset.GetY()).index); -#endif + return paragraph_->GetGlyphIndexByCoordinate(localOffset); } -void TextFieldPattern::GetWordBoundaryPositon(int32_t offset, int32_t& start, int32_t& end) +int32_t TextFieldPattern::ConvertTouchOffsetToCaretPositionNG(const Offset& localOffset) { -#ifndef USE_GRAPHIC_TEXT_GINE - CHECK_NULL_VOID(paragraph_); - auto positon = paragraph_->GetWordBoundary(offset); - start = static_cast(positon.start_); - end = static_cast(positon.end_); -#else - CHECK_NULL_VOID(paragraph_); - auto positon = paragraph_->GetWordBoundaryByIndex(offset); - start = static_cast(positon.leftIndex); - end = static_cast(positon.rightIndex); -#endif + CHECK_NULL_RETURN(paragraph_, 0); + auto offset = localOffset - Offset(textRect_.GetX(), textRect_.GetY()); + return paragraph_->GetGlyphIndexByCoordinate(offset); } bool TextFieldPattern::DisplayPlaceHolder() @@ -1362,16 +593,12 @@ void TextFieldPattern::HandleFocusEvent() CHECK_NULL_VOID(context); auto globalOffset = host->GetPaintRectOffset() - context->GetRootRect().GetOffset(); UpdateTextFieldManager(Offset(globalOffset.GetX(), globalOffset.GetY()), frameRect_.Height()); - if (caretUpdateType_ != CaretUpdateType::PRESSED) { - caretUpdateType_ = CaretUpdateType::EVENT; - needToRequestKeyboardInner_ = !(dragRecipientStatus_ == DragStatus::DRAGGING); - } + needToRequestKeyboardInner_ = !(dragRecipientStatus_ == DragStatus::DRAGGING); auto paintProperty = GetPaintProperty(); CHECK_NULL_VOID(paintProperty); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (IsNormalInlineState() && - (!textEditingValue_.GetWideText().empty() || !layoutProperty->GetPlaceholderValue("").empty())) { + if (IsNormalInlineState() && (!contentController_->IsEmpty() || !layoutProperty->GetPlaceholderValue("").empty())) { ApplyInlineStates(true); inlineSelectAllFlag_ = true; inlineFocusState_ = true; @@ -1382,7 +609,6 @@ void TextFieldPattern::HandleFocusEvent() auto eventHub = host->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireOnEditChanged(true); - CloseSelectOverlay(); auto visible = layoutProperty->GetShowErrorTextValue(false); if (!visible && layoutProperty->GetShowUnderlineValue(false) && IsUnspecifiedOrTextType()) { auto renderContext = host->GetRenderContext(); @@ -1401,21 +627,14 @@ void TextFieldPattern::HandleFocusEvent() void TextFieldPattern::HandleSetSelection(int32_t start, int32_t end, bool showHandle) { + // todo LOGI("HandleSetSelection %{public}d, %{public}d", start, end); CloseSelectOverlay(); + StopTwinkling(); UpdateSelection(start, end); - textEditingValue_.caretPosition = - std::clamp(end, 0, static_cast(textEditingValue_.GetWideText().length())); - selectionMode_ = start == end ? SelectionMode::NONE : SelectionMode::SELECT; - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); AdjustTextSelectionRectOffsetX(); - UpdateCaretRectByPosition(textEditingValue_.caretPosition); if (showHandle) { - if (start == end) { - CreateSingleHandle(); - } else { - CreateHandles(); - } + ProcessOverlay(); } UpdateCaretInfoToController(); auto tmpHost = GetHost(); @@ -1429,14 +648,9 @@ void TextFieldPattern::AdjustTextSelectionRectOffsetX() return; } auto contentLeftBoundary = contentRect_.GetX(); - auto contentRightBoundary = contentRect_.GetX() + contentRect_.GetSize().Width() - unitWidth_; -#ifndef USE_GRAPHIC_TEXT_GINE - auto selectionStart = textBoxes_.begin()->rect_.GetLeft() + textRect_.GetX(); - auto selectionEnd = textBoxes_.begin()->rect_.GetRight() + textRect_.GetX(); -#else - auto selectionStart = textBoxes_.begin()->rect.GetLeft() + textRect_.GetX(); - auto selectionEnd = textBoxes_.begin()->rect.GetRight() + textRect_.GetX(); -#endif + auto contentRightBoundary = contentRect_.GetX() + contentRect_.GetSize().Width(); + auto selectionStart = textBoxes_.begin()->Left() + textRect_.GetX(); + auto selectionEnd = textBoxes_.begin()->Right() + textRect_.GetX(); float dx = 0.0f; if (selectionEnd < contentLeftBoundary) { @@ -1483,9 +697,8 @@ void TextFieldPattern::HandleExtendAction(int32_t action) void TextFieldPattern::HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) { - LOGI("HandleSelect, current caret position %{public}d", textEditingValue_.caretPosition); + LOGI("HandleSelect, current caret position %{public}d", selectController_->GetCaretIndex()); KeyCode code = static_cast(keyCode); - caretUpdateType_ = CaretUpdateType::EVENT; switch (code) { case KeyCode::KEY_DPAD_LEFT: { HandleSelectionLeft(); @@ -1576,9 +789,7 @@ void TextFieldPattern::HandleBlurEvent() isFocusedBeforeClick_ = false; StopTwinkling(); CloseKeyboard(true); - MarkRedrawOverlay(); - textSelector_.Update(-1); - selectionMode_ = SelectionMode::NONE; + selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); auto eventHub = host->GetEventHub(); eventHub->FireOnEditChanged(false); CloseSelectOverlay(true); @@ -1587,7 +798,6 @@ void TextFieldPattern::HandleBlurEvent() bool TextFieldPattern::OnKeyEvent(const KeyEvent& event) { - caretUpdateType_ = CaretUpdateType::EVENT; CloseSelectOverlay(true); auto context = PipelineContext::GetCurrentContext(); auto textFieldManager = DynamicCast(context->GetTextFieldManager()); @@ -1616,15 +826,16 @@ void TextFieldPattern::HandleOnUndoAction() ClearEditingValue(); return; } - textEditingValue_ = operationRecords_.back(); - SetEditingValueToProperty(textEditingValue_.text); + auto textEditingValue = operationRecords_.back(); // record应该包含光标、select状态、文本 + contentController_->SetTextValue(textEditingValue.text); + selectController_->UpdateCaretIndex(textEditingValue.caretPosition); + FireOnTextChangeEvent(); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); - FireEventHubOnChange(GetEditingValue().text); + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::HandleOnRedoAction() @@ -1634,49 +845,52 @@ void TextFieldPattern::HandleOnRedoAction() LOGW("Redo operation records empty, cannot undo"); return; } - textEditingValue_ = redoOperationRecords_.back(); + auto textEditingValue = redoOperationRecords_.back(); + contentController_->SetTextValue(textEditingValue.text); + selectController_->UpdateCaretIndex(textEditingValue.caretPosition); redoOperationRecords_.pop_back(); - operationRecords_.push_back(textEditingValue_); - SetEditingValueToProperty(textEditingValue_.text); + operationRecords_.push_back(textEditingValue); + FireOnTextChangeEvent(); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); - FireEventHubOnChange(GetEditingValue().text); + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) { LOGI("TextFieldPattern::HandleOnSelectAll"); - auto textSize = static_cast(GetEditingValue().GetWideText().length()); - if (inlineStyle == true) { - if (GetEditingValue().GetWideText().rfind(L".") < textSize - FIND_TEXT_ZERO_INDEX) { - textSize = GetEditingValue().GetWideText().rfind(L"."); + auto textSize = static_cast(contentController_->GetWideText().length()); + if (inlineStyle) { + if (contentController_->GetWideText().rfind(L".") < textSize - FIND_TEXT_ZERO_INDEX) { + textSize = contentController_->GetWideText().rfind(L"."); } UpdateSelection(0, textSize); } else { UpdateSelection(0, textSize); } + if (selectController_->IsSelected()) { + isSingleHandle_ = false; + } updateSelectionAfterObscure_ = ResetObscureTickCountDown(); - textEditingValue_.caretPosition = textSize; - selectionMode_ = SelectionMode::SELECT_ALL; - caretUpdateType_ = CaretUpdateType::EVENT; - MarkRedrawOverlay(); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - isSingleHandle_ = textEditingValue_.text.empty(); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + // move text to end + if (IsTextArea() && GreatOrEqual(textRect_.Height(), contentRect_.Height())) { + auto offsetY = textRect_.GetY() + textRect_.Height() - contentRect_.GetY() - contentRect_.Height(); + textRect_.SetTop(textRect_.GetY() - offsetY); + } else if (GreatOrEqual(textRect_.Width(), contentRect_.Width())) { + auto offsetX = textRect_.GetX() + textRect_.Width() - contentRect_.GetX() - contentRect_.Width(); + textRect_.SetLeft(textRect_.GetX() - offsetX); + } + selectController_->MoveSecondHandleToContentRect(textSize); CloseSelectOverlay(true); + StopTwinkling(); if (isKeyEvent || inlineSelectAllFlag_) { return; } - std::optional firstHandle = textSelector_.firstHandle; - std::optional secondHandle = textSelector_.secondHandle; - ShowSelectOverlay(firstHandle, secondHandle); + ProcessOverlay(true); } void TextFieldPattern::HandleOnCopy() @@ -1687,25 +901,23 @@ void TextFieldPattern::HandleOnCopy() CHECK_NULL_VOID(tmpHost); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - caretUpdateType_ = CaretUpdateType::NONE; if (layoutProperty->GetCopyOptionsValue(CopyOptions::Distributed) == CopyOptions::None) { LOGW("Copy option not allowed"); return; } + if (!IsSelected()) { + LOGW("Nothing to select"); + return; + } if (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD) { LOGW("Cannot copy in password mode"); - selectionMode_ = SelectionMode::NONE; - UpdateCaretPositionWithClamp(textSelector_.GetEnd()); - UpdateSelection(textEditingValue_.caretPosition); + UpdateSelection(selectController_->GetEndIndex()); StartTwinkling(); return; } - if (!IsSelected() || (textSelector_.IsValid() && textSelector_.GetStart() == textSelector_.GetEnd())) { - LOGW("Nothing to select"); - return; - } - LOGI("On copy, text selector %{public}s", textSelector_.ToString().c_str()); - auto value = GetEditingValue().GetSelectedText(textSelector_.GetStart(), textSelector_.GetEnd()); + LOGI("On copy, text selector %{public}s", selectController_->ToString().c_str()); + auto value = + contentController_->GetSelectedValue(selectController_->GetStartIndex(), selectController_->GetEndIndex()); if (value.empty()) { LOGW("Copy value is empty"); return; @@ -1715,21 +927,11 @@ void TextFieldPattern::HandleOnCopy() clipboard_->SetData(value, layoutProperty->GetCopyOptionsValue(CopyOptions::Distributed)); } - UpdateCaretPositionWithClamp(textSelector_.GetEnd()); - UpdateSelection(textEditingValue_.caretPosition); - UpdateCaretRectByPosition(textEditingValue_.caretPosition); - selectionMode_ = SelectionMode::NONE; + selectController_->UpdateCaretIndex(selectController_->GetSecondHandleIndex()); StartTwinkling(); - // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(tmpHost->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnCopy(value); - return; - } - - auto eventHub = tmpHost->GetEventHub(); + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto eventHub = host->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireOnCopy(value); } @@ -1737,7 +939,7 @@ void TextFieldPattern::HandleOnCopy() void TextFieldPattern::HandleOnPaste() { LOGI("TextFieldPattern::HandleOnPaste"); - auto pasteCallback = [weak = WeakClaim(this), textSelector = textSelector_](const std::string& data) { + auto pasteCallback = [weak = WeakClaim(this)](const std::string& data) { if (data.empty()) { LOGW("Paste value is empty"); return; @@ -1748,58 +950,27 @@ void TextFieldPattern::HandleOnPaste() CHECK_NULL_VOID(tmpHost); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - auto value = textfield->GetEditingValue(); - auto valueLength = textfield->GetEditingValue().GetWideText().length(); - int32_t start = 0; - int32_t end = 0; - if (textfield->IsSelected()) { - start = textSelector.GetStart(); - end = textSelector.GetEnd(); - SwapIfLarger(start, end); - } else { - start = value.caretPosition; - end = value.caretPosition; - } - std::string result; - std::string valueToUpdate(data); - textfield->EditingValueFilter(valueToUpdate, result, true); - LOGD("After filter paste value is %{private}s", result.c_str()); - std::wstring pasteData; - std::wstring wData = StringUtils::ToWstring(result); - textfield->StripNextLine(wData); - if (wData.length() + valueLength - (end - start) > textfield->GetMaxLength()) { - pasteData = wData.substr(0, textfield->GetMaxLength() - valueLength + (end - start)); - } else { - pasteData = wData; - } - value.text = - value.GetValueBeforePosition(start) + StringUtils::ToString(pasteData) + value.GetValueAfterPosition(end); + + auto start = textfield->selectController_->GetStartIndex(); + auto end = textfield->selectController_->GetEndIndex(); + + std::wstring pasteData = StringUtils::ToWstring(data); + textfield->StripNextLine(pasteData); + textfield->contentController_->ReplaceSelectedValue(start, end, StringUtils::ToString(pasteData)); auto newCaretPosition = std::clamp(std::min(start, end) + static_cast(pasteData.length()), 0, - static_cast(StringUtils::ToWstring(value.text).length())); + static_cast(textfield->contentController_->GetWideText().length())); textfield->ResetObscureTickCountDown(); - textfield->UpdateEditingValue(value.text, newCaretPosition); - textfield->UpdateSelection(newCaretPosition); - textfield->SetEditingValueToProperty(value.text); - textfield->SetInSelectMode(SelectionMode::NONE); - textfield->SetCaretUpdateType(CaretUpdateType::INPUT); + textfield->selectController_->UpdateCaretIndex(newCaretPosition); + textfield->FireOnTextChangeEvent(); textfield->UpdateEditingValueToRecord(); + if (textfield->IsTextArea() && layoutProperty->HasMaxLength()) { + textfield->HandleCounterBorder(); + } auto host = textfield->GetHost(); CHECK_NULL_VOID(host); - // If the parent node is a Search, the Search callback is executed. - if (textfield->IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnPaste(StringUtils::ToString(pasteData)); - textfield->FireEventHubOnChange(value.text); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - return; - } - - auto eventHub = tmpHost->GetEventHub(); + auto eventHub = textfield->GetHost()->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireOnPaste(StringUtils::ToString(pasteData)); - textfield->FireEventHubOnChange(value.text); host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF : PROPERTY_UPDATE_MEASURE); textfield->StartTwinkling(); @@ -1836,53 +1007,36 @@ void TextFieldPattern::HandleOnCut() CHECK_NULL_VOID(tmpHost); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - caretUpdateType_ = CaretUpdateType::NONE; + if (layoutProperty->GetCopyOptionsValue(CopyOptions::Distributed) == CopyOptions::None) { LOGW("Copy option not allowed"); return; } - auto start = textSelector_.GetStart(); - auto end = textSelector_.GetEnd(); + auto start = selectController_->GetStartIndex(); + auto end = selectController_->GetEndIndex(); SwapIfLarger(start, end); - if (!IsSelected() || (textSelector_.IsValid() && start == end)) { + if (!IsSelected()) { LOGW("HandleOnCut nothing Selected"); return; } - auto value = GetEditingValue(); - auto selectedText = value.GetSelectedText(start, end); + auto selectedText = contentController_->GetSelectedValue(start, end); if (layoutProperty->GetCopyOptionsValue(CopyOptions::Distributed) != CopyOptions::None) { LOGI("Cut value is %{private}s", selectedText.c_str()); clipboard_->SetData(selectedText, layoutProperty->GetCopyOptionsValue(CopyOptions::Distributed)); } - textEditingValue_.text = - textEditingValue_.GetValueBeforePosition(start) + textEditingValue_.GetValueAfterPosition(end); - textEditingValue_.CursorMoveToPosition(start); - SetEditingValueToProperty(textEditingValue_.text); - selectionMode_ = SelectionMode::NONE; + contentController_->erase(start, end - start); + UpdateSelection(start); + SetEditingValueToProperty(contentController_->GetTextValue()); CloseSelectOverlay(true); StartTwinkling(); UpdateEditingValueToRecord(); - UpdateSelection(textEditingValue_.caretPosition); - MarkRedrawOverlay(); - cursorVisible_ = true; auto host = GetHost(); CHECK_NULL_VOID(host); - // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnCut(selectedText); - FireEventHubOnChange(textEditingValue_.text); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - return; - } - auto eventHub = host->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireOnCut(selectedText); - FireEventHubOnChange(textEditingValue_.text); + FireEventHubOnChange(contentController_->GetTextValue()); host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF : PROPERTY_UPDATE_MEASURE); } @@ -1894,9 +1048,13 @@ void TextFieldPattern::UpdateSelection(int32_t both) void TextFieldPattern::UpdateSelection(int32_t start, int32_t end) { - if (start != textSelector_.GetStart() || end != textSelector_.GetEnd()) { - FireOnSelectionChange(start, end); - textSelector_.Update(start, end); + auto startIndex = std::min(start, end); + auto endIndex = std::max(start, end); + startIndex = std::clamp(startIndex, 0, static_cast(contentController_->GetWideText().length())); + endIndex = std::clamp(endIndex, 0, static_cast(contentController_->GetWideText().length())); + if (startIndex != selectController_->GetStartIndex() || endIndex != selectController_->GetEndIndex()) { + FireOnSelectionChange(startIndex, endIndex); + selectController_->UpdateHandleIndex(startIndex, endIndex); } } @@ -1917,14 +1075,6 @@ void TextFieldPattern::FireEventHubOnChange(const std::string& text) if (!layoutProperty->GetNeedFireOnChangeValue(false)) { return; } - // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->UpdateChangeEvent(text); - return; - } auto pipeline = PipelineBase::GetCurrentContext(); CHECK_NULL_VOID(pipeline); auto textFieldTheme = pipeline->GetTheme(); @@ -2011,6 +1161,24 @@ void TextFieldPattern::HandleTouchUp() } } +void TextFieldPattern::InitDragEvent() +{ +#ifdef ENABLE_DRAG_FRAMEWORK + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto layoutProperty = host->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + if (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) != TextInputType::VISIBLE_PASSWORD && + layoutProperty->GetCopyOptionsValue(CopyOptions::Local) != CopyOptions::None) { + InitDragDropEvent(); + AddDragFrameNodeToManager(host); + } else { + ClearDragDropEvent(); + RemoveDragFrameNodeFromManager(host); + } +#endif // ENABLE_DRAG_FRAMEWORK +} + #ifdef ENABLE_DRAG_FRAMEWORK std::function TextFieldPattern::GetThumbnailCallback() { @@ -2030,18 +1198,8 @@ std::function TextFieldPattern::GetThumbnailCallback() return callback; } -void TextFieldPattern::InitDragDropEvent() +std::function&, const std::string&)> TextFieldPattern::OnDragStart() { - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto gestureHub = host->GetOrCreateGestureEventHub(); - CHECK_NULL_VOID(gestureHub); - gestureHub->InitDragDropEvent(); - gestureHub->SetTextDraggable(true); - auto callback = GetThumbnailCallback(); - gestureHub->SetThumbnailCallback(std::move(callback)); - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); auto onDragStart = [weakPtr = WeakClaim(this)](const RefPtr& event, const std::string& extraParams) -> NG::DragDropInfo { NG::DragDropInfo itemInfo; @@ -2053,13 +1211,11 @@ void TextFieldPattern::InitDragDropEvent() CHECK_NULL_RETURN(layoutProperty, itemInfo); pattern->dragStatus_ = DragStatus::DRAGGING; pattern->textFieldContentModifier_->ChangeDragStatus(); - pattern->selectionMode_ = SelectionMode::NONE; - pattern->dragTextStart_ = std::min(pattern->textSelector_.GetStart(), pattern->textSelector_.GetEnd()); - pattern->dragTextEnd_ = std::max(pattern->textSelector_.GetStart(), pattern->textSelector_.GetEnd()); - auto textEditingValue = pattern->GetEditingValue(); - std::string beforeStr = textEditingValue.GetValueBeforePosition(pattern->dragTextStart_); - std::string selectedStr = textEditingValue.GetSelectedText(pattern->dragTextStart_, pattern->dragTextEnd_); - std::string afterStr = textEditingValue.GetValueAfterPosition(pattern->dragTextEnd_); + auto contentController = pattern->contentController_; + auto selectController = pattern->selectController_; + std::string beforeStr = contentController->GetValueBeforeIndex(selectController->GetStartIndex()); + std::string selectedStr = contentController->GetSelectedValue(selectController->GetStartIndex(), selectController->GetEndIndex()); + std::string afterStr = contentController->GetValueAfterIndex(selectController->GetEndIndex()); pattern->dragContents_ = { beforeStr, selectedStr, afterStr }; itemInfo.extraInfo = selectedStr; RefPtr unifiedData = UdmfClient::GetInstance()->CreateUnifiedData(); @@ -2069,8 +1225,76 @@ void TextFieldPattern::InitDragDropEvent() : PROPERTY_UPDATE_MEASURE); return itemInfo; }; + return onDragStart; +} + +std::function&, const std::string&)> TextFieldPattern::OnDragDrop() +{ + auto onDrop = [weakPtr = WeakClaim(this)]( + const RefPtr& event, const std::string& extraParams) { + auto pattern = weakPtr.Upgrade(); + CHECK_NULL_VOID(pattern); + auto host = pattern->GetHost(); + CHECK_NULL_VOID(host); + if (extraParams.empty()) { + pattern->dragStatus_ = DragStatus::ON_DROP; + pattern->textFieldContentModifier_->ChangeDragStatus(); + auto host = pattern->GetHost(); + CHECK_NULL_VOID(host); + auto layoutProperty = host->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF + : PROPERTY_UPDATE_MEASURE); + return; + } + auto data = event->GetData(); + CHECK_NULL_VOID(data); + auto records = UdmfClient::GetInstance()->GetPlainTextRecords(data); + std::string str; + for (const auto& record : records) { + str += record; + } + pattern->needToRequestKeyboardInner_ = true; + pattern->dragRecipientStatus_ = DragStatus::NONE; + if (str.empty()) { + return; + } + if (pattern->dragStatus_ == DragStatus::NONE) { + pattern->InsertValue(str); + } else { + auto current = pattern->selectController_->GetCaretIndex(); + auto dragTextStart = pattern->dragTextStart_; + auto dragTextEnd = pattern->dragTextEnd_; + if (current < dragTextStart) { + pattern->contentController_->erase(dragTextStart, dragTextEnd - dragTextStart); + pattern->InsertValue(str); + } else if (current > dragTextEnd) { + pattern->contentController_->erase(dragTextStart, dragTextEnd - dragTextStart); + pattern->selectController_->UpdateCaretIndex(current - (dragTextEnd - dragTextStart)); + pattern->InsertValue(str); + } + pattern->dragStatus_ = DragStatus::NONE; + pattern->MarkContentChange(); + host->MarkDirtyNode(pattern->IsTextArea() ? PROPERTY_UPDATE_MEASURE : PROPERTY_UPDATE_MEASURE_SELF); + } + }; + return onDrop; +} + +void TextFieldPattern::InitDragDropEvent() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto gestureHub = host->GetOrCreateGestureEventHub(); + CHECK_NULL_VOID(gestureHub); + gestureHub->InitDragDropEvent(); + gestureHub->SetTextDraggable(true); + auto callback = GetThumbnailCallback(); + gestureHub->SetThumbnailCallback(std::move(callback)); + auto eventHub = host->GetEventHub(); + CHECK_NULL_VOID(eventHub); if (!eventHub->HasOnDragStart()) { - eventHub->SetOnDragStart(std::move(onDragStart)); + eventHub->SetOnDragStart(OnDragStart()); } auto onDragEnter = [weakPtr = WeakClaim(this)]( @@ -2096,11 +1320,7 @@ void TextFieldPattern::InitDragDropEvent() auto position = pattern->ConvertTouchOffsetToCaretPosition(offset); auto host = pattern->GetHost(); CHECK_NULL_VOID(host); - auto focusHub = host->GetOrCreateFocusHub(); - if (pattern->IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); - } + auto focusHub = pattern->GetFocusHub(); focusHub->RequestFocusImmediately(); pattern->SetCaretPosition(position); pattern->StartTwinkling(); @@ -2135,57 +1355,7 @@ void TextFieldPattern::InitDragDropEvent() }; eventHub->SetOnDragEnd(std::move(onDragEnd)); - auto onDrop = [weakPtr = WeakClaim(this)]( - const RefPtr& event, const std::string& extraParams) { - auto pattern = weakPtr.Upgrade(); - CHECK_NULL_VOID(pattern); - auto host = pattern->GetHost(); - CHECK_NULL_VOID(host); - if (extraParams.empty()) { - pattern->dragStatus_ = DragStatus::ON_DROP; - pattern->textFieldContentModifier_->ChangeDragStatus(); - auto host = pattern->GetHost(); - CHECK_NULL_VOID(host); - auto layoutProperty = host->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); - return; - } - auto data = event->GetData(); - CHECK_NULL_VOID(data); - auto records = UdmfClient::GetInstance()->GetPlainTextRecords(data); - std::string str = ""; - for (const auto& record : records) { - str += record; - } - pattern->needToRequestKeyboardInner_ = true; - pattern->dragRecipientStatus_ = DragStatus::NONE; - if (str.empty()) { - return; - } - if (pattern->dragStatus_ == DragStatus::NONE) { - pattern->InsertValue(str); - } else { - auto current = pattern->textEditingValue_.caretPosition; - float dragTextStart = pattern->dragTextStart_; - float dragTextEnd = pattern->dragTextEnd_; - if (current < dragTextStart) { - pattern->textEditingValue_.text = pattern->textEditingValue_.GetValueBeforePosition(dragTextStart) + - pattern->textEditingValue_.GetValueAfterPosition(dragTextEnd); - pattern->InsertValue(str); - } else if (current > dragTextEnd) { - pattern->textEditingValue_.text = pattern->textEditingValue_.GetValueBeforePosition(dragTextStart) + - pattern->textEditingValue_.GetValueAfterPosition(dragTextEnd); - pattern->textEditingValue_.caretPosition = current - (dragTextEnd - dragTextStart); - pattern->InsertValue(str); - } - pattern->dragStatus_ = DragStatus::NONE; - pattern->MarkContentChange(); - host->MarkDirtyNode(pattern->IsTextArea() ? PROPERTY_UPDATE_MEASURE : PROPERTY_UPDATE_MEASURE_SELF); - } - }; - eventHub->SetOnDrop(std::move(onDrop)); + eventHub->SetOnDrop(OnDragDrop()); } void TextFieldPattern::ClearDragDropEvent() @@ -2217,6 +1387,7 @@ void TextFieldPattern::InitTouchEvent() auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) { auto pattern = weak.Upgrade(); CHECK_NULL_VOID(pattern); + pattern->isUsingMouse_ = false; pattern->HandleTouchEvent(info); }; touchListener_ = MakeRefPtr(std::move(touchTask)); @@ -2241,95 +1412,71 @@ void TextFieldPattern::InitClickEvent() void TextFieldPattern::HandleClickEvent(GestureEvent& info) { - LOGI("TextFieldPattern::HandleClickEvent"); - if (hasClicked_) { - hasClicked_ = false; - TimeStamp clickTimeStamp = info.GetTimeStamp(); - std::chrono::duration> timeout = - clickTimeStamp - lastClickTimeStamp_; - lastClickTimeStamp_ = info.GetTimeStamp(); - if (timeout.count() < DOUBLECLICK_INTERVAL_MS) { - lastTouchOffset_ = info.GetLocalLocation(); - HandleDoubleClickEvent(info); - } else { - HandleClickEvent(info); - } - } else { - hasClicked_ = true; - lastClickTimeStamp_ = info.GetTimeStamp(); - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(context); - auto globalOffset = host->GetPaintRectOffset() - context->GetRootRect().GetOffset(); - // emulate clicking bottom of the textField - UpdateTextFieldManager(Offset(globalOffset.GetX(), globalOffset.GetY()), frameRect_.Height()); - auto focusHub = host->GetOrCreateFocusHub(); - - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); - } + TimeStamp clickTimeStamp = info.GetTimeStamp(); + std::chrono::duration> timeout = clickTimeStamp - lastClickTimeStamp_; + lastClickTimeStamp_ = info.GetTimeStamp(); + isUsingMouse_ = false; + if (timeout.count() < DOUBLECLICK_INTERVAL_MS) { + HandleDoubleClickEvent(info); // 注册手势事件 + } else { + HandleSingleClickEvent(info); + } +} - if (!focusHub->IsFocusable()) { - LOGI("Textfield %{public}d is not focusable ,cannot request keyboard", host->GetId()); - return; - } - lastTouchOffset_ = info.GetLocalLocation(); - isTouchAtLeftOffset_ = IsTouchAtLeftOffset(lastTouchOffset_.GetX()); - caretUpdateType_ = CaretUpdateType::PRESSED; - isFocusedBeforeClick_ = HasFocus(); - selectionMode_ = SelectionMode::NONE; - isUsingMouse_ = false; - CloseSelectOverlay(true); - auto layoutProperty = GetLayoutProperty(); - if (lastTouchOffset_.GetX() > frameRect_.Width() - imageRect_.Width() - GetIconRightOffset() && - NeedShowPasswordIcon()) { - LOGI("Password Icon pressed, change text to be shown only"); - textObscured_ = !textObscured_; - ProcessPasswordIcon(); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - caretUpdateType_ = CaretUpdateType::ICON_PRESSED; - return; - } - ResetObscureTickCountDown(); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - StartTwinkling(); +void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) +{ + // emulate clicking bottom of the textField + UpdateTextFieldManager(Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()), frameRect_.Height()); + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto focusHub = GetFocusHub(); - if (isMousePressed_) { - LOGI("TextFieldPattern::HandleTouchUp of mouse"); - isMousePressed_ = false; - return; - } + if (!focusHub->IsFocusable()) { + LOGI("Textfield %{public}d is not focusable ,cannot request keyboard", host->GetId()); + return; + } + auto layoutProperty = GetLayoutProperty(); + CloseSelectOverlay(true); + ResetObscureTickCountDown(); + auto hasFocus = HasFocus(); + if (!hasFocus) { if (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately()) { LOGW("Request focus failed, cannot open input method"); StopTwinkling(); return; } - if (RequestKeyboard(false, true, true)) { - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); - } } + auto lastCaretIndex = selectController_->GetCaretIndex(); + selectController_->UpdateCaretInfoByOffset(info.GetLocalLocation()); + StartTwinkling(); + isSingleHandle_ = true; + if (lastCaretIndex == selectController_->GetCaretIndex() && hasFocus && caretStatus_ == CaretStatus::SHOW && + !isUsingMouse_ && !selectController_->IsSelected()) { + ProcessOverlay(true); + } + + if (RequestKeyboard(false, true, true)) { + auto eventHub = host->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->FireOnEditChanged(true); // 事件可能重复上报待整改 + } + host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } void TextFieldPattern::HandleDoubleClickEvent(GestureEvent& info) { - LOGI("TextFieldPattern::HandleDoubleClickEvent"); - isDoubleClick_ = true; - if (!GetEditingValue().text.empty()) { + selectController_->UpdateSelectByOffset(info.GetLocalLocation()); + if (selectController_->IsSelected()) { StopTwinkling(); - } - if (!IsUsingMouse()) { - caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK; isSingleHandle_ = false; - isUsingMouse_ = false; - CloseSelectOverlay(true); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } + if (!isUsingMouse_) { + CloseSelectOverlay(); + ProcessOverlay(true); + } + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } void TextFieldPattern::ScheduleCursorTwinkling() @@ -2367,9 +1514,8 @@ void TextFieldPattern::StartTwinkling() // Show cursor right now. cursorVisible_ = true; - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + caretStatus_ = CaretStatus::SHOW; + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); ScheduleCursorTwinkling(); } @@ -2378,16 +1524,12 @@ void TextFieldPattern::OnCursorTwinkling() cursorTwinklingTask_.Cancel(); cursorVisible_ = !cursorVisible_; auto shouldMeasure = !IsTextArea() && IsInPasswordMode() && GetTextObscured() && obscureTickCountDown_ == 1; - if (IsInPasswordMode() && GetTextObscured() && obscureTickCountDown_ > 0) { - --obscureTickCountDown_; - } - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); + auto host = GetHost(); + CHECK_NULL_VOID(host); if (shouldMeasure) { - caretUpdateType_ = CaretUpdateType::EVENT; - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } else { - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } ScheduleCursorTwinkling(); } @@ -2406,6 +1548,7 @@ void TextFieldPattern::StopTwinkling() if (ResetObscureTickCountDown()) { tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } + caretStatus_ = CaretStatus::HIDE; } void TextFieldPattern::CheckIfNeedToResetKeyboard() @@ -2478,7 +1621,12 @@ void TextFieldPattern::OnModifyDone() InitMouseEvent(); InitTouchEvent(); SetAccessibilityAction(); - FilterExistText(); + FilterInitializeText(); + FireOnTextChangeEvent(); + InitSelectOverlay(); + if (responseArea_) { + responseArea_->InitResponseArea(WeakClaim(this)); + } #ifdef ENABLE_DRAG_FRAMEWORK if (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) != TextInputType::VISIBLE_PASSWORD) { InitDragDropEvent(); @@ -2488,7 +1636,6 @@ void TextFieldPattern::OnModifyDone() RemoveDragFrameNodeFromManager(host); } #endif // ENABLE_DRAG_FRAMEWORK - ProcessPasswordIcon(); context->AddOnAreaChangeNode(host->GetId()); if (!clipboard_ && context) { clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(context->GetTaskExecutor()); @@ -2504,13 +1651,14 @@ void TextFieldPattern::OnModifyDone() if (renderContext->HasBackgroundColor()) { paintProperty->UpdateBackgroundColor(renderContext->GetBackgroundColorValue()); } - auto textWidth = static_cast(textEditingValue_.GetWideText().length()); + + auto textWidth = static_cast(contentController_->GetWideText().length()); if (SelectOverlayIsOn()) { needToRefreshSelectOverlay_ = true; - UpdateSelection( - std::clamp(textSelector_.GetStart(), 0, textWidth), std::clamp(textSelector_.GetEnd(), 0, textWidth)); - UpdateCaretPositionWithClamp(textSelector_.GetEnd()); - if (!textSelector_.StartEqualToDest()) { + UpdateSelection(std::clamp(selectController_->GetStartIndex(), 0, textWidth), + std::clamp(selectController_->GetEndIndex(), 0, textWidth)); + UpdateCaretPositionWithClamp(selectController_->GetEndIndex()); + if (IsSelected()) { selectionMode_ = SelectionMode::SELECT; } } @@ -2519,16 +1667,6 @@ void TextFieldPattern::OnModifyDone() operationRecords_.clear(); redoOperationRecords_.clear(); } - auto maxLength = GetMaxLength(); - if (GreatNotEqual(textWidth, maxLength)) { - textEditingValue_.text = StringUtils::ToString(textEditingValue_.GetWideText().substr(0, maxLength)); - UpdateCaretPositionWithClamp(textEditingValue_.caretPosition); - SetEditingValueToProperty(textEditingValue_.text); - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - layoutProperty->UpdateNeedFireOnChange(true); - } - FireOnChangeIfNeeded(); if (IsTextArea() || IsNormalInlineState()) { SetAxis(Axis::VERTICAL); if (!GetScrollableEvent()) { @@ -2552,7 +1690,6 @@ void TextFieldPattern::OnModifyDone() if (textFieldOverlayModifier_) { textFieldOverlayModifier_->SetScrollBar(scrollBar); UpdateScrollBarOffset(); - MarkRedrawOverlay(); } } else { SetAxis(Axis::HORIZONTAL); @@ -2619,37 +1756,39 @@ void TextFieldPattern::CalculateDefaultCursor() float caretWidth = paintProperty->GetCursorWidth().has_value() ? static_cast(paintProperty->GetCursorWidthValue().ConvertToPx()) : static_cast(CURSOR_WIDTH.ConvertToPx()); - caretRect_.SetWidth(caretWidth); - if (textEditingValue_.caretPosition != 0) { + selectController_->UpdateCaretWidth(caretWidth); + if (!contentController_->IsEmpty()) { return; } - caretRect_.SetLeft(GetPaddingLeft()); - caretRect_.SetTop(GetPaddingTop()); - caretRect_.SetHeight(PreferredLineHeight()); - CHECK_NULL_VOID(layoutProperty->GetCalcLayoutConstraint()); - CHECK_NULL_VOID(layoutProperty->GetCalcLayoutConstraint()->selfIdealSize.has_value()); - CHECK_NULL_VOID(layoutProperty->GetCalcLayoutConstraint()->selfIdealSize.value().Height().has_value()); - auto alignment = layoutProperty->GetPositionProperty() - ? layoutProperty->GetPositionProperty()->GetAlignment().value_or(Alignment::CENTER) - : Alignment::CENTER; - auto idealHeight = layoutProperty->GetCalcLayoutConstraint()->selfIdealSize.value().Height().value(); - caretRect_.SetTop( - (1.0 + alignment.GetVertical()) * (idealHeight.GetDimension().ConvertToPx() - PreferredLineHeight()) / 2.0); + selectController_->UpdateCaretHeight(PreferredLineHeight()); } -void TextFieldPattern::FireOnChangeIfNeeded() +void TextFieldPattern::FireOnTextChangeEvent() { - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto eventHub = host->GetEventHub(); + CHECK_NULL_VOID(eventHub); + auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (!layoutProperty->GetNeedFireOnChangeValue(false)) { - return; + + auto textCache = layoutProperty->GetValueValue(""); + if (textCache != contentController_->GetTextValue()) { + layoutProperty->UpdateValue(contentController_->GetTextValue()); + host->OnAccessibilityEvent(AccessibilityEventType::TEXT_CHANGE, textCache, contentController_->GetTextValue()); + eventHub->FireOnChange(contentController_->GetTextValue()); + } +} + +void TextFieldPattern::FilterInitializeText() +{ + auto layoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto inputFilter = layoutProperty->GetInputFilter(); + auto inputType = layoutProperty->GetTextInputType(); + if ((inputFilter.has_value() || inputType.has_value()) && !contentController_->IsEmpty()) { + contentController_->FilterValue(); } - layoutProperty->UpdateNeedFireOnChange(false); - auto eventHub = tmpHost->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnChange(textEditingValue_.text); } bool TextFieldPattern::IsDisabled() @@ -2728,26 +1867,20 @@ void TextFieldPattern::InitLongPressEvent() auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) { auto pattern = weak.Upgrade(); CHECK_NULL_VOID(pattern); + pattern->isUsingMouse_ = false; pattern->HandleLongPress(info); }; longPressEvent_ = MakeRefPtr(std::move(longPressCallback)); gesture->SetLongPressEvent(longPressEvent_); - - auto onTextSelectorChange = [weak = WeakClaim(this)]() { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - auto frameNode = pattern->GetHost(); - CHECK_NULL_VOID(frameNode); - frameNode->OnAccessibilityEvent(AccessibilityEventType::TEXT_SELECTION_UPDATE); - }; - textSelector_.SetOnAccessibility(std::move(onTextSelectorChange)); } void TextFieldPattern::HandleLongPress(GestureEvent& info) { + if (isUsingMouse_) { + return; + } auto host = GetHost(); CHECK_NULL_VOID(host); - lastTouchOffset_ = info.GetLocalLocation(); auto hub = host->GetEventHub(); CHECK_NULL_VOID(hub); auto gestureHub = hub->GetOrCreateGestureEventHub(); @@ -2761,267 +1894,158 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) #ifdef ENABLE_DRAG_FRAMEWORK gestureHub->SetIsTextDraggable(false); #endif - caretUpdateType_ = (isMousePressed_ || !HasFocus()) ? CaretUpdateType::PRESSED : CaretUpdateType::LONG_PRESSED; - isSingleHandle_ = false; - isUsingMouse_ = false; ResetObscureTickCountDown(); - LOGI("TextField %{public}d handle long press", host->GetId()); - auto focusHub = host->GetOrCreateFocusHub(); - CloseSelectOverlay(true); - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); - } + isUsingMouse_ = false; + auto focusHub = GetFocusHub(); if (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately()) { - LOGE("Long press request focus failed"); - StopTwinkling(); return; } - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); -} - -void TextFieldPattern::UpdateSelectorByPosition(const int32_t& pos) -{ - CHECK_NULL_VOID(paragraph_); - int32_t start = 0; - int32_t end = 0; - GetWordBoundaryPositon(pos, start, end); - textSelector_.Update(start, end); -} - -int32_t TextFieldPattern::GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev) -{ - char16_t aroundChar = 0; - if (checkPrev) { - if (static_cast(extend) <= text.length()) { - aroundChar = text[std::max(0, extend - 1)]; - } - } else { - if (static_cast(extend) <= (text.length())) { - aroundChar = text[std::min(static_cast(text.length() - 1), extend)]; - } + selectController_->UpdateSelectByOffset(info.GetLocalLocation()); + if (IsSelected()) { + StopTwinkling(); + isSingleHandle_ = false; } - return StringUtils::NotInUtf16Bmp(aroundChar) ? 2 : 1; + ProcessOverlay(true); + host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } void TextFieldPattern::UpdateCaretPositionWithClamp(const int32_t& pos) { - textEditingValue_.caretPosition = - std::clamp(pos, 0, static_cast(GetEditingValue().GetWideText().length())); + selectController_->UpdateCaretIndex( + std::clamp(pos, 0, static_cast(contentController_->GetWideText().length()))); } -void TextFieldPattern::ProcessOverlay(bool animation) +void TextFieldPattern::ProcessOverlay(bool animation, bool isShowMenu) { - if (caretUpdateType_ != CaretUpdateType::RIGHT_CLICK) { - StopTwinkling(); - } - if (textEditingValue_.text.empty()) { - CreateSingleHandle(animation); - return; - } - if (caretUpdateType_ == CaretUpdateType::LONG_PRESSED || caretUpdateType_ == CaretUpdateType::DOUBLE_CLICK) { - // When the content length is 1, you need to use the TextBox and pressing coordinates to determine whether it is - // selected - if (textEditingValue_.text.length() == 1) { -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector box; -#else - std::vector box; -#endif - GetTextRectsInRange(0, 1, box); - if (LastTouchIsInSelectRegion(box)) { - UpdateSelection(0, 1); - textEditingValue_.CursorMoveToPosition(1); - CreateHandles(animation); - return; - } - } - if (textEditingValue_.caretPosition == 0 && GetLastTouchOffset().GetX() < textRect_.GetX()) { - UpdateSelection(0); - CreateSingleHandle(animation); - return; - } else if (textEditingValue_.CaretAtLast() && GetLastTouchOffset().GetX() > textRect_.GetX()) { - UpdateSelection(textEditingValue_.caretPosition); - CreateSingleHandle(animation); - return; - } else { - UpdateSelectorByPosition(textEditingValue_.caretPosition); - } - if (!textSelector_.StartEqualToDest()) { - FireOnSelectionChange(textSelector_.GetStart(), textSelector_.GetEnd()); - selectionMode_ = SelectionMode::SELECT; - } + selectController_->CalculateHandleOffset(); + if (isSingleHandle_) { + StartTwinkling(); + LOGD("Show single handle Handle info %{public}s", selectController_->GetSecondHandleRect().ToString().c_str()); + ShowSelectOverlay(std::nullopt, selectController_->GetSecondHandleRect(), animation, isShowMenu); + } else { + LOGD("Show handles firstHandle info %{public}s, secondHandle Info %{public}s", + selectController_->GetFirstHandleRect().ToString().c_str(), + selectController_->GetSecondHandleRect().ToString().c_str()); + ShowSelectOverlay( + selectController_->GetFirstHandleRect(), selectController_->GetSecondHandleRect(), animation, isShowMenu); } - CreateHandles(animation); -} - -void TextFieldPattern::CreateHandles() -{ - CreateHandles(false); -} - -void TextFieldPattern::CreateHandles(bool animation) -{ -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector tmp; -#else - std::vector tmp; -#endif - MarkRedrawOverlay(); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), tmp); - auto firstHandlePosition = CalcCursorOffsetByPosition(textSelector_.GetStart()); - OffsetF firstHandleOffset(firstHandlePosition.offset.GetX() + parentGlobalOffset_.GetX(), - firstHandlePosition.offset.GetY() + parentGlobalOffset_.GetY()); - textSelector_.firstHandleOffset_ = firstHandleOffset; - auto secondHandlePosition = CalcCursorOffsetByPosition(textSelector_.GetEnd(), false); - OffsetF secondHandleOffset(secondHandlePosition.offset.GetX() + parentGlobalOffset_.GetX(), - secondHandlePosition.offset.GetY() + parentGlobalOffset_.GetY()); - textSelector_.secondHandleOffset_ = secondHandleOffset; - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - std::optional firstHandle = RectF(firstHandleOffset, handlePaintSize); - std::optional secondHandle = RectF(secondHandleOffset, handlePaintSize); - LOGD("First handle %{public}s, second handle %{public}s", firstHandle->ToString().c_str(), - secondHandle->ToString().c_str()); - CheckHandles(firstHandle, secondHandle); - ShowSelectOverlay(firstHandle, secondHandle, animation); - textBoxes_ = tmp; } void TextFieldPattern::ShowSelectOverlay( const std::optional& firstHandle, const std::optional& secondHandle, bool animation, bool isMenuShow) { - CloseSelectOverlay(); if (isTransparent_) { return; } - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(pipeline); - auto hasDataCallback = [weak = WeakClaim(this), pipeline, firstHandle, secondHandle, animation, isMenuShow]( - bool hasData) { + auto hasDataCallback = [weak = WeakClaim(this), firstHandle, secondHandle, animation, isMenuShow](bool hasData) { LOGI("HasData callback from clipboard, data available ? %{public}d", hasData); auto pattern = weak.Upgrade(); - SelectOverlayInfo selectInfo; - if (!pattern->IsUsingMouse()) { - if (firstHandle.has_value()) { - selectInfo.firstHandle.paintRect = firstHandle.value(); - } else { - selectInfo.firstHandle.isShow = false; - } - if (secondHandle.has_value()) { - selectInfo.secondHandle.paintRect = secondHandle.value(); - } else { - selectInfo.secondHandle.isShow = false; - } - } + CHECK_NULL_VOID(pattern); + ClientOverlayInfo overlayInfo = { .animation = animation, .isMenuShow = isMenuShow }; if (firstHandle.has_value()) { - selectInfo.firstHandle.isShow = pattern->CheckHandleVisible(firstHandle.value()); + auto handle = firstHandle.value(); + handle.SetOffset(handle.GetOffset() + pattern->GetTextPaintOffset()); + SelectHandleInfo firstHandleInfo; + firstHandleInfo.paintRect = handle; + overlayInfo.firstHandleInfo = firstHandleInfo; } if (secondHandle.has_value()) { - selectInfo.secondHandle.isShow = pattern->CheckHandleVisible(secondHandle.value()); - } - selectInfo.isSingleHandle = !firstHandle.has_value() || !secondHandle.has_value(); - if (selectInfo.isSingleHandle && pattern->IsTextArea() && - pattern->GetSelectMode() == SelectionMode::SELECT_ALL) { - auto contentRect = pattern->GetContentRect(); - auto parentGlobalOffset = pattern->GetParentGlobalOffset(); - selectInfo.menuInfo.menuOffset = + auto handle = secondHandle.value(); + handle.SetOffset(handle.GetOffset() + pattern->GetTextPaintOffset()); + SelectHandleInfo secondHandleInfo; + secondHandleInfo.paintRect = handle; + overlayInfo.secondHandleInfo = secondHandleInfo; + } + overlayInfo.extraInfo.boolExtra.insert({ CLIPBOARD_HAS_DATA, hasData }); + overlayInfo.extraInfo.boolExtra.insert({ SELECT_OVERLAY_MENU_IS_SHOW, isMenuShow }); + pattern->RequestOpenSelectOverlay(overlayInfo); + auto start = pattern->GetTextSelectController()->GetStartIndex(); + auto end = pattern->GetTextSelectController()->GetEndIndex(); + pattern->UpdateSelectInfo(pattern->contentController_->GetSelectedValue(start, end)); + }; + clipboard_->HasData(hasDataCallback); +} + +bool TextFieldPattern::OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extraInfo) +{ + auto host = GetHost(); + CHECK_NULL_RETURN(host, false); + auto layoutProperty = host->GetLayoutProperty(); + CHECK_NULL_RETURN(layoutProperty, false); + bool isHideSelectionMenu = layoutProperty->GetSelectionMenuHiddenValue(false); + // right click menu + if (IsUsingMouse()) { + CHECK_NULL_RETURN(isHideSelectionMenu, false); + overlayInfo.rightClickOffset = GetRightClickOffset(); + overlayInfo.isUsingMouse = true; + } else { + if (overlayInfo.isSingleHandle && IsTextArea() && GetSelectMode() == SelectionMode::SELECT_ALL) { + auto contentRect = GetContentRect(); + auto parentGlobalOffset = GetParentGlobalOffset(); + overlayInfo.menuInfo.menuOffset = OffsetF(contentRect.GetOffset().GetX() + contentRect.Width() / 2.0 + parentGlobalOffset.GetX(), contentRect.GetOffset().GetY() + parentGlobalOffset.GetY()); } - selectInfo.onHandleMove = [weak](const RectF& handleRect, bool isFirst) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->OnHandleMove(handleRect, isFirst); - }; - selectInfo.onHandleMoveDone = [weak](const RectF& handleRect, bool isFirst) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->OnHandleMoveDone(handleRect, isFirst); - }; + overlayInfo.singleLineHeight = PreferredLineHeight(); + } + auto hasTextContent = !contentController_->IsEmpty(); + overlayInfo.menuInfo.showCopy = hasTextContent && AllowCopy() && IsSelected(); + overlayInfo.menuInfo.showCut = overlayInfo.menuInfo.showCopy; + overlayInfo.menuInfo.showCopyAll = hasTextContent && !IsSelectAll(); + auto hasData = extraInfo.GetBoolOrDefault(CLIPBOARD_HAS_DATA, false); + overlayInfo.menuInfo.showPaste = hasData; + overlayInfo.menuInfo.menuIsShow = (hasTextContent || hasData) && !isHideSelectionMenu && + extraInfo.GetBoolOrDefault(SELECT_OVERLAY_MENU_IS_SHOW, false); + overlayInfo.isHandleLineShow = overlayInfo.isHandleLineShow && !IsSingleHandle(); + overlayInfo.menuInfo.menuDisable = isHideSelectionMenu; + auto gesture = host->GetOrCreateGestureEventHub(); + gesture->RemoveTouchEvent(GetTouchListener()); + return true; +} - auto host = pattern->GetHost(); - CHECK_NULL_VOID(host); - auto layoutProperty = host->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); +// 建议将函数名换成和overlay相关,此函数会和select中的handle产生歧义 +void TextFieldPattern::UpdateFirstHandlePosition(bool needLayout) +{ + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + SelectHandleInfo handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); + handleInfo.needLayout = needLayout; + proxy->UpdateFirstSelectHandleInfo(handleInfo); +} - bool isHideSelectionMenu = layoutProperty->GetSelectionMenuHiddenValue(false); - selectInfo.isUsingMouse = pattern->IsUsingMouse(); - if (isHideSelectionMenu && selectInfo.isUsingMouse) { - return; - } +void TextFieldPattern::UpdateSecondHandlePosition(bool needLayout) +{ + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + SelectHandleInfo handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); + proxy->UpdateSecondSelectHandleInfo(handleInfo); +} - selectInfo.rightClickOffset = pattern->GetRightClickOffset(); - selectInfo.singleLineHeight = pattern->PreferredLineHeight(); - pattern->UpdateSelectMenuInfo(hasData, isHideSelectionMenu); - selectInfo.menuInfo = pattern->GetSelectMenuInfo(); - if (!isMenuShow) { - selectInfo.menuInfo.menuIsShow = false; - } - if (pattern->isSingleHandle_) { - selectInfo.isHandleLineShow = false; - } - selectInfo.menuCallback.onCopy = [weak]() { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->HandleOnCopy(); - pattern->CloseSelectOverlay(true); - }; +// 基于最新的代码整改 +void TextFieldPattern::UpdateDoubleHandlePosition(bool firstNeedLayout, bool secondNeedLayout) +{ + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + SelectHandleInfo firstHandleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); + firstHandleInfo.needLayout = firstNeedLayout; - selectInfo.menuCallback.onCut = [weak]() { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->HandleOnCut(); - pattern->CloseSelectOverlay(true); - }; + SelectHandleInfo secondHandleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); + secondHandleInfo.needLayout = secondNeedLayout; + proxy->UpdateFirstAndSecondHandleInfo(firstHandleInfo, secondHandleInfo); - selectInfo.menuCallback.onPaste = [weak]() { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->HandleOnPaste(); - pattern->CloseSelectOverlay(true); - }; - selectInfo.menuCallback.onSelectAll = [weak]() { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->HandleOnSelectAll(false); - pattern->UpdateCopyAllStatus(); - pattern->SetNeedCloseOverlay(false); - }; - selectInfo.onClose = [weak](bool closedByGlobalEvent) { - if (closedByGlobalEvent) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - auto host = pattern->GetHost(); - CHECK_NULL_VOID(host); - auto current = pattern->GetTextSelector().GetEnd(); - pattern->SetInSelectMode(SelectionMode::NONE); - pattern->UpdateSelection(current); - pattern->MarkRedrawOverlay(); - pattern->StartTwinkling(); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - } - }; + auto selectionVisible = !firstHandleInfo.isShow && !secondHandleInfo.isShow && CheckSelectionRectVisible(); + proxy->SetSelectRegionVisible(selectionVisible); +} - if (!pattern->GetMenuOptionItems().empty()) { - selectInfo.menuOptionItems = pattern->GetMenuOptionItems(); - } - auto gesture = host->GetOrCreateGestureEventHub(); - gesture->RemoveTouchEvent(pattern->GetTouchListener()); - pattern->SetSelectOverlay(pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( - selectInfo, WeakClaim(RawPtr(pattern)), animation)); - - auto selectOverlay = pattern->GetSelectOverlay(); - CHECK_NULL_VOID(selectOverlay); - auto start = pattern->GetTextSelector().GetStart(); - auto end = pattern->GetTextSelector().GetEnd(); - selectOverlay->SetSelectInfo(pattern->GetTextEditingValue().GetSelectedText(start, end)); - if (isMenuShow) { - selectOverlay->ShowOrHiddenMenu(isHideSelectionMenu); - } - selectOverlay->DisableMenu(isHideSelectionMenu); - }; - clipboard_->HasData(hasDataCallback); +SelectHandleInfo TextFieldPattern::GetSelectHandleInfo(OffsetF offset) +{ + SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), + selectController_->GetCaretRect().Height() }; + // 要将相对textRect的坐标转换为全局坐标 + auto paintRect = RectF(offset.GetX() + GetTextPaintOffset().GetX(), offset.GetY() + GetTextPaintOffset().GetY(), + handlePaintSize.Width(), handlePaintSize.Height()); + return { .isShow = CheckHandleVisible(paintRect), .paintRect = paintRect }; } bool TextFieldPattern::AllowCopy() @@ -3035,6 +2059,11 @@ bool TextFieldPattern::AllowCopy() void TextFieldPattern::OnDetachFromFrameNode(FrameNode* node) { CloseSelectOverlay(); + ResetSelectOverlayClient(); + if (responseArea_) { + responseArea_->DestoryArea(); + responseArea_.Reset(); + } auto pipeline = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipeline); if (HasSurfaceChangedCallback()) { @@ -3066,74 +2095,60 @@ void TextFieldPattern::CloseSelectOverlay() void TextFieldPattern::CloseSelectOverlay(bool animation) { - if (selectOverlayProxy_) { - LOGI("Close select overlay"); - selectOverlayProxy_->Close(animation); - } + RequestCloseSelectOverlay(animation); auto host = GetHost(); CHECK_NULL_VOID(host); auto gesture = host->GetOrCreateGestureEventHub(); gesture->AddTouchEvent(GetTouchListener()); - originalIsMenuShow_ = false; -} - -bool TextFieldPattern::SelectOverlayIsOn() -{ - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_RETURN(pipeline, false); - CHECK_NULL_RETURN(selectOverlayProxy_, false); - auto overlayId = selectOverlayProxy_->GetSelectOverlayId(); - return pipeline->GetSelectOverlayManager()->HasSelectOverlay(overlayId); } void TextFieldPattern::OnHandleMove(const RectF& handleRect, bool isFirstHandle) { CHECK_NULL_VOID(SelectOverlayIsOn()); - CHECK_NULL_VOID(!textEditingValue_.Empty()); - isFirstHandle_ = isFirstHandle; + CHECK_NULL_VOID(!contentController_->IsEmpty()); auto localOffset = handleRect.GetOffset() - parentGlobalOffset_; - isTouchAtLeftOffset_ = IsTouchAtLeftOffset(localOffset.GetX()); auto position = UpdateCaretPositionOnHandleMove(localOffset); - textEditingValue_.CursorMoveToPosition(position); - auto caretMetrics = CalcCursorOffsetByPosition(position, isTouchAtLeftOffset_); - caretRect_.SetOffset(caretMetrics.offset); - selectionMode_ = isSingleHandle_ ? SelectionMode::NONE : SelectionMode::SELECT; - caretUpdateType_ = CaretUpdateType::HANDLE_MOVE; - UpdateTextSelectorByHandleMove(isFirstHandle, position, caretMetrics.offset); - - auto selectOverlay = GetSelectOverlay(); - CHECK_NULL_VOID(selectOverlay); - auto start = GetTextSelector().GetStart(); - auto end = GetTextSelector().GetEnd(); - selectOverlay->SetSelectInfo(GetTextEditingValue().GetSelectedText(start, end)); - - GetTextRectsInRange(start, end, textBoxes_); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + if (isSingleHandle_) { + selectController_->MoveCaretToContentRect(position); + } else { + if (isFirstHandle) { + selectController_->MoveFirstHandleToContentRect(position); + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + SelectHandleInfo handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); + proxy->UpdateSecondSelectHandleInfo(handleInfo); + } else { + selectController_->MoveSecondHandleToContentRect(position); + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + SelectHandleInfo handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); + proxy->UpdateFirstSelectHandleInfo(handleInfo); + } + } + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } int32_t TextFieldPattern::UpdateCaretPositionOnHandleMove(const OffsetF& localOffset) { int32_t position = 0; if (!IsTextArea()) { - if (localOffset.GetX() < contentRect_.GetX()) { - position = std::max(static_cast(textEditingValue_.caretPosition - - GetGraphemeClusterLength(GetEditingValue().GetWideText(), - GetEditingValue().caretPosition, true)), + if (LessNotEqual(localOffset.GetX(), contentRect_.GetX())) { + position = std::max(static_cast(selectController_->GetStartIndex() - + GetGraphemeClusterLength(contentController_->GetWideText(), + selectController_->GetStartIndex(), true)), 0); } else if (GreatOrEqual(localOffset.GetX(), contentRect_.GetX() + contentRect_.Width())) { - position = std::min(static_cast(textEditingValue_.caretPosition + - GetGraphemeClusterLength(GetEditingValue().GetWideText(), - GetEditingValue().caretPosition)), - static_cast(textEditingValue_.GetWideText().length())); + position = std::min(static_cast(selectController_->GetEndIndex() + + GetGraphemeClusterLength(contentController_->GetWideText(), + selectController_->GetEndIndex())), + static_cast(contentController_->GetWideText().length())); } else { Offset offset(localOffset.GetX() - textRect_.GetX(), 0.0f); position = ConvertTouchOffsetToCaretPosition(offset); } return position; } - if (localOffset.GetY() < contentRect_.GetY()) { + if (LessNotEqual(localOffset.GetY(), contentRect_.GetY())) { position = ConvertTouchOffsetToCaretPosition(Offset( localOffset.GetX() - GetPaddingLeft(), localOffset.GetY() - textRect_.GetY() - PreferredLineHeight())); } else if (GreatOrEqual(localOffset.GetY(), contentRect_.GetY() + contentRect_.Height())) { @@ -3148,115 +2163,52 @@ int32_t TextFieldPattern::UpdateCaretPositionOnHandleMove(const OffsetF& localOf void TextFieldPattern::UpdateCopyAllStatus() { - selectMenuInfo_.showCopyAll = !IsSelectAll(); auto host = GetHost(); CHECK_NULL_VOID(host); auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (selectOverlayProxy_ && !layoutProperty->GetSelectionMenuHiddenValue(false)) { - selectOverlayProxy_->UpdateSelectMenuInfo(selectMenuInfo_); - } -} - -void TextFieldPattern::UpdateTextSelectorByHandleMove( - bool isMovingBase, int32_t position, OffsetF& offsetToParagraphBeginning) -{ - if (isSingleHandle_) { - textSelector_.selectionBaseOffset = offsetToParagraphBeginning; - textSelector_.selectionDestinationOffset = textSelector_.selectionBaseOffset; - UpdateSelection(position); - return; - } - if (isMovingBase) { - UpdateSelection(position, textSelector_.GetEnd()); - textSelector_.selectionBaseOffset = offsetToParagraphBeginning; - return; + if (!layoutProperty->GetSelectionMenuHiddenValue(false)) { + UpdateSelectMenuInfo([weak = WeakClaim(this)](SelectMenuInfo& menuInfo) { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + menuInfo.showCopyAll = !pattern->IsSelectAll(); + }); } - UpdateSelection(textSelector_.GetStart(), position); - textSelector_.selectionDestinationOffset = offsetToParagraphBeginning; } void TextFieldPattern::OnHandleMoveDone(const RectF& /* handleRect */, bool isFirstHandle) { - CHECK_NULL_VOID(SelectOverlayIsOn()); - caretUpdateType_ = CaretUpdateType::HANDLE_MOVE_DONE; - isFirstHandle_ = isFirstHandle; - if (!isSingleHandle_) { - StopTwinkling(); - } UpdateCopyAllStatus(); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); -} - -void TextFieldPattern::UpdateOtherHandleOnMove(float dx, float dy) -{ - SelectHandleInfo firstInfo, secondInfo; - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - if (isFirstHandle_) { - // update position of the other handle - textSelector_.secondHandleOffset_.AddX(dx); - textSelector_.secondHandleOffset_.AddY(dy); - secondInfo.paintRect = { textSelector_.secondHandleOffset_, handlePaintSize }; - // hide the other handle if it's outside content rect - auto handleOffset = textSelector_.secondHandleOffset_ - parentGlobalOffset_; - secondInfo.isShow = - contentRect_.IsInRegion({ handleOffset.GetX(), handleOffset.GetY() + caretRect_.Height() / 2 }); - selectOverlayProxy_->UpdateSecondSelectHandleInfo(secondInfo); + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + if (!isSingleHandle_) { + auto handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); + proxy->UpdateFirstSelectHandleInfo(handleInfo); + handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); + proxy->UpdateSecondSelectHandleInfo(handleInfo); } else { - textSelector_.firstHandleOffset_.AddX(dx); - textSelector_.firstHandleOffset_.AddY(dy); - firstInfo.paintRect = { textSelector_.firstHandleOffset_, handlePaintSize }; - - auto handleOffset = textSelector_.firstHandleOffset_ - parentGlobalOffset_; - firstInfo.isShow = - contentRect_.IsInRegion({ handleOffset.GetX(), handleOffset.GetY() + caretRect_.Height() / 2 }); - selectOverlayProxy_->UpdateFirstSelectHandleInfo(firstInfo); + auto handleInfo = GetSelectHandleInfo(selectController_->GetCaretRect().GetOffset()); + proxy->UpdateSecondSelectHandleInfo(handleInfo); } + + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } -void TextFieldPattern::SetHandlerOnMoveDone() +void TextFieldPattern::OnHandleClosed(bool closedByGlobalEvent) { - SelectHandleInfo info; - auto newHandleOffset = parentGlobalOffset_; - CaretMetricsF handleOffset; - if (!isSingleHandle_) { - handleOffset = CalcCursorOffsetByPosition( - isFirstHandle_ ? textSelector_.baseOffset : textSelector_.destinationOffset, isFirstHandle_ ? true : false); - } else { - handleOffset = CalcCursorOffsetByPosition(textEditingValue_.caretPosition, isTouchAtLeftOffset_); - } - newHandleOffset += handleOffset.offset; - SizeF handlePaintSize = { SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), caretRect_.Height() }; - RectF newHandle; - newHandle.SetOffset(newHandleOffset); - newHandle.SetSize(handlePaintSize); - info.paintRect = newHandle; - info.needLayout = true; - selectionMode_ = isSingleHandle_ ? SelectionMode::NONE : SelectionMode::SELECT; - if (isFirstHandle_) { - textSelector_.firstHandleOffset_ = newHandleOffset; - selectOverlayProxy_->UpdateFirstSelectHandleInfo(info); - return; + SelectOverlayClient::OnHandleClosed(closedByGlobalEvent); + if (closedByGlobalEvent) { + auto host = GetHost(); + CHECK_NULL_VOID(host); + selectController_->UpdateCaretIndex(selectController_->GetSecondHandleIndex()); + StartTwinkling(); } - textSelector_.secondHandleOffset_ = newHandleOffset; - selectOverlayProxy_->UpdateSecondSelectHandleInfo(info); } void TextFieldPattern::InitEditingValueText(std::string content) { - textEditingValue_.text = std::move(content); - textEditingValue_.caretPosition = textEditingValue_.GetWideText().length(); - SetEditingValueToProperty(textEditingValue_.text); - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - layoutProperty->UpdateNeedFireOnChange(true); -} - -void TextFieldPattern::InitCaretPosition(std::string content) -{ - textEditingValue_.caretPosition = static_cast(StringUtils::ToWstring(content).length()); + contentController_->SetTextValue(std::move(content)); + selectController_->UpdateCaretIndex(static_cast(StringUtils::ToWstring(content).length())); } void TextFieldPattern::InitMouseEvent() @@ -3342,125 +2294,102 @@ void TextFieldPattern::HandleMouseEvent(MouseInfo& info) auto pipeline = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(pipeline); pipeline->SetMouseStyleHoldNode(frameId); - - if (!IsSearchParentNode()) { - info.SetStopPropagation(true); - } - - if (info.GetLocalLocation().GetX() > (frameRect_.Width() - imageRect_.Width() - GetIconRightOffset()) && - NeedShowPasswordIcon()) { + auto responseAreaWidth = responseArea_ ? responseArea_->GetAreaRect().Width() : 0.0f; + if (info.GetLocalLocation().GetX() > (frameRect_.Width() - responseAreaWidth)) { pipeline->ChangeMouseStyle(frameId, MouseFormat::DEFAULT); return; - } else { - pipeline->ChangeMouseStyle(frameId, MouseFormat::TEXT_CURSOR); } + pipeline->ChangeMouseStyle(frameId, MouseFormat::TEXT_CURSOR); + CloseSelectOverlay(true); + isUsingMouse_ = true; + if (info.GetButton() == MouseButton::RIGHT_BUTTON) { + HandleRightMouseEvent(info); + } else if (info.GetButton() == MouseButton::LEFT_BUTTON) { + HandleLeftMouseEvent(info); + } +} - auto focusHub = tmpHost->GetOrCreateFocusHub(); - - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(tmpHost->GetParent()); - focusHub = parentFrameNode->GetOrCreateFocusHub(); +void TextFieldPattern::HandleRightMouseEvent(MouseInfo& info) +{ + if (info.GetAction() == MouseAction::RELEASE) { + LOGI("Handle mouse right button release"); + rightClickOffset_ = OffsetF( + static_cast(info.GetGlobalLocation().GetX()), static_cast(info.GetGlobalLocation().GetY())); + ProcessOverlay(); } +} - if (info.GetButton() == MouseButton::RIGHT_BUTTON) { - if (info.GetAction() == MouseAction::PRESS) { - LOGI("Handle mouse right button press"); - isMousePressed_ = true; +void TextFieldPattern::HandleLeftMouseEvent(MouseInfo& info) +{ + switch (info.GetAction()) { + case OHOS::Ace::MouseAction::PRESS: { + HandleLeftMousePressEvent(info); + break; } - if (info.GetAction() == MouseAction::PRESS || info.GetAction() == MouseAction::RELEASE) { - CloseSelectOverlay(true); + case OHOS::Ace::MouseAction::MOVE: { + HandleLeftMouseMoveEvent(info); // 注意鼠标拖拽的滚动效果 + break; } - - if (info.GetAction() == MouseAction::RELEASE) { - LOGI("Handle mouse right button release"); - rightClickOffset_ = OffsetF(static_cast(info.GetGlobalLocation().GetX()), - static_cast(info.GetGlobalLocation().GetY())); - lastTouchOffset_ = info.GetLocalLocation(); - caretUpdateType_ = CaretUpdateType::RIGHT_CLICK; - isSingleHandle_ = false; - isUsingMouse_ = true; - mouseStatus_ = MouseStatus::RELEASED; - isMousePressed_ = false; - ProcessOverlay(true); - caretUpdateType_ = CaretUpdateType::NONE; + case OHOS::Ace::MouseAction::RELEASE: { + HandleLeftMouseReleaseEvent(info); + break; } + default: { + } + } +} + +void TextFieldPattern::HandleLeftMousePressEvent(MouseInfo& info) +{ + if (selectController_->IsSelected() && BetweenSelectedPosition(info.GetGlobalLocation())) { + blockPress_ = true; return; } - if (info.GetAction() == MouseAction::PRESS) { - LOGI("Handle mouse left button press"); - if (IsSelected() && BetweenSelectedPosition(info.GetGlobalLocation())) { - blockPress_ = true; - return; - } - blockPress_ = false; - CloseSelectOverlay(true); - if (!focusHub->IsFocusable()) { - return; - } - isMousePressed_ = true; - isUsingMouse_ = true; - mouseStatus_ = MouseStatus::PRESSED; - StartTwinkling(); - lastTouchOffset_ = info.GetLocalLocation(); - isTouchAtLeftOffset_ = IsTouchAtLeftOffset(lastTouchOffset_.GetX()); - caretUpdateType_ = CaretUpdateType::PRESSED; - selectionMode_ = SelectionMode::NONE; - UpdateCaretPositionByPressOffset(); - auto paintProperty = GetPaintProperty(); - CHECK_NULL_VOID(paintProperty); - if (paintProperty->GetInputStyleValue(InputStyle::DEFAULT) != InputStyle::INLINE && - (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately())) { - LOGW("Request focus failed, cannot open input method"); - StopTwinkling(); - return; - } - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + auto focusHub = GetFocusHub(); + if (!focusHub->IsFocusable()) { return; } - if (info.GetAction() == MouseAction::RELEASE) { - LOGI("Handle mouse left button release"); - if (blockPress_) { - blockPress_ = false; - } - if (isDoubleClick_) { - caretUpdateType_ = CaretUpdateType::EVENT; - isMousePressed_ = false; - mouseStatus_ = MouseStatus::RELEASED; - MarkRedrawOverlay(); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - } else { - CloseSelectOverlay(true); - caretUpdateType_ = CaretUpdateType::NONE; - isMousePressed_ = false; - mouseStatus_ = MouseStatus::RELEASED; - if (!focusHub->IsCurrentFocus()) { - return; - } - if (RequestKeyboard(false, true, true)) { - auto eventHub = tmpHost->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - } - } + mouseStatus_ = MouseStatus::PRESSED; + blockPress_ = false; + leftMouseCanMove_ = true; + auto paintProperty = GetPaintProperty(); + CHECK_NULL_VOID(paintProperty); + if (paintProperty->GetInputStyleValue(InputStyle::DEFAULT) != InputStyle::INLINE && + (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately())) { + StopTwinkling(); + return; } + selectController_->UpdateCaretInfoByOffset(info.GetLocalLocation()); + StartTwinkling(); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); +} - if (info.GetAction() == MouseAction::MOVE) { - if (!isMousePressed_ || blockPress_) { - return; - } - caretUpdateType_ = CaretUpdateType::EVENT; - lastTouchOffset_ = info.GetLocalLocation(); - isTouchAtLeftOffset_ = IsTouchAtLeftOffset(lastTouchOffset_.GetX()); - mouseStatus_ = MouseStatus::MOVE; - MarkRedrawOverlay(); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); +void TextFieldPattern::HandleLeftMouseMoveEvent(MouseInfo& info) +{ + if (!leftMouseCanMove_ || blockPress_) { + return; } + mouseStatus_ = MouseStatus::MOVE; + selectController_->UpdateSecondHandleInfoByMouseOffset(info.GetLocalLocation()); // 更新时上报事件 + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } -void TextFieldPattern::UpdatePositionOfParagraph(int32_t position) +void TextFieldPattern::HandleLeftMouseReleaseEvent(MouseInfo& info) { - textEditingValue_.CursorMoveToPosition(position); + if (blockPress_ && mouseStatus_ == MouseStatus::PRESSED) { + selectController_->UpdateCaretInfoByOffset(info.GetLocalLocation()); + StartTwinkling(); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + } + mouseStatus_ = MouseStatus::NONE; + blockPress_ = false; + leftMouseCanMove_ = false; + auto eventHub = GetHost()->GetEventHub(); + CHECK_NULL_VOID(eventHub); + if (HasFocus() && RequestKeyboard(false, true, true)) { + eventHub->FireOnEditChanged(true); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + } } void TextFieldPattern::UpdateTextFieldManager(const Offset& offset, float height) @@ -3482,9 +2411,7 @@ void TextFieldPattern::UpdateTextFieldManager(const Offset& offset, float height TextInputAction TextFieldPattern::GetDefaultTextInputAction() { TextInputAction defaultTextInputAction = TextInputAction::DONE; - if (IsSearchParentNode()) { - defaultTextInputAction = TextInputAction::SEARCH; - } else if (IsTextArea()) { + if (IsTextArea()) { defaultTextInputAction = TextInputAction::UNSPECIFIED; } else { defaultTextInputAction = TextInputAction::DONE; @@ -3492,6 +2419,7 @@ TextInputAction TextFieldPattern::GetDefaultTextInputAction() return defaultTextInputAction; } +// todo 代整改 bool TextFieldPattern::RequestKeyboard(bool isFocusViewChanged, bool needStartTwinkling, bool needShowSoftKeyboard) { auto tmpHost = GetHost(); @@ -3543,9 +2471,9 @@ bool TextFieldPattern::RequestKeyboard(bool isFocusViewChanged, bool needStartTw return false; } TextEditingValue value; - value.text = textEditingValue_.text; + value.text = contentController_->GetTextValue(); value.hint = GetPlaceHolder(); - value.selection.Update(textSelector_.baseOffset, textSelector_.destinationOffset); + value.selection.Update(selectController_->GetStartIndex(), selectController_->GetEndIndex()); connection_->SetEditingState(value, GetInstanceId()); } connection_->Show(isFocusViewChanged, GetInstanceId()); @@ -3562,15 +2490,16 @@ std::optional TextFieldPattern::GetMiscTextConfig() co auto pipeline = tmpHost->GetContext(); CHECK_NULL_RETURN(pipeline, {}); auto windowRect = pipeline->GetCurrentWindowRect(); - MiscServices::CursorInfo cursorInfo { .left = caretRect_.Left() + windowRect.Left() + parentGlobalOffset_.GetX(), - .top = caretRect_.Top() + windowRect.Top() + parentGlobalOffset_.GetY(), + MiscServices::CursorInfo cursorInfo { .left = selectController_->GetCaretRect().Left() + windowRect.Left() + + parentGlobalOffset_.GetX(), + .top = selectController_->GetCaretRect().Top() + windowRect.Top() + parentGlobalOffset_.GetY(), .width = CURSOR_WIDTH.ConvertToPx(), - .height = caretRect_.Height() }; + .height = selectController_->GetCaretRect().Height() }; MiscServices::InputAttribute inputAttribute = { .inputPattern = (int32_t)keyboard_, .enterKeyType = (int32_t)GetTextInputActionValue(TextInputAction::DONE) }; MiscServices::TextConfig textConfig = { .inputAttribute = inputAttribute, .cursorInfo = cursorInfo, - .range = { .start = textSelector_.GetStart(), .end = textSelector_.GetEnd() }, + .range = { .start = selectController_->GetStartIndex(), .end = selectController_->GetEndIndex() }, .windowId = pipeline->GetFocusWindowId() }; return textConfig; } @@ -3643,201 +2572,6 @@ bool TextFieldPattern::CloseCustomKeyboard() return true; } -void TextFieldPattern::ProcessPasswordIcon() -{ - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - if (layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) != TextInputType::VISIBLE_PASSWORD) { - return; - } - - bool showPasswordIcon = layoutProperty->GetShowPasswordIconValue(true); - if (!showPasswordIcon) { - return; - } - if (textObscured_) { - ImageSourceInfo hidePasswordSourceInfo = GetImageSourceInfoFromTheme(textObscured_); - if (hideUserDefinedIcon_) { - UpdateUserDefineResource(hidePasswordSourceInfo); - } else { - UpdateInternalResource(hidePasswordSourceInfo); - } - LoadNotifier hideIconLoadNotifier(CreateDataReadyCallback(textObscured_), - CreateLoadSuccessCallback(textObscured_), CreateLoadFailCallback(textObscured_)); - hidePasswordImageLoadingCtx_ = - AceType::MakeRefPtr(hidePasswordSourceInfo, std::move(hideIconLoadNotifier), true); - hidePasswordImageLoadingCtx_->LoadImageData(); - return; - } - if (!textObscured_) { - ImageSourceInfo showPasswordSourceInfo = GetImageSourceInfoFromTheme(textObscured_); - if (showUserDefinedIcon_) { - UpdateUserDefineResource(showPasswordSourceInfo); - } else { - UpdateInternalResource(showPasswordSourceInfo); - } - LoadNotifier showIconLoadNotifier(CreateDataReadyCallback(textObscured_), - CreateLoadSuccessCallback(textObscured_), CreateLoadFailCallback(textObscured_)); - showPasswordImageLoadingCtx_ = - AceType::MakeRefPtr(showPasswordSourceInfo, std::move(showIconLoadNotifier), true); - showPasswordImageLoadingCtx_->LoadImageData(); - return; - } -} - -ImageSourceInfo TextFieldPattern::GetImageSourceInfoFromTheme(bool checkHidePasswordIcon) -{ - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, {}); - auto context = tmpHost->GetContext(); - CHECK_NULL_RETURN(context, {}); - ImageSourceInfo imageSourceInfo; - auto theme = context->GetTheme(); - CHECK_NULL_RETURN(theme, imageSourceInfo); - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_RETURN(layoutProperty, imageSourceInfo); - if (checkHidePasswordIcon && hideUserDefinedIcon_) { - return layoutProperty->GetHidePasswordSourceInfoValue(imageSourceInfo); - } - if (checkHidePasswordIcon) { - imageSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG); - return imageSourceInfo; - } - if (showUserDefinedIcon_) { - return layoutProperty->GetShowPasswordSourceInfoValue(imageSourceInfo); - } - imageSourceInfo.SetResourceId(InternalResource::ResourceId::SHOW_PASSWORD_SVG); - return imageSourceInfo; -} - -void TextFieldPattern::UpdateUserDefineResource(ImageSourceInfo& sourceInfo) -{ - auto pipeline = PipelineBase::GetCurrentContext(); - CHECK_NULL_VOID(pipeline); - auto iconPath = sourceInfo.GetSrc(); - if (iconPath.empty()) { - LOGE("Icon path empty"); - return; - } - sourceInfo.SetDimension(DEFAULT_FONT, DEFAULT_FONT); - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - if (textObscured_) { - layoutProperty->UpdateHidePasswordSourceInfo(sourceInfo); - return; - } - layoutProperty->UpdateShowPasswordSourceInfo(sourceInfo); -} - -void TextFieldPattern::UpdateInternalResource(ImageSourceInfo& sourceInfo) -{ - CHECK_NULL_VOID(sourceInfo.IsInternalResource()); - auto pipeline = PipelineBase::GetCurrentContext(); - CHECK_NULL_VOID(pipeline); - auto iconTheme = pipeline->GetTheme(); - CHECK_NULL_VOID(iconTheme); - auto iconPath = iconTheme->GetIconPath(sourceInfo.GetResourceId()); - if (iconPath.empty()) { - LOGE("Icon path empty"); - return; - } - auto theme = pipeline->GetTheme(); - CHECK_NULL_VOID(theme); - if (IsDisabled()) { - sourceInfo.SetSrc(iconPath, theme->GetDisableTextColor()); - } else { - sourceInfo.SetSrc(iconPath); - } - sourceInfo.SetDimension(DEFAULT_FONT, DEFAULT_FONT); - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - if (textObscured_) { - layoutProperty->UpdateHidePasswordSourceInfo(sourceInfo); - return; - } - layoutProperty->UpdateShowPasswordSourceInfo(sourceInfo); -} - -LoadSuccessNotifyTask TextFieldPattern::CreateLoadSuccessCallback(bool checkHidePasswordIcon) -{ - auto task = [weak = WeakClaim(this), checkHidePasswordIcon](const ImageSourceInfo& /* sourceInfo */) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->OnImageLoadSuccess(checkHidePasswordIcon); - }; - return task; -} - -DataReadyNotifyTask TextFieldPattern::CreateDataReadyCallback(bool checkHidePasswordIcon) -{ - auto task = [weak = WeakClaim(this), checkHidePasswordIcon](const ImageSourceInfo& /* sourceInfo */) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->OnImageDataReady(checkHidePasswordIcon); - }; - return task; -} - -LoadFailNotifyTask TextFieldPattern::CreateLoadFailCallback(bool checkHidePasswordIcon) -{ - auto task = [weak = WeakClaim(this), checkHidePasswordIcon]( - const ImageSourceInfo& /* sourceInfo */, const std::string& msg) { - auto pattern = weak.Upgrade(); - CHECK_NULL_VOID(pattern); - pattern->OnImageLoadFail(checkHidePasswordIcon); - }; - return task; -} - -void TextFieldPattern::OnImageLoadFail(bool checkHidePasswordIcon) -{ - LOGE("Image data load fail for %{public}s", checkHidePasswordIcon ? "hide icon" : "show icon"); - if (checkHidePasswordIcon && hideUserDefinedIcon_) { - hideUserDefinedIcon_ = false; - ProcessPasswordIcon(); - hideUserDefinedIcon_ = true; - } - if (!checkHidePasswordIcon && showUserDefinedIcon_) { - showUserDefinedIcon_ = false; - ProcessPasswordIcon(); - showUserDefinedIcon_ = true; - } -} - -void TextFieldPattern::OnImageDataReady(bool checkHidePasswordIcon) -{ - ACE_SCOPED_TRACE("TextFieldPattern::OnImageDataReady"); - auto host = GetHost(); - CHECK_NULL_VOID(host); - LOGI("Image data ready for %{public}s", checkHidePasswordIcon ? "hide icon" : "show icon"); - - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); -} - -void TextFieldPattern::OnImageLoadSuccess(bool checkHidePasswordIcon) -{ - ACE_SCOPED_TRACE("TextFieldPattern::OnImageLoadSuccess"); - ImagePaintConfig config; - auto host = GetHost(); - CHECK_NULL_VOID(host); - host->MarkNeedRenderOnly(); - if (checkHidePasswordIcon) { - LOGI("Load hide icon successfully"); - hidePasswordCanvasImage_ = hidePasswordImageLoadingCtx_->MoveCanvasImage(); - config.srcRect_ = hidePasswordImageLoadingCtx_->GetSrcRect(); - config.dstRect_ = hidePasswordImageLoadingCtx_->GetDstRect(); - config.isSvg_ = hidePasswordImageLoadingCtx_->GetSourceInfo().IsSvg(); - hidePasswordCanvasImage_->SetPaintConfig(config); - return; - } - LOGI("Load show icon successfully"); - showPasswordCanvasImage_ = showPasswordImageLoadingCtx_->MoveCanvasImage(); - config.srcRect_ = showPasswordImageLoadingCtx_->GetSrcRect(); - config.dstRect_ = showPasswordImageLoadingCtx_->GetDstRect(); - config.isSvg_ = showPasswordImageLoadingCtx_->GetSourceInfo().IsSvg(); - showPasswordCanvasImage_->SetPaintConfig(config); -} - void TextFieldPattern::OnTextInputActionUpdate(TextInputAction value) {} void TextFieldPattern::InsertValue(const std::string& insertValue) @@ -3847,75 +2581,51 @@ void TextFieldPattern::InsertValue(const std::string& insertValue) } auto wideInsertValue = StringUtils::ToWstring(insertValue); LOGD("Insert length %{public}d", static_cast(wideInsertValue.length())); - auto originLength = static_cast(textEditingValue_.GetWideText().length()); + auto originLength = static_cast(contentController_->GetWideText().length()); if (originLength >= GetMaxLength() && !IsSelected()) { LOGW("Max length reached"); return; } - - std::string valueToUpdate; - if (originLength + wideInsertValue.length() >= GetMaxLength() && !IsSelected()) { - valueToUpdate = StringUtils::ToString(wideInsertValue.substr(0, GetMaxLength() - originLength)); - } else { - valueToUpdate = insertValue; - } - std::string oldText = textEditingValue_.text; auto caretStart = 0; - std::string result; auto host = GetHost(); CHECK_NULL_VOID(host); auto textFieldLayoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(textFieldLayoutProperty); - auto start = textSelector_.GetStart(); - auto end = textSelector_.GetEnd(); - SwapIfLarger(start, end); + auto start = selectController_->GetStartIndex(); + auto end = selectController_->GetEndIndex(); + // SwapIfLarger(start, end); if (IsSelected()) { LOGI("In select mode, replace selected text"); caretStart = start; } else { - caretStart = textEditingValue_.caretPosition; - } - EditingValueFilter(valueToUpdate, result, true); - if (result.empty()) { - return; + caretStart = selectController_->GetCaretIndex(); } + int32_t caretMoveLength = 0; if (IsSelected()) { - textEditingValue_.text = - textEditingValue_.GetValueBeforePosition(start) + result + textEditingValue_.GetValueAfterPosition(end); + auto originLength = static_cast(contentController_->GetWideText().length()) - (end - start); + contentController_->ReplaceSelectedValue(start, end, insertValue); + caretMoveLength = abs(static_cast(contentController_->GetWideText().length()) - originLength); } else { - textEditingValue_.text = - textEditingValue_.GetValueBeforeCursor() + result + textEditingValue_.GetValueAfterCursor(); + auto originLength = static_cast(contentController_->GetWideText().length()); + contentController_->InsertValue(selectController_->GetCaretIndex(), insertValue); + caretMoveLength = abs(static_cast(contentController_->GetWideText().length()) - originLength); } - textEditingValue_.CursorMoveToPosition(caretStart + static_cast(StringUtils::ToWstring(result).length())); + selectController_->UpdateCaretIndex(caretStart + caretMoveLength); if (!IsTextArea() && IsInPasswordMode() && GetTextObscured()) { if (wideInsertValue.length() == 1) { obscureTickCountDown_ = OBSCURE_SHOW_TICKS; - nakedCharPosition_ = textEditingValue_.caretPosition - 1; + nakedCharPosition_ = selectController_->GetCaretIndex() - 1; } else { obscureTickCountDown_ = 0; nakedCharPosition_ = -1; } } - SetEditingValueToProperty(textEditingValue_.text); UpdateEditingValueToRecord(); - caretUpdateType_ = CaretUpdateType::INPUT; cursorVisible_ = true; selectionMode_ = SelectionMode::NONE; CloseSelectOverlay(true); StartTwinkling(); - // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->UpdateChangeEvent(textEditingValue_.text); - parentFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); - return; - } - - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnChange(textEditingValue_.text); + FireOnTextChangeEvent(); auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); if (IsTextArea() && layoutProperty->HasMaxLength()) { @@ -3934,172 +2644,31 @@ void TextFieldPattern::UpdateEditingValueToRecord() } operationRecords_.erase(operationRecords_.begin()); } - operationRecords_.emplace_back(textEditingValue_); -} - -void TextFieldPattern::UpdateEditingValueCaretPositionToRecord() -{ - if (operationRecords_.empty()) { - LOGW("Operation records empty, cannot update position"); - return; - } - if (operationRecords_.back().caretPosition != textEditingValue_.caretPosition) { - operationRecords_.back().caretPosition = textEditingValue_.caretPosition; - } -} - -bool TextFieldPattern::FilterWithRegex( - const std::string& filter, const std::string& valueToUpdate, std::string& result, bool needToEscape) -{ - if (filter.empty() || valueToUpdate.empty()) { - LOGD("Text is empty or filter is empty"); - return false; - } - std::string escapeFilter; - if (needToEscape && !TextFieldControllerBase::EscapeString(filter, escapeFilter)) { - LOGE("Escape filter string failed"); - return false; - } - if (!needToEscape) { - escapeFilter = filter; - } - std::regex filterRegex(escapeFilter); - auto errorText = regex_replace(valueToUpdate, filterRegex, ""); - RemoveErrorTextFromValue(valueToUpdate, errorText, result); - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, false); - if (!errorText.empty()) { - auto textFieldEventHub = tmpHost->GetEventHub(); - CHECK_NULL_RETURN(textFieldEventHub, false); - LOGI("Error text %{private}s", errorText.c_str()); - textFieldEventHub->FireOnInputFilterError(errorText); - } - auto textFieldAccessibilityProperty = tmpHost->GetAccessibilityProperty(); - CHECK_NULL_RETURN(textFieldAccessibilityProperty, false); - textFieldAccessibilityProperty->SetErrorText(errorText); - return !errorText.empty(); -} - -void TextFieldPattern::EditingValueFilter(std::string& valueToUpdate, std::string& result, bool isInsertValue) -{ - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto textFieldLayoutProperty = tmpHost->GetLayoutProperty(); - CHECK_NULL_VOID(textFieldLayoutProperty); - // filter text editing value with user defined filter first - auto inputFilter = textFieldLayoutProperty->GetInputFilterValue(""); - bool textChanged = false; - if (!inputFilter.empty()) { - textChanged |= FilterWithRegex(inputFilter, valueToUpdate, result); - } - if (textChanged) { - valueToUpdate = result; - textChanged = false; - } - result = ""; - switch (textFieldLayoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED)) { - case TextInputType::NUMBER: { - textChanged |= FilterWithRegex(DIGIT_WHITE_LIST, valueToUpdate, result); - break; - } - case TextInputType::PHONE: { - textChanged |= FilterWithRegex(PHONE_WHITE_LIST, valueToUpdate, result); - break; - } - case TextInputType::EMAIL_ADDRESS: { - if (valueToUpdate == "@" && isInsertValue) { - auto charExists = textEditingValue_.text.find('@') != std::string::npos; - result = charExists ? "" : valueToUpdate; - return; - } else { - textChanged |= FilterWithRegex(EMAIL_WHITE_LIST, valueToUpdate, result); - textChanged |= FilterWithEmail(result); - } - break; - } - case TextInputType::URL: { - textChanged |= FilterWithRegex(URL_WHITE_LIST, valueToUpdate, result); - break; - } - case TextInputType::VISIBLE_PASSWORD: { - textChanged |= FilterWithAscii(valueToUpdate, result); - break; - } - default: { - // No need limit. - } - } - if (!textChanged) { - result = valueToUpdate; - } -} - -bool TextFieldPattern::FilterWithAscii(const std::string& valueToUpdate, std::string& result) -{ - if (valueToUpdate.empty()) { - LOGD("Text is empty or filter is empty"); - return false; - } - bool textChange = true; - std::string errorText = ""; - for (size_t valuePtr = 0; valuePtr < valueToUpdate.size(); valuePtr++) { - if (isascii(valueToUpdate[valuePtr])) { - result += valueToUpdate[valuePtr]; - } else { - errorText += valueToUpdate[valuePtr]; - } - } - if (errorText.empty()) { - textChange = false; - } else { - LOGI("FilterWithAscii Error text %{private}s", errorText.c_str()); - } - return textChange; -} - -bool TextFieldPattern::FilterWithEmail(std::string& result) -{ - auto valueToUpdate = result; - bool first = true; - std::replace_if( - result.begin(), result.end(), - [&first](const char c) { - if (c == '@' && !first) - return true; - if (c == '@') - first = false; - return false; - }, - ' '); - - // remove the spaces - result.erase(std::remove(result.begin(), result.end(), ' '), result.end()); - return result != valueToUpdate; + TextEditingValueNG record { + .text = contentController_->GetTextValue(), + .caretPosition = selectController_->GetCaretIndex(), + }; + operationRecords_.emplace_back(record); } float TextFieldPattern::PreferredTextHeight(bool isPlaceholder) { + if (paragraph_ && paragraph_->GetHeight() != 0.0f) { + return paragraph_->GetHeight() / paragraph_->GetLineCount(); + } + RefPtr paragraph; + std::string textContent; + TextStyle textStyle; auto tmpHost = GetHost(); CHECK_NULL_RETURN(tmpHost, 0.0f); - auto layoutProperty = tmpHost->GetLayoutProperty(); + auto layoutProperty = GetHost()->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, 0.0f); - // check if util paragraph need to update - if (!isPlaceholder && - (textLineHeightUtilParagraph_ && !layoutProperty->GetPreferredTextLineHeightNeedToUpdateValue(true))) { - return static_cast(textLineHeightUtilParagraph_->GetHeight()); - - } else if (isPlaceholder && (placeholderLineHeightUtilParagraph_ && - !layoutProperty->GetPreferredPlaceholderLineHeightNeedToUpdateValue(true))) { - return static_cast(placeholderLineHeightUtilParagraph_->GetHeight()); - } - auto pipeline = tmpHost->GetContext(); + auto pipeline = GetHost()->GetContext(); CHECK_NULL_RETURN(pipeline, 0.0f); auto themeManager = pipeline->GetThemeManager(); CHECK_NULL_RETURN(themeManager, 0.0f); auto textFieldTheme = themeManager->GetTheme(); CHECK_NULL_RETURN(textFieldTheme, 0.0f); - std::string textContent; - TextStyle textStyle; // use text or placeHolder value if exists, space otherwise if (!isPlaceholder) { TextFieldLayoutAlgorithm::UpdateTextStyle(tmpHost, layoutProperty, textFieldTheme, textStyle, false); @@ -4110,92 +2679,42 @@ float TextFieldPattern::PreferredTextHeight(bool isPlaceholder) } if (textStyle.GetFontSize().IsNonPositive()) { textStyle.SetFontSize(DEFAULT_FONT); - } - RSParagraphStyle paraStyle; -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.textDirection_ = ToRSTextDirection(TextFieldLayoutAlgorithm::GetTextDirection(textEditingValue_.text)); - paraStyle.textAlign_ = ToRSTextAlign(textStyle.GetTextAlign()); - paraStyle.maxLines_ = textStyle.GetMaxLines(); - paraStyle.locale_ = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType_ = ToRSWordBreakType(textStyle.GetWordBreak()); - paraStyle.fontSize_ = textStyle.GetFontSize().ConvertToPx(); - if (LessOrEqual(paraStyle.fontSize_, 0.0f)) { - paraStyle.fontSize_ = DEFAULT_FONT.ConvertToPx(); -#else - paraStyle.textDirection = ToRSTextDirection(TextFieldLayoutAlgorithm::GetTextDirection(textEditingValue_.text)); - paraStyle.textAlign = ToRSTextAlign(textStyle.GetTextAlign()); - paraStyle.maxLines = textStyle.GetMaxLines(); - paraStyle.locale = Localization::GetInstance()->GetFontLocale(); - paraStyle.wordBreakType = ToRSWordBreakType(textStyle.GetWordBreak()); - paraStyle.fontSize = textStyle.GetFontSize().ConvertToPx(); - if (LessOrEqual(paraStyle.fontSize, 0.0f)) { - paraStyle.fontSize = DEFAULT_FONT.ConvertToPx(); -#endif - } - if (textStyle.GetTextOverflow() == TextOverflow::ELLIPSIS) { -#ifndef USE_GRAPHIC_TEXT_GINE - paraStyle.ellipsis_ = RSParagraphStyle::ELLIPSIS; -#else - paraStyle.ellipsis = RSParagraphStyle::ELLIPSIS; -#endif - } -#ifndef USE_GRAPHIC_TEXT_GINE - auto builder = RSParagraphBuilder::CreateRosenBuilder(paraStyle, RSFontCollection::GetInstance(false)); -#else - auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create()); -#endif - builder->PushStyle(ToRSTextStyle(PipelineContext::GetCurrentContext(), textStyle)); - StringUtils::TransformStrCase(textEditingValue_.text, static_cast(textStyle.GetTextCase())); -#ifndef USE_GRAPHIC_TEXT_GINE - builder->AddText(StringUtils::Str8ToStr16(textContent)); - builder->Pop(); -#else - builder->AppendText(StringUtils::Str8ToStr16(textContent)); - builder->PopStyle(); -#endif - if (!isPlaceholder) { -#ifndef USE_GRAPHIC_TEXT_GINE - textLineHeightUtilParagraph_ = builder->Build(); -#else - textLineHeightUtilParagraph_ = builder->CreateTypography(); -#endif - textLineHeightUtilParagraph_->Layout(std::numeric_limits::infinity()); - layoutProperty->UpdatePreferredTextLineHeightNeedToUpdate(false); - return static_cast(textLineHeightUtilParagraph_->GetHeight()); - } -#ifndef USE_GRAPHIC_TEXT_GINE - placeholderLineHeightUtilParagraph_ = builder->Build(); -#else - placeholderLineHeightUtilParagraph_ = builder->CreateTypography(); -#endif - placeholderLineHeightUtilParagraph_->Layout(std::numeric_limits::infinity()); - layoutProperty->UpdatePreferredPlaceholderLineHeightNeedToUpdate(false); - return static_cast(placeholderLineHeightUtilParagraph_->GetHeight()); + } + ParagraphStyle paraStyle { .direction = + TextFieldLayoutAlgorithm::GetTextDirection(contentController_->GetTextValue()), + .align = textStyle.GetTextAlign(), + .maxLines = textStyle.GetMaxLines(), + .fontLocale = Localization::GetInstance()->GetFontLocale(), + .wordBreak = textStyle.GetWordBreak(), + .textOverflow = textStyle.GetTextOverflow(), + .fontSize = textStyle.GetFontSize().ConvertToPx() }; + paragraph = Paragraph::Create(paraStyle, FontCollection::Current()); + CHECK_NULL_RETURN(paragraph, 0.0f); + paragraph->AddText(StringUtils::Str8ToStr16(textContent)); + paragraph->Build(); + paragraph->Layout(std::numeric_limits::infinity()); + return paragraph->GetHeight(); } float TextFieldPattern::PreferredLineHeight() { - return PreferredTextHeight(textEditingValue_.text.empty()); + return PreferredTextHeight(contentController_->IsEmpty()); } void TextFieldPattern::OnCursorMoveDone() { CloseSelectOverlay(); - caretUpdateType_ = CaretUpdateType::EVENT; selectionMode_ = SelectionMode::NONE; - UpdateSelection(textEditingValue_.caretPosition); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + selectController_->MoveCaretToContentRect(GetCaretIndex()); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } int32_t TextFieldPattern::GetWordLength(int32_t originCaretPosition, int32_t directionMove) { - if (textEditingValue_.text.empty()) { + if (contentController_->IsEmpty()) { return 0; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + int32_t textLength = static_cast(contentController_->GetWideText().length()); if (originCaretPosition < 0 || originCaretPosition > textLength) { LOGD("Get word length failed, the origin caret position is out of range"); return 0; @@ -4207,7 +2726,7 @@ int32_t TextFieldPattern::GetWordLength(int32_t originCaretPosition, int32_t dir } int32_t offset = 0; int32_t strIndex = 0; - auto wideTextValue = textEditingValue_.GetWideText(); + auto wideTextValue = contentController_->GetWideText(); for (directionMove == 0 ? strIndex = (originCaretPosition - 1) : strIndex = originCaretPosition; directionMove == 0 ? strIndex >= 0 : strIndex <= textLength;) { if ((wideTextValue[strIndex] >= L'0' && wideTextValue[strIndex] <= L'9') || @@ -4232,10 +2751,11 @@ int32_t TextFieldPattern::GetWordLength(int32_t originCaretPosition, int32_t dir int32_t TextFieldPattern::GetLineBeginPosition(int32_t originCaretPosition, bool needToCheckLineChanged) { - if (textEditingValue_.text.empty()) { + if (contentController_->IsEmpty()) { return 0; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + auto wideTextValue = contentController_->GetWideText(); + int32_t textLength = static_cast(wideTextValue.length()); if (originCaretPosition < 0 || originCaretPosition > textLength) { LOGD("Get begin position failed, the origin caret position is out of range"); return 0; @@ -4245,7 +2765,6 @@ int32_t TextFieldPattern::GetLineBeginPosition(int32_t originCaretPosition, bool } int32_t moveLineBeginOffset = 0; int32_t strIndex = originCaretPosition; - auto wideTextValue = textEditingValue_.GetWideText(); do { moveLineBeginOffset++; strIndex--; @@ -4266,10 +2785,11 @@ int32_t TextFieldPattern::GetLineBeginPosition(int32_t originCaretPosition, bool int32_t TextFieldPattern::GetLineEndPosition(int32_t originCaretPosition, bool needToCheckLineChanged) { - if (textEditingValue_.text.empty()) { + if (contentController_->IsEmpty()) { return 0; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + auto wideTextValue = contentController_->GetWideText(); + int32_t textLength = static_cast(wideTextValue.length()); if (originCaretPosition < 0 || originCaretPosition > textLength) { LOGD("Get line end position failed, the origin caret position is out of range"); return originCaretPosition; @@ -4279,7 +2799,6 @@ int32_t TextFieldPattern::GetLineEndPosition(int32_t originCaretPosition, bool n } int32_t moveLineEndOffset = 0; int32_t strIndex = 0; - auto wideTextValue = textEditingValue_.GetWideText(); for (strIndex = originCaretPosition + 1; (strIndex <= textLength && wideTextValue[strIndex] != L'\n') || (needToCheckLineChanged && !CharLineChanged(strIndex)); strIndex++) { @@ -4293,74 +2812,72 @@ int32_t TextFieldPattern::GetLineEndPosition(int32_t originCaretPosition, bool n bool TextFieldPattern::CharLineChanged(int32_t caretPosition) { - if (caretPosition < 0 || caretPosition > static_cast(textEditingValue_.GetWideText().length())) { + if (caretPosition < 0 || caretPosition > static_cast(contentController_->GetWideText().length())) { return true; } - auto caretMetrics = CalcCursorOffsetByPosition(caretPosition); - return !NearEqual(caretMetrics.offset.GetY(), caretRect_.GetY()); + CaretMetricsF caretMetrics; + CalcCaretMetricsByPosition(selectController_->GetStartIndex(), caretMetrics); + return !NearEqual(caretMetrics.offset.GetY(), selectController_->GetCaretRect().GetY()); } bool TextFieldPattern::CursorMoveLeft() { LOGI("Handle cursor move left"); ResetObscureTickCountDown(); - auto originCaretPosition = textEditingValue_.caretPosition; - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = 0; - } else if (IsSelected()) { - textBoxes_.clear(); + auto originCaretPosition = selectController_->GetCaretIndex(); + if (IsSelected()) { + selectController_->UpdateCaretIndex( + selectController_->GetEndIndex() - GetGraphemeClusterLength(contentController_->GetWideText(), + selectController_->GetSecondHandleIndex(), true)); + CloseSelectOverlay(); } else { UpdateCaretPositionWithClamp( - textEditingValue_.caretPosition - - GetGraphemeClusterLength(textEditingValue_.GetWideText(), textEditingValue_.caretPosition, true)); + selectController_->GetCaretIndex() - + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetCaretIndex(), true)); } OnCursorMoveDone(); - if (originCaretPosition == textEditingValue_.caretPosition) { - return false; - } - return true; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveLeftWord() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot move to left"); return true; } - int32_t originCaretPosition = textEditingValue_.caretPosition; - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + int32_t originCaretPosition = selectController_->GetCaretIndex(); + int32_t textLength = static_cast(contentController_->GetWideText().length()); int32_t leftWordLength = GetWordLength(originCaretPosition, 0); - if (leftWordLength < 0 || leftWordLength > textLength || textEditingValue_.caretPosition - leftWordLength < 0) { + if (leftWordLength < 0 || leftWordLength > textLength || selectController_->GetCaretIndex() - leftWordLength < 0) { LOGD("Get left word length faild, the left word offset is out of range"); return false; } - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = 0; - } else if (IsSelected()) { - textBoxes_.clear(); + if (IsSelected()) { + selectController_->UpdateCaretIndex(selectController_->GetSecondHandleIndex() - leftWordLength); + CloseSelectOverlay(); } else { UpdateCaretPositionWithClamp(originCaretPosition - leftWordLength); } ResetObscureTickCountDown(); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveLineBegin() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot move to left"); return true; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); - int32_t originCaretPosition = textEditingValue_.caretPosition; + int32_t textLength = static_cast(contentController_->GetWideText().length()); + int32_t originCaretPosition = selectController_->GetCaretIndex(); int32_t lineBeginPosition = GetLineBeginPosition(originCaretPosition); if (lineBeginPosition < 0 || lineBeginPosition > textLength) { LOGD("Cursor move to line begin faild, the line begin offset is out of range"); return false; } - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = 0; + if (selectController_->IsSelectedAll()) { + selectController_->UpdateCaretIndex(0); } else if (IsTextArea()) { UpdateCaretPositionWithClamp(lineBeginPosition); } else { @@ -4368,94 +2885,90 @@ bool TextFieldPattern::CursorMoveLineBegin() } ResetObscureTickCountDown(); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveToParagraphBegin() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot move to left"); return true; } - auto originCaretPosition = textEditingValue_.caretPosition; + auto originCaretPosition = selectController_->GetCaretIndex(); UpdateCaretPositionWithClamp(GetLineBeginPosition(originCaretPosition, false)); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveHome() { // ctrl + home, caret move to position 0 - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot move to left"); return true; } - int32_t originCaretPosition = textEditingValue_.caretPosition; + int32_t originCaretPosition = selectController_->GetCaretIndex(); UpdateCaretPositionWithClamp(0); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveRight() { LOGI("Handle cursor move right"); ResetObscureTickCountDown(); - auto originCaretPosition = textEditingValue_.caretPosition; - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = static_cast(textEditingValue_.GetWideText().length()); - } else if (IsSelected()) { - textBoxes_.clear(); + auto originCaretPosition = selectController_->GetCaretIndex(); + if (IsSelected()) { + CloseSelectOverlay(); + selectController_->UpdateCaretIndex(selectController_->GetEndIndex() + 1); } else { UpdateCaretPositionWithClamp( - textEditingValue_.caretPosition + - GetGraphemeClusterLength(textEditingValue_.GetWideText(), textEditingValue_.caretPosition)); + selectController_->GetCaretIndex() + + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetCaretIndex())); } OnCursorMoveDone(); - if (originCaretPosition == textEditingValue_.caretPosition) { - return false; - } - return true; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveRightWord() { - if (textEditingValue_.caretPosition == static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() == static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end, cannot move to right"); return true; } - int32_t originCaretPosition = textEditingValue_.caretPosition; - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + int32_t originCaretPosition = selectController_->GetCaretIndex(); + int32_t textLength = static_cast(contentController_->GetWideText().length()); int32_t rightWordLength = GetWordLength(originCaretPosition, 1); if (rightWordLength < 0 || rightWordLength > textLength || - rightWordLength + textEditingValue_.caretPosition > textLength) { + rightWordLength + selectController_->GetCaretIndex() > textLength) { LOGD("Get right word length failed, the right word offset is out of range"); return false; } - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = textLength; + if (selectController_->IsSelectedAll()) { + selectController_->UpdateCaretIndex(textLength); } else { UpdateCaretPositionWithClamp(originCaretPosition + rightWordLength); } ResetObscureTickCountDown(); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveLineEnd() { - if (textEditingValue_.caretPosition == static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() == static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end, cannot move to right"); return true; } - int32_t originCaretPosition = textEditingValue_.caretPosition; - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + int32_t originCaretPosition = selectController_->GetCaretIndex(); + int32_t textLength = static_cast(contentController_->GetWideText().length()); int32_t lineEndPosition = GetLineEndPosition(originCaretPosition); if (lineEndPosition < 0 || lineEndPosition > textLength) { LOGD("Handle cursor move to line end failed, the line end position is out of range"); return false; } - if (IsSelected() && selectionMode_ == SelectionMode::SELECT_ALL) { - textEditingValue_.caretPosition = textLength; + if (selectController_->IsSelectedAll()) { + selectController_->UpdateCaretIndex(textLength); } else if (IsTextArea()) { UpdateCaretPositionWithClamp(lineEndPosition); } else { @@ -4463,93 +2976,73 @@ bool TextFieldPattern::CursorMoveLineEnd() } ResetObscureTickCountDown(); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveToParagraphEnd() { - if (textEditingValue_.caretPosition == static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() == static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end, cannot move to right"); return true; } - auto originCaretPosition = textEditingValue_.caretPosition; + auto originCaretPosition = selectController_->GetCaretIndex(); UpdateCaretPositionWithClamp(GetLineEndPosition(originCaretPosition, false)); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveEnd() { // ctrl end, caret to the very end - if (textEditingValue_.caretPosition == static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() == static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end, cannot move to right"); return true; } - int32_t originCaretPosition = textEditingValue_.caretPosition; - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); + int32_t originCaretPosition = selectController_->GetCaretIndex(); + int32_t textLength = static_cast(contentController_->GetWideText().length()); UpdateCaretPositionWithClamp(textLength); OnCursorMoveDone(); - return originCaretPosition != textEditingValue_.caretPosition; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveUp() { LOGI("Handle cursor move up"); CHECK_NULL_RETURN(IsTextArea(), false); - auto originCaretPosition = textEditingValue_.caretPosition; - auto offsetX = caretRect_.GetX() - contentRect_.GetX(); - auto offsetY = caretRect_.GetY() - textRect_.GetY(); + auto originCaretPosition = selectController_->GetCaretIndex(); + auto offsetX = selectController_->GetCaretRect().GetX() - contentRect_.GetX(); + auto offsetY = selectController_->GetCaretRect().GetY() - textRect_.GetY(); // multiply by 0.5f to convert to the grapheme center point of the previous line. float verticalOffset = offsetY - PreferredLineHeight() * 0.5f; - textEditingValue_.caretPosition = static_cast( - -#ifndef USE_GRAPHIC_TEXT_GINE - paragraph_->GetGlyphPositionAtCoordinate(offsetX, verticalOffset).pos_); -#else - paragraph_->GetGlyphIndexByCoordinate(offsetX, verticalOffset).index); -#endif + selectController_->UpdateCaretIndex( + static_cast(paragraph_->GetGlyphIndexByCoordinate(Offset(offsetX, verticalOffset)))); OnCursorMoveDone(); - if (originCaretPosition == textEditingValue_.caretPosition) { - return false; - } - return true; + return originCaretPosition != selectController_->GetCaretIndex(); } bool TextFieldPattern::CursorMoveDown() { LOGI("Handle cursor move down"); CHECK_NULL_RETURN(IsTextArea(), false); - auto originCaretPosition = textEditingValue_.caretPosition; - auto offsetX = caretRect_.GetX() - contentRect_.GetX(); - auto offsetY = caretRect_.GetY() - textRect_.GetY(); + auto originCaretPosition = selectController_->GetCaretIndex(); + auto offsetX = selectController_->GetCaretRect().GetX() - contentRect_.GetX(); + auto offsetY = selectController_->GetCaretRect().GetY() - textRect_.GetY(); // multiply by 1.5f to convert to the grapheme center point of the next line. float verticalOffset = offsetY + PreferredLineHeight() * 1.5f; - textEditingValue_.caretPosition = static_cast( - -#ifndef USE_GRAPHIC_TEXT_GINE - paragraph_->GetGlyphPositionAtCoordinate(offsetX, verticalOffset).pos_); -#else - paragraph_->GetGlyphIndexByCoordinate(offsetX, verticalOffset).index); -#endif + selectController_->UpdateCaretIndex( + static_cast(paragraph_->GetGlyphIndexByCoordinate(Offset(offsetX, verticalOffset)))); OnCursorMoveDone(); - if (originCaretPosition == textEditingValue_.caretPosition) { - return false; - } - return true; + return originCaretPosition != selectController_->GetCaretIndex(); } void TextFieldPattern::Delete(int32_t start, int32_t end) { SwapIfLarger(start, end); LOGI("Handle Delete within [%{public}d, %{public}d]", start, end); - textEditingValue_.text = - textEditingValue_.GetValueBeforePosition(start) + textEditingValue_.GetValueAfterPosition(end); - UpdateCaretPositionWithClamp(start); - SetEditingValueToProperty(textEditingValue_.text); - FireEventHubOnChange(GetEditingValue().text); - selectionMode_ = SelectionMode::NONE; - caretUpdateType_ = CaretUpdateType::DEL; - CloseSelectOverlay(); + contentController_->erase(start, end - start); + selectController_->UpdateCaretIndex(start); + FireOnTextChangeEvent(); + CloseSelectOverlay(true); StartTwinkling(); UpdateEditingValueToRecord(); auto tmpHost = GetHost(); @@ -4559,10 +3052,8 @@ void TextFieldPattern::Delete(int32_t start, int32_t end) if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } - // trigger repaint of select mask - ++drawOverlayFlag_; - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + GetHost()->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::SetEditingValueToProperty(const std::string& newValueText) @@ -4575,8 +3066,7 @@ void TextFieldPattern::SetEditingValueToProperty(const std::string& newValueText layoutProperty->UpdateValue(newValueText); if (textCache != newValueText) { layoutProperty->UpdateNeedFireOnChange(true); - caretUpdateType_ = CaretUpdateType::INPUT; - host->OnAccessibilityEvent(AccessibilityEventType::TEXT_CHANGE, textCache, newValueText.c_str()); + host->OnAccessibilityEvent(AccessibilityEventType::TEXT_CHANGE, textCache, newValueText); } else { layoutProperty->UpdateNeedFireOnChange(false); } @@ -4584,8 +3074,9 @@ void TextFieldPattern::SetEditingValueToProperty(const std::string& newValueText void TextFieldPattern::ClearEditingValue() { - textEditingValue_.Reset(); - SetEditingValueToProperty(""); + contentController_->Reset(); + selectController_->UpdateCaretIndex(0); + FireOnTextChangeEvent(); UpdateEditingValueToRecord(); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); @@ -4611,7 +3102,7 @@ void TextFieldPattern::HandleCounterBorder() auto textFieldTheme = themeManager->GetTheme(); CHECK_NULL_VOID(textFieldTheme); auto maxLength = GetMaxLength(); - auto currentLength = static_cast(textEditingValue_.GetWideText().length()); + auto currentLength = static_cast(contentController_->GetWideText().length()); BorderWidthProperty currentBorderWidth; if (layoutProperty->GetBorderWidthProperty() != nullptr) { currentBorderWidth = *(layoutProperty->GetBorderWidthProperty()); @@ -4655,16 +3146,6 @@ void TextFieldPattern::PerformAction(TextInputAction action, bool forceCloseKeyb auto host = GetHost(); CHECK_NULL_VOID(host); // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->UpdateSubmitEvent(textEditingValue_.text); - CloseKeyboard(forceCloseKeyboard); - FocusHub::LostFocusToViewRoot(); - return; - } - auto paintProperty = GetPaintProperty(); CHECK_NULL_VOID(paintProperty); auto eventHub = host->GetEventHub(); @@ -4690,32 +3171,15 @@ void TextFieldPattern::PerformAction(TextInputAction action, bool forceCloseKeyb void TextFieldPattern::UpdateEditingValue(const std::shared_ptr& value, bool needFireChangeEvent) { - textEditingValue_.text = value->text; - textEditingValue_.caretPosition = value->selection.baseOffset; + contentController_->SetTextValue(value->text); + selectController_->UpdateCaretIndex(value->selection.baseOffset); ContainerScope scope(GetInstanceId()); - SetEditingValueToProperty(textEditingValue_.text); UpdateEditingValueToRecord(); - caretUpdateType_ = CaretUpdateType::INPUT; - selectionMode_ = SelectionMode::NONE; CloseSelectOverlay(); StartTwinkling(); auto host = GetHost(); CHECK_NULL_VOID(host); - // If the parent node is a Search, the Search callback is executed. - if (IsSearchParentNode()) { - auto parentFrameNode = AceType::DynamicCast(host->GetParent()); - auto eventHub = parentFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->UpdateChangeEvent(textEditingValue_.text); - parentFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); - return; - } - - if (needFireChangeEvent) { - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnChange(textEditingValue_.text); - } + FireOnTextChangeEvent(); auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); @@ -4742,22 +3206,15 @@ void TextFieldPattern::OnAreaChangedInner() CHECK_NULL_VOID(host); auto context = PipelineContext::GetCurrentContext(); CHECK_NULL_VOID(context); - auto parentGlobalOffset = host->GetPaintRectOffset() - context->GetRootRect().GetOffset(); + auto parentGlobalOffset = GetTextPaintOffset(); if (parentGlobalOffset != parentGlobalOffset_) { parentGlobalOffset_ = parentGlobalOffset; UpdateTextFieldManager(Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()), frameRect_.Height()); - CHECK_NULL_VOID(SelectOverlayIsOn()); - textSelector_.selectionBaseOffset.SetX(CalcCursorOffsetByPosition(textSelector_.GetStart()).offset.GetX()); - textSelector_.selectionDestinationOffset.SetX( - CalcCursorOffsetByPosition(textSelector_.GetEnd(), false).offset.GetX()); - UpdateSelection(textSelector_.GetStart(), textSelector_.GetEnd()); - if (isSingleHandle_) { - CreateSingleHandle(); - RequestKeyboardOnFocus(); - return; + selectController_->UpdateCaretOffset(); + selectController_->CalculateHandleOffset(); + if (SelectOverlayIsOn()) { + ProcessOverlay(); } - ProcessOverlay(); - selectionMode_ = SelectionMode::SELECT; } RequestKeyboardOnFocus(); } @@ -4771,11 +3228,7 @@ void TextFieldPattern::RequestKeyboardOnFocus() if (!RequestKeyboard(false, true, true)) { return; } - StartTwinkling(); - LOGI("RequestKeyboardOnFocus ok, reset flag"); - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto eventHub = tmpHost->GetEventHub(); + auto eventHub = GetHost()->GetEventHub(); CHECK_NULL_VOID(eventHub); eventHub->FireOnEditChanged(true); needToRequestKeyboardInner_ = false; @@ -4786,7 +3239,6 @@ void TextFieldPattern::OnVisibleChange(bool isVisible) LOGI("visible change to %{public}d", isVisible); if (!isVisible) { LOGI("TextField is not visible"); - caretUpdateType_ = CaretUpdateType::INPUT; selectionMode_ = SelectionMode::NONE; CloseKeyboard(true); if (SelectOverlayIsOn()) { @@ -4802,13 +3254,10 @@ void TextFieldPattern::HandleSurfaceChanged(int32_t newWidth, int32_t newHeight, "height %{public}d", newWidth, newHeight, prevWidth, prevHeight); CloseSelectOverlay(); - if (HasFocus() && isSingleHandle_) { + if (HasFocus() && IsSingleHandle()) { StartTwinkling(); } - textRectWillChange_ = true; - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); UpdateCaretInfoToController(); } @@ -4858,24 +3307,18 @@ void TextFieldPattern::DeleteBackward(int32_t length) LOGI("Handle DeleteBackward %{public}d characters", length); if (IsSelected()) { ResetObscureTickCountDown(); - Delete(textSelector_.GetStart(), textSelector_.GetEnd()); + Delete(selectController_->GetStartIndex(), selectController_->GetEndIndex()); return; } - if (textEditingValue_.caretPosition <= 0) { + if (selectController_->GetCaretIndex() <= 0) { LOGW("Caret position at the beginning , cannot DeleteBackward"); return; } ResetObscureTickCountDown(); - auto start = std::max(textEditingValue_.caretPosition - length, 0); - auto end = - std::min(textEditingValue_.caretPosition, static_cast(textEditingValue_.GetWideText().length())); - textEditingValue_.text = - textEditingValue_.GetValueBeforePosition(start) + textEditingValue_.GetValueAfterPosition(end); - textEditingValue_.CursorMoveToPosition(textEditingValue_.caretPosition - length); - SetEditingValueToProperty(textEditingValue_.text); - FireEventHubOnChange(GetEditingValue().text); - selectionMode_ = SelectionMode::NONE; - caretUpdateType_ = CaretUpdateType::DEL; + auto start = std::max(selectController_->GetCaretIndex() - length, 0); + contentController_->erase(start, length); + selectController_->UpdateCaretIndex(start); + FireOnTextChangeEvent(); CloseSelectOverlay(); StartTwinkling(); UpdateEditingValueToRecord(); @@ -4895,20 +3338,17 @@ void TextFieldPattern::DeleteForward(int32_t length) LOGI("Handle DeleteForward %{public}d characters", length); if (IsSelected()) { ResetObscureTickCountDown(); - Delete(textSelector_.GetStart(), textSelector_.GetEnd()); + Delete(selectController_->GetStartIndex(), selectController_->GetEndIndex()); return; } - if (textEditingValue_.caretPosition >= static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() >= static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end , cannot DeleteForward"); return; } ResetObscureTickCountDown(); - textEditingValue_.text = textEditingValue_.GetValueBeforePosition(textEditingValue_.caretPosition) + - textEditingValue_.GetValueAfterPosition(textEditingValue_.caretPosition + length); - SetEditingValueToProperty(textEditingValue_.text); - FireEventHubOnChange(GetEditingValue().text); + contentController_->erase(selectController_->GetCaretIndex(), length); + FireOnTextChangeEvent(); selectionMode_ = SelectionMode::NONE; - caretUpdateType_ = CaretUpdateType::INPUT; CloseSelectOverlay(); StartTwinkling(); UpdateEditingValueToRecord(); @@ -4925,39 +3365,37 @@ void TextFieldPattern::DeleteForward(int32_t length) std::u16string TextFieldPattern::GetLeftTextOfCursor(int32_t number) { - auto start = textEditingValue_.caretPosition; + auto start = selectController_->GetCaretIndex(); if (IsSelected()) { - start = std::min(textSelector_.GetStart(), textSelector_.GetEnd()); + start = selectController_->GetStartIndex(); } - auto stringText = textEditingValue_.GetSelectedText(start - number, start); + auto stringText = contentController_->GetSelectedValue(start - number, start); return StringUtils::Str8ToStr16(stringText); } std::u16string TextFieldPattern::GetRightTextOfCursor(int32_t number) { - auto end = textEditingValue_.caretPosition; + auto end = selectController_->GetCaretIndex(); if (IsSelected()) { - end = std::max(textSelector_.GetStart(), textSelector_.GetEnd()); + end = selectController_->GetEndIndex(); } - auto stringText = textEditingValue_.GetSelectedText(end, end + number); + auto stringText = contentController_->GetSelectedValue(end, end + number); return StringUtils::Str8ToStr16(stringText); } int32_t TextFieldPattern::GetTextIndexAtCursor() { - return textEditingValue_.caretPosition; + return selectController_->GetCaretIndex(); } void TextFieldPattern::AfterSelection() { - LOGI("Selection %{public}s, caret position %{public}d", textSelector_.ToString().c_str(), - textEditingValue_.caretPosition); + LOGI("Selection %{public}s, caret position %{public}d", selectController_->ToString().c_str(), + selectController_->GetCaretIndex()); updateSelectionAfterObscure_ = ResetObscureTickCountDown(); - GetTextRectsInRange(textSelector_.GetStart(), textSelector_.GetEnd(), textBoxes_); - caretUpdateType_ = CaretUpdateType::EVENT; auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); + auto layoutProperty = GetHost()->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF : PROPERTY_UPDATE_MEASURE); @@ -4970,22 +3408,12 @@ void TextFieldPattern::HandleSelectionUp() LOGW("Unsupported operation for text field"); return; } - if (selectionMode_ != SelectionMode::SELECT) { - UpdateSelection(textEditingValue_.caretPosition); - } - auto newOffsetY = caretRect_.GetY() - PreferredLineHeight() * 0.5 - textRect_.GetY(); - textEditingValue_.caretPosition = - -#ifndef USE_GRAPHIC_TEXT_GINE - static_cast(paragraph_->GetGlyphPositionAtCoordinate(caretRect_.GetX(), newOffsetY).pos_); -#else - static_cast(paragraph_->GetGlyphIndexByCoordinate(caretRect_.GetX(), newOffsetY).index); -#endif - UpdateSelection(textSelector_.GetStart(), textEditingValue_.caretPosition); - selectionMode_ = SelectionMode::SELECT; - if (textSelector_.baseOffset == textSelector_.destinationOffset) { - selectionMode_ = SelectionMode::NONE; + if (!IsSelected()) { + UpdateSelection(selectController_->GetCaretIndex()); } + auto newOffsetY = selectController_->GetCaretRect().GetY() - PreferredLineHeight() * 0.5 - textRect_.GetY(); + selectController_->MoveSecondHandleToContentRect(static_cast( + paragraph_->GetGlyphIndexByCoordinate(Offset(selectController_->GetCaretRect().GetX(), newOffsetY)))); AfterSelection(); } @@ -4996,22 +3424,12 @@ void TextFieldPattern::HandleSelectionDown() LOGW("Unsupported operation for text field"); return; } - if (selectionMode_ != SelectionMode::SELECT) { - UpdateSelection(textEditingValue_.caretPosition); - } - auto newOffsetY = caretRect_.GetY() + PreferredLineHeight() * 1.5 - textRect_.GetY(); - textEditingValue_.caretPosition = - -#ifndef USE_GRAPHIC_TEXT_GINE - static_cast(paragraph_->GetGlyphPositionAtCoordinate(caretRect_.GetX(), newOffsetY).pos_); -#else - static_cast(paragraph_->GetGlyphIndexByCoordinate(caretRect_.GetX(), newOffsetY).index); -#endif - UpdateSelection(textSelector_.GetStart(), textEditingValue_.caretPosition); - selectionMode_ = SelectionMode::SELECT; - if (textSelector_.baseOffset == textSelector_.destinationOffset) { - selectionMode_ = SelectionMode::NONE; + if (!IsSelected()) { + UpdateSelection(selectController_->GetCaretIndex()); } + auto newOffsetY = selectController_->GetCaretRect().GetY() + PreferredLineHeight() * 1.5 - textRect_.GetY(); + selectController_->MoveSecondHandleToContentRect(static_cast( + paragraph_->GetGlyphIndexByCoordinate(Offset(selectController_->GetCaretRect().GetX(), newOffsetY)))); AfterSelection(); } @@ -5019,100 +3437,75 @@ void TextFieldPattern::HandleSelectionLeft() { LOGI("Handle selection left"); if (!IsSelected()) { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot update selection to left"); return; } - UpdateSelection(textEditingValue_.caretPosition, - std::max(textSelector_.baseOffset - - GetGraphemeClusterLength(GetEditingValue().GetWideText(), textSelector_.baseOffset, true), - 0)); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect( + selectController_->GetSecondHandleIndex() - + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetCaretIndex(), true)); } else { - textSelector_.destinationOffset = - std::max(textSelector_.destinationOffset - GetGraphemeClusterLength(GetEditingValue().GetWideText(), - textSelector_.destinationOffset, true), - 0); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect( + selectController_->GetSecondHandleIndex() - GetGraphemeClusterLength(contentController_->GetWideText(), + selectController_->GetSecondHandleIndex(), true)); } AfterSelection(); } void TextFieldPattern::HandleSelectionLeftWord() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot update selection to left"); return; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); - int32_t leftWordLength = GetWordLength(textEditingValue_.caretPosition, 0); - if (leftWordLength < 0 || leftWordLength > textLength || textEditingValue_.caretPosition - leftWordLength < 0) { + int32_t textLength = static_cast(contentController_->GetWideText().length()); + int32_t leftWordLength = GetWordLength(selectController_->GetCaretIndex(), 0); + if (leftWordLength < 0 || leftWordLength > textLength || selectController_->GetCaretIndex() - leftWordLength < 0) { LOGD("Handle select a left word failed, the left word offset is out of range"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = textEditingValue_.caretPosition - leftWordLength; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(selectController_->GetSecondHandleIndex() - leftWordLength); } else { - textSelector_.destinationOffset = textEditingValue_.caretPosition - leftWordLength; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(selectController_->GetSecondHandleIndex() - leftWordLength); } AfterSelection(); } void TextFieldPattern::HandleSelectionLineBegin() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex()) { LOGW("Caret position at beginning, cannot update selection to left"); return; } - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); - int32_t lineBeginPosition = GetLineBeginPosition(textEditingValue_.caretPosition); + int32_t textLength = static_cast(contentController_->GetWideText().length()); + int32_t lineBeginPosition = GetLineBeginPosition(selectController_->GetCaretIndex()); if (lineBeginPosition < 0 || lineBeginPosition > textLength) { LOGD("Handle select line begin failed, the line begin offset is out of range"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = lineBeginPosition; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(lineBeginPosition); } else { - textSelector_.destinationOffset = lineBeginPosition; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(lineBeginPosition); } AfterSelection(); } void TextFieldPattern::HandleSelectionHome() { - if (textEditingValue_.caretPosition == 0) { + if (selectController_->GetCaretIndex() == 0) { LOGW("Caret position at beginning, cannot update selection to left"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = 0; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(0); } else { - textSelector_.destinationOffset = 0; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(0); } AfterSelection(); } @@ -5122,81 +3515,62 @@ void TextFieldPattern::HandleSelectionRight() LOGI("Handle selection right"); // if currently not in select mode, reset baseOffset and move destinationOffset and caret position if (!IsSelected()) { - if (textEditingValue_.caretPosition == static_cast(textEditingValue_.GetWideText().length())) { + if (selectController_->GetCaretIndex() == static_cast(contentController_->GetWideText().length())) { LOGW("Caret position at the end, cannot update selection to right"); return; } - UpdateSelection(textEditingValue_.caretPosition, - std::min(textSelector_.baseOffset + - GetGraphemeClusterLength(GetEditingValue().GetWideText(), textSelector_.baseOffset), - static_cast(textEditingValue_.GetWideText().length()))); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect( + selectController_->GetSecondHandleIndex() + + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetSecondHandleIndex())); } else { // if currently not in select mode, move destinationOffset and caret position only - textSelector_.destinationOffset = - std::min(textSelector_.destinationOffset + - GetGraphemeClusterLength(GetEditingValue().GetWideText(), textSelector_.destinationOffset), - static_cast(textEditingValue_.GetWideText().length())); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect( + selectController_->GetSecondHandleIndex() + + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetSecondHandleIndex())); } AfterSelection(); } void TextFieldPattern::HandleSelectionRightWord() { - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); - if (textEditingValue_.caretPosition == textLength) { + int32_t textLength = static_cast(contentController_->GetWideText().length()); + if (selectController_->GetCaretIndex() == textLength) { LOGW("Caret position at the end, cannot update selection to right"); return; } - int32_t rightWordLength = GetWordLength(textEditingValue_.caretPosition, 1); + int32_t rightWordLength = GetWordLength(selectController_->GetCaretIndex(), 1); if (rightWordLength < 0 || rightWordLength > textLength || - rightWordLength + textEditingValue_.caretPosition > textLength) { + rightWordLength + selectController_->GetCaretIndex() > textLength) { LOGD("Handle select a right word failed, the right word offset is out of range"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = textEditingValue_.caretPosition + rightWordLength; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(selectController_->GetSecondHandleIndex() + rightWordLength); } else { - textSelector_.destinationOffset = textEditingValue_.caretPosition + rightWordLength; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(selectController_->GetSecondHandleIndex() + rightWordLength); + AfterSelection(); } - AfterSelection(); } void TextFieldPattern::HandleSelectionLineEnd() { - int32_t textLength = static_cast(textEditingValue_.GetWideText().length()); - if (textEditingValue_.caretPosition == textLength) { + int32_t textLength = static_cast(contentController_->GetWideText().length()); + if (selectController_->GetCaretIndex() == textLength) { LOGW("Caret position at the end, cannot update selection to right"); return; } - int32_t lineEndPosition = GetLineEndPosition(textEditingValue_.caretPosition); + int32_t lineEndPosition = GetLineEndPosition(selectController_->GetCaretIndex()); if (lineEndPosition < 0 || lineEndPosition > textLength) { LOGD("Handle select a line end failed, the line end offset is out of range"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = lineEndPosition; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(lineEndPosition); } else { - textSelector_.destinationOffset = lineEndPosition; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(lineEndPosition); } AfterSelection(); } @@ -5204,22 +3578,16 @@ void TextFieldPattern::HandleSelectionLineEnd() void TextFieldPattern::HandleSelectionEnd() { // shift end, select to the end of current line - int32_t endPos = static_cast(textEditingValue_.GetWideText().length()); - if (textEditingValue_.caretPosition == endPos) { + int32_t endPos = static_cast(contentController_->GetWideText().length()); + if (selectController_->GetCaretIndex() == endPos) { LOGW("Caret position at the end, cannot update selection to right"); return; } if (!IsSelected()) { - textSelector_.destinationOffset = endPos; - UpdateSelection(textEditingValue_.caretPosition, textSelector_.destinationOffset); - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - selectionMode_ = SelectionMode::SELECT; + UpdateSelection(selectController_->GetCaretIndex()); + selectController_->MoveSecondHandleToContentRect(endPos); } else { - textSelector_.destinationOffset = endPos; - UpdateCaretPositionWithClamp(textSelector_.destinationOffset); - if (textSelector_.destinationOffset == textSelector_.baseOffset) { - selectionMode_ = SelectionMode::NONE; - } + selectController_->MoveSecondHandleToContentRect(endPos); } AfterSelection(); } @@ -5227,82 +3595,25 @@ void TextFieldPattern::HandleSelectionEnd() void TextFieldPattern::SetCaretPosition(int32_t position) { LOGI("Set caret position to %{public}d", position); - textEditingValue_.caretPosition = - std::clamp(position, 0, static_cast(textEditingValue_.GetWideText().length())); - selectionMode_ = SelectionMode::NONE; - caretUpdateType_ = CaretUpdateType::EVENT; + selectController_->UpdateCaretIndex(position); CloseSelectOverlay(); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } -void TextFieldPattern::SetTextSelection(int32_t selectionStart, int32_t selectionEnd) -{ - selectionStart = selectionStart < 0 ? 0 : selectionStart; - selectionEnd = std::clamp(selectionEnd, 0, static_cast(textEditingValue_.GetWideText().length())); - if (selectionStart > selectionEnd) { - selectionStart = selectionEnd; - } - auto instanceId = GetInstanceId(); - ContainerScope scope(instanceId); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(context); - auto taskExecutor = context->GetTaskExecutor(); - CHECK_NULL_VOID(taskExecutor); - auto task = [weak = WeakClaim(this), selectionStart, selectionEnd] { - auto client = AceType::DynamicCast(weak.Upgrade()); - if (!client) { - LOGE("text field is null"); - return; - } - ContainerScope scope(client->GetInstanceId()); - client->HandleSetSelection(selectionStart, selectionEnd, false); - if (selectionStart == selectionEnd) { - client->SetInSelectMode(SelectionMode::NONE); - client->StartTwinkling(); - } else { - client->SetInSelectMode(SelectionMode::SELECT); - client->StopTwinkling(); - } - client->isUsingMouse_ = false; - client->SetCaretUpdateType(CaretUpdateType::EVENT); - client->CloseSelectOverlay(); - client->MarkRedrawOverlay(); - if (client->RequestKeyboard(false, true, true)) { - auto textFieldFrameNode = client->GetHost(); - CHECK_NULL_VOID(textFieldFrameNode); - auto eventHub = textFieldFrameNode->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); - } - }; - taskExecutor->PostTask(task, TaskExecutor::TaskType::UI); -} - void TextFieldPattern::SetSelectionFlag(int32_t selectionStart, int32_t selectionEnd) { if (!HasFocus()) { return; } cursorVisible_ = false; - MarkRedrawOverlay(); - SetTextSelection(selectionStart, selectionEnd); + HandleSetSelection(selectionStart, selectionEnd, true); auto host = GetHost(); CHECK_NULL_VOID(host); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); } -void TextFieldPattern::CaretMoveToLastNewLineChar() -{ - while (textEditingValue_.caretPosition > 0) { - textEditingValue_.caretPosition -= 1; - if (textEditingValue_.text.substr(textEditingValue_.caretPosition, 1) == "\n") { - break; - } - } -} - bool TextFieldPattern::OnBackPressed() { auto tmpHost = GetHost(); @@ -5583,18 +3894,9 @@ bool TextFieldPattern::GetErrorTextState() const return layoutProperty->GetShowErrorTextValue(false); } -bool TextFieldPattern::IsSearchParentNode() const -{ - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, false); - auto parentFrameNode = AceType::DynamicCast(tmpHost->GetParent()); - return parentFrameNode && parentFrameNode->GetTag() == V2::SEARCH_ETS_TAG; -} - void TextFieldPattern::SearchRequestKeyboard() { StartTwinkling(); - caretUpdateType_ = CaretUpdateType::PRESSED; selectionMode_ = SelectionMode::NONE; if (RequestKeyboard(false, true, true)) { auto tmpHost = GetHost(); @@ -5649,7 +3951,7 @@ std::string TextFieldPattern::GetBarStateString() const void TextFieldPattern::UpdateScrollBarOffset() { - if (textEditingValue_.text.empty()) { + if (contentController_->IsEmpty()) { return; } if (!GetScrollBar() && !GetScrollBarProxy()) { @@ -5678,13 +3980,7 @@ bool TextFieldPattern::OnScrollCallback(float offset, int32_t source) if (scrollBar) { scrollBar->PlayScrollBarAppearAnimation(); } - auto selectOverlayProxy = GetSelectOverlay(); - if (selectOverlayProxy) { - if (selectOverlayProxy->IsHandleShow()) { - originalIsMenuShow_ = selectOverlayProxy->IsMenuShow(); - } - selectOverlayProxy->ShowOrHiddenMenu(true); - } + UpdateSelectMenuVisibility(false); return true; } if (IsReachedBoundary(offset)) { @@ -5706,15 +4002,10 @@ void TextFieldPattern::CheckScrollable() auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (textEditingValue_.text.empty()) { + if (contentController_->IsEmpty()) { scrollable_ = false; } else { - if (layoutProperty->GetShowCounterValue(false) && counterParagraph_ && !isCounterIdealheight_ && - !IsNormalInlineState()) { - scrollable_ = GreatNotEqual(textRect_.Height(), contentRect_.Height() - counterParagraph_->GetHeight()); - } else { - scrollable_ = GreatNotEqual(textRect_.Height(), contentRect_.Height()); - } + scrollable_ = GreatNotEqual(textRect_.Height(), contentRect_.Height()); } SetScrollEnable(scrollable_); } @@ -5743,12 +4034,34 @@ void TextFieldPattern::SetUnitNode(const RefPtr& unitNode) auto host = GetHost(); CHECK_NULL_VOID(host); CHECK_NULL_VOID(unitNode); - if (host->GetChildren().size() != 0) { + if (!host->GetChildren().empty()) { host->Clean(); } unitNode->MountToParent(host); } +void TextFieldPattern::AddCounterNode() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + if (!host->GetChildren().empty()) { + host->Clean(); + } + auto counterTextNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, + ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr(); }); + counterTextNode->MountToParent(host); + counterTextNode->MarkModifyDone(); + counterTextNode->MarkDirtyNode(); +} + +void TextFieldPattern::ClearCounterNode() +{ + auto host = GetHost(); + if (!host->GetChildren().empty()) { + host->Clean(); + } +} + void TextFieldPattern::SetShowError() { auto layoutProperty = GetLayoutProperty(); @@ -5936,7 +4249,7 @@ float TextFieldPattern::GetMarginBottom() const CHECK_NULL_RETURN(tmpHost, 0.0f); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, 0.0f); - auto& getMargin = layoutProperty->GetMarginProperty(); + const auto& getMargin = layoutProperty->GetMarginProperty(); if (getMargin && getMargin->bottom.has_value()) { return getMargin->bottom->GetDimension().ConvertToPx(); } @@ -5949,8 +4262,9 @@ std::string TextFieldPattern::GetShowResultImageSrc() const CHECK_NULL_RETURN(tmpHost, ""); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, ""); - if (showUserDefinedIcon_) { - return showUserDefinedIconSrc_; + auto showImageSource = layoutProperty->GetShowPasswordSourceInfo(); + if (showImageSource) { + return showImageSource->GetSrc(); } return SHOW_PASSWORD_SVG; } @@ -5961,8 +4275,9 @@ std::string TextFieldPattern::GetHideResultImageSrc() const CHECK_NULL_RETURN(tmpHost, ""); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, ""); - if (hideUserDefinedIcon_) { - return hideUserDefinedIconSrc_; + auto hideSourceInfo = layoutProperty->GetHidePasswordSourceInfo(); + if (hideSourceInfo) { + return hideSourceInfo->GetSrc(); } return HIDE_PASSWORD_SVG; } @@ -6020,37 +4335,13 @@ void TextFieldPattern::SaveInlineStates() } } -void TextFieldPattern::TextIsEmptyRect(RectF& rect) -{ - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - if (GetEditingValue().text.empty()) { - switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { - case TextAlign::START: - break; - case TextAlign::CENTER: - rect.SetLeft(static_cast(rect.GetX()) + contentRect_.Width() / 2.0f); - break; - case TextAlign::END: - rect.SetLeft(static_cast(rect.GetX()) + contentRect_.Width() - - static_cast(CURSOR_WIDTH.ConvertToPx())); - break; - default: - break; - } - return; - } -} - void TextFieldPattern::TextAreaInputRectUpdate(RectF& rect) { auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (IsTextArea() && !GetEditingValue().text.empty()) { + if (IsTextArea() && !contentController_->IsEmpty()) { auto inputContentWidth = GetParagraph()->GetMaxIntrinsicWidth(); switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { case TextAlign::START: @@ -6078,6 +4369,11 @@ void TextFieldPattern::TextAreaInputRectUpdate(RectF& rect) } } +void TextFieldPattern::TextIsEmptyRect(RectF& rect) +{ + rect = selectController_->CalculateEmptyValueCaretRect(); +} + void TextFieldPattern::UpdateRectByAlignment(RectF& rect) { auto tmpHost = GetHost(); @@ -6137,26 +4433,6 @@ void TextFieldPattern::ApplyInlineStates(bool focusStatus) margin.left = CalcLength(inlineState_.padding.left->GetDimension() + inlineState_.margin.left->GetDimension()); margin.top = CalcLength(inlineState_.padding.top->GetDimension() + inlineState_.margin.top->GetDimension()); layoutProperty->UpdateMargin(margin); - CalcSize idealSize; - inlinePadding_ = padding.ConvertToPx() + padding.ConvertToPx(); - if (focusStatus) { -#ifndef USE_GRAPHIC_TEXT_GINE - previewWidth_ = paragraph_->GetLongestLine() + inlinePadding_; -#else - previewWidth_ = paragraph_->GetActualWidth() + inlinePadding_; -#endif - std::optional width(previewWidth_); - idealSize.SetWidth(width); - } else { - std::optional width(previewWidth_); - idealSize.SetWidth(width); - } - layoutProperty->UpdateUserDefinedIdealSize(idealSize); - auto&& layoutConstraint = layoutProperty->GetCalcLayoutConstraint(); - if (layoutConstraint && layoutConstraint->selfIdealSize && layoutConstraint->selfIdealSize->Height()) { - layoutProperty->ClearUserDefinedIdealSize(false, true); - inlineState_.setHeight = true; - } if (!IsTextArea()) { layoutProperty->ResetMaxLines(); } @@ -6205,14 +4481,6 @@ void TextFieldPattern::RestorePreInlineStates() textRect_.SetOffset(OffsetF(GetPaddingLeft(), GetPaddingTop())); } layoutProperty->UpdateMargin(inlineState_.margin); - CalcSize idealSize; - std::optional width(inlineState_.frameRect.Width()); - idealSize.SetWidth(width); - if (inlineState_.setHeight) { - std::optional height(inlineState_.frameRect.Height()); - idealSize.SetHeight(height); - } - layoutProperty->UpdateUserDefinedIdealSize(idealSize); renderContext->UpdateBackgroundColor(inlineState_.bgColor); layoutProperty->UpdateBorderWidth(inlineState_.borderWidth); renderContext->UpdateBorderWidth(inlineState_.borderWidth); @@ -6246,16 +4514,13 @@ bool TextFieldPattern::IsUnspecifiedOrTextType() const auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, false); auto inputType = layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED); - if (inputType == TextInputType::UNSPECIFIED || inputType == TextInputType::TEXT) { - return true; - } - return false; + return inputType == TextInputType::UNSPECIFIED || inputType == TextInputType::TEXT; } void TextFieldPattern::ToJsonValue(std::unique_ptr& json) const { json->Put("placeholder", GetPlaceHolder().c_str()); - json->Put("text", textEditingValue_.text.c_str()); + json->Put("text", contentController_->GetTextValue().c_str()); json->Put("fontSize", GetFontSize().c_str()); json->Put("fontColor", GetTextColor().c_str()); json->Put("fontStyle", GetItalicFontStyle() == Ace::FontStyle::NORMAL ? "FontStyle.Normal" : "FontStyle.Italic"); @@ -6287,8 +4552,8 @@ void TextFieldPattern::FromJson(const std::unique_ptr& json) auto layoutProperty = GetLayoutProperty(); layoutProperty->UpdatePlaceholder(json->GetString("placeholder")); UpdateEditingValue(json->GetString("text"), StringUtils::StringToInt(json->GetString("caretPosition"))); - SetEditingValueToProperty(textEditingValue_.text); - UpdateSelection(textEditingValue_.caretPosition); + FireOnTextChangeEvent(); + UpdateSelection(selectController_->GetCaretIndex()); auto maxLines = json->GetString("maxLines"); if (!maxLines.empty() && maxLines != "INF") { layoutProperty->UpdateMaxLines(StringUtils::StringToUint(maxLines)); @@ -6350,7 +4615,7 @@ void TextFieldPattern::SetAccessibilityAction() accessibilityProperty->SetActionClearSelection([weakPtr = WeakClaim(this)]() { const auto& pattern = weakPtr.Upgrade(); CHECK_NULL_VOID(pattern); - auto current = pattern->GetTextSelector().GetEnd(); + auto current = pattern->selectController_->GetEndIndex(); pattern->SetInSelectMode(SelectionMode::NONE); pattern->UpdateSelection(current); pattern->SetSelectionFlag(current, current); @@ -6372,19 +4637,18 @@ void TextFieldPattern::SetAccessibilityMoveTextAction() CHECK_NULL_VOID(pattern); auto host = pattern->GetHost(); CHECK_NULL_VOID(host); - if (pattern->GetEditingValue().GetWideText().empty()) { + if (pattern->contentController_->IsEmpty()) { return; } int range = 0; if (moveUnit == 1) { range = 1; } - auto caretPosition = forward ? pattern->textEditingValue_.caretPosition + range - : pattern->textEditingValue_.caretPosition - range; + auto caretPosition = forward ? pattern->selectController_->GetCaretIndex() + range + : pattern->selectController_->GetCaretIndex() - range; auto layoutProperty = host->GetLayoutProperty(); layoutProperty->UpdateCaretPosition(caretPosition); pattern->SetCaretPosition(caretPosition); - pattern->UpdateCaretPositionByTextEdit(); }); } @@ -6432,25 +4696,6 @@ void TextFieldPattern::SetAccessibilityScrollAction() }); } -void TextFieldPattern::CheckHandles(std::optional& firstHandle, std::optional& secondHandle, - float firstHandleSize, float secondHandleSize) -{ - auto firstHandleOffset = textSelector_.firstHandleOffset_ - parentGlobalOffset_; - if (!contentRect_.IsInRegion( - { firstHandleOffset.GetX(), firstHandleOffset.GetY() + BOX_EPSILON + firstHandleSize })) { - // hide firstHandle when it's out of content region - firstHandle = std::nullopt; - } - auto secondHandleOffset = textSelector_.secondHandleOffset_ - parentGlobalOffset_; - if (!contentRect_.IsInRegion( - { secondHandleOffset.GetX(), secondHandleOffset.GetY() + BOX_EPSILON + secondHandleSize })) { - // hide secondHandle when it's out of content region - secondHandle = std::nullopt; - } - LOGD("firstHandleOffset %{public}s, secondHandleOffset %{public}s contentRect: %{public}s", - firstHandleOffset.ToString().c_str(), secondHandleOffset.ToString().c_str(), contentRect_.ToString().c_str()); -} - void TextFieldPattern::StopEditing() { LOGI("TextFieldPattern: StopEditing"); @@ -6468,53 +4713,41 @@ void TextFieldPattern::StopEditing() CHECK_NULL_VOID(eventHub); eventHub->FireOnEditChanged(false); } - HandleSetSelection(textEditingValue_.caretPosition, textEditingValue_.caretPosition); + UpdateSelection(selectController_->GetCaretIndex()); StopTwinkling(); - MarkRedrawOverlay(); CloseSelectOverlay(); CloseKeyboard(true); } -#ifndef USE_GRAPHIC_TEXT_GINE -bool TextFieldPattern::LastTouchIsInSelectRegion(const std::vector& boxes) +bool TextFieldPattern::CheckHandleVisible(const RectF& paintRect) { - if (boxes.empty()) { - return false; - } - - Offset offset = GetLastTouchOffset() - Offset(textRect_.GetX(), textRect_.GetY()); - for (const auto& box : boxes) { - RectF rect(box.rect_.GetLeft(), box.rect_.GetTop(), box.rect_.GetWidth(), box.rect_.GetHeight()); - if (rect.IsInRegion({ offset.GetX(), offset.GetY() })) { - return true; - } - } - return false; + OffsetF offset(paintRect.GetX() - parentGlobalOffset_.GetX(), paintRect.GetY() - parentGlobalOffset_.GetY()); + return !(!contentRect_.IsInRegion({ offset.GetX(), offset.GetY() + paintRect.Height() - BOX_EPSILON }) || + !contentRect_.IsInRegion({ offset.GetX(), offset.GetY() + BOX_EPSILON })); } -#else -bool TextFieldPattern::LastTouchIsInSelectRegion(const std::vector& boxes) + +bool TextFieldPattern::CheckSelectionRectVisible() { - if (boxes.empty()) { + if (!selectController_->IsSelected()) { return false; } - - Offset offset = GetLastTouchOffset() - Offset(textRect_.GetX(), textRect_.GetY()); - for (const auto& box : boxes) { - RectF rect(box.rect.GetLeft(), box.rect.GetTop(), box.rect.GetWidth(), box.rect.GetHeight()); - if (rect.IsInRegion({ offset.GetX(), offset.GetY() })) { + std::vector selectedRects; + paragraph_->GetRectsForRange(selectController_->GetStartIndex(), selectController_->GetEndIndex(), selectedRects); + if (selectedRects.empty()) { + return false; + } + for (const auto& rect : selectedRects) { + auto left = rect.Left(); + auto top = rect.Top(); + SizeF boxSize = { rect.Width(), rect.Height() }; + auto boxOffset = OffsetF(left + (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()), + top + (IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) + BOX_EPSILON); + if (contentRect_.IsIntersectWith(RectF(boxOffset, boxSize))) { return true; } } return false; } -#endif - -bool TextFieldPattern::CheckHandleVisible(const RectF& paintRect) -{ - OffsetF offset(paintRect.GetX() - parentGlobalOffset_.GetX(), paintRect.GetY() - parentGlobalOffset_.GetY()); - return !(!contentRect_.IsInRegion({ offset.GetX(), offset.GetY() + paintRect.Height() - BOX_EPSILON }) || - !contentRect_.IsInRegion({ offset.GetX(), offset.GetY() + BOX_EPSILON })); -} void TextFieldPattern::SetTextRectOffset() { @@ -6530,23 +4763,7 @@ void TextFieldPattern::SetTextRectOffset() } } -void TextFieldPattern::FilterExistText() -{ - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - auto inputFilter = layoutProperty->GetInputFilter(); - auto inputType = layoutProperty->GetTextInputType(); - if ((inputFilter.has_value() || inputType.has_value()) && !textEditingValue_.text.empty()) { - std::string result; - auto textEditorValue = textEditingValue_.text; - EditingValueFilter(textEditorValue, result); - if (textEditingValue_.text != result) { - InitEditingValueText(result); - } - } -} - -void TextFieldPattern::DumpAdvanceInfo() +void TextFieldPattern::DumpInfo() { if (customKeyboardBulder_) { DumpLog::GetInstance().AddDesc(std::string("CustomKeyboard: true") @@ -6585,20 +4802,13 @@ bool TextFieldPattern::IsTouchAtLeftOffset(float currentOffsetX) OffsetF TextFieldPattern::GetDragUpperLeftCoordinates() { - if (textBoxes_.empty()) { + if (!IsSelected()) { return { 0.0f, 0.0f }; } -#ifndef USE_GRAPHIC_TEXT_GINE - auto startY = textBoxes_.front().rect_.GetTop(); - auto startX = textBoxes_.front().rect_.GetLeft(); - - auto endY = textBoxes_.back().rect_.GetTop(); -#else - auto startY = textBoxes_.front().rect.GetTop(); - auto startX = textBoxes_.front().rect.GetLeft(); - - auto endY = textBoxes_.back().rect.GetTop(); -#endif + auto selectRects = selectController_->GetSelectedRects(); + auto startY = selectRects.front().Top(); + auto startX = selectRects.front().Left(); + auto endY = selectRects.back().Top(); OffsetF startOffset; if (NearEqual(startY, endY)) { startOffset = { (IsTextArea() ? contentRect_.GetX() : textRect_.GetX()) + startX, @@ -6642,4 +4852,95 @@ bool TextFieldPattern::IsReachedBoundary(float offset) (NearEqual(textRect_.GetX() + textRect_.Width(), contentRect_.GetX() + contentRect_.Width()) && LessNotEqual(offset, 0.0f)); } + +OffsetF TextFieldPattern::GetTextPaintOffset() const +{ + auto host = GetHost(); + CHECK_NULL_RETURN(host, OffsetF(0.0f, 0.0f)); + auto pipeline = host->GetContext(); + CHECK_NULL_RETURN(pipeline, OffsetF(0.0f, 0.0f)); + auto rootOffset = pipeline->GetRootRect().GetOffset(); + auto textPaintOffset = host->GetPaintRectOffset(); + return textPaintOffset - rootOffset; +} + +void TextFieldPattern::UpdateSelectController() +{ + selectController_->UpdateContentRect(contentRect_); + selectController_->UpdateParagraph(paragraph_); + selectController_->UpdateCaretOffset(); +} + +bool TextFieldPattern::IsSingleHandle() const +{ + return contentController_->IsEmpty() || !selectController_->IsSelected(); +} + +void TextFieldPattern::OnAttachToFrameNode() +{ + auto onTextSelectorChange = [weak = WeakClaim(this)]() { + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto frameNode = pattern->GetHost(); + CHECK_NULL_VOID(frameNode); + frameNode->OnAccessibilityEvent(AccessibilityEventType::TEXT_SELECTION_UPDATE); + }; + selectController_->SetOnAccessibility(std::move(onTextSelectorChange)); +} + +bool TextFieldPattern::NeedPaintSelect() +{ + auto paintProperty = GetPaintProperty(); + CHECK_NULL_RETURN(paintProperty, false); + auto firstHandle = paintProperty->GetFirstHandleInfo(); + auto secondHandle = paintProperty->GetSecondHandleInfo(); + if (!selectController_->IsSelected()) { + if (!firstHandle.has_value() || !secondHandle.has_value()) { + paintProperty->UpdateFirstHandleInfo(selectController_->GetCaretInfo()); + paintProperty->UpdateSecondHandleInfo(selectController_->GetCaretInfo()); + return false; + } + + if (firstHandle->index != secondHandle->index) { + paintProperty->UpdateFirstHandleInfo(selectController_->GetCaretInfo()); + paintProperty->UpdateSecondHandleInfo(selectController_->GetCaretInfo()); + return true; + } + } + auto needPaint = firstHandle != selectController_->GetFirstHandleInfo() || + secondHandle != selectController_->GetSecondHandleInfo(); + paintProperty->UpdateFirstHandleInfo(selectController_->GetFirstHandleInfo()); + paintProperty->UpdateSecondHandleInfo(selectController_->GetSecondHandleInfo()); + return needPaint; +} + +RefPtr TextFieldPattern::GetFocusHub() const +{ + auto focusHub = GetHost()->GetOrCreateFocusHub(); + return focusHub; +} + +void TextFieldPattern::UpdateRecordCaretIndex(int32_t index) +{ + if (operationRecords_.empty()) { + LOGW("Operation records empty, cannot update position"); + return; + } + operationRecords_.back().caretPosition = index; +} + +void TextFieldPattern::OnObscuredChanged(bool isObscured) +{ + textObscured_ = isObscured; + auto host = GetHost(); + CHECK_NULL_VOID(host); + selectController_->UpdateCaretIndex(selectController_->GetSecondHandleIndex()); + StartTwinkling(); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); +} + +void TextFieldPattern::CreateHandles() +{ + ProcessOverlay(false, false); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 9342e0604e7..30d319fa447 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include "base/geometry/ng/offset_t.h" #include "base/geometry/ng/rect_t.h" #include "base/geometry/rect.h" +#include "base/memory/referenced.h" #include "base/mousestyle/mouse_style.h" #include "core/common/clipboard/clipboard.h" #include "core/common/ime/text_edit_controller.h" @@ -36,6 +38,7 @@ #include "core/common/ime/text_input_proxy.h" #include "core/common/ime/text_input_type.h" #include "core/common/ime/text_selection.h" +#include "core/components_ng/base/frame_node.h" #include "core/components_ng/image_provider/image_loading_context.h" #include "core/components_ng/pattern/pattern.h" #include "core/components_ng/pattern/scroll/inner/scroll_bar.h" @@ -43,16 +46,20 @@ #include "core/components_ng/pattern/scrollable/scrollable_pattern.h" #include "core/components_ng/pattern/text/text_base.h" #include "core/components_ng/pattern/text/text_menu_extension.h" +#include "core/components_ng/pattern/text_area/text_area_layout_algorithm.h" #include "core/components_ng/pattern/text_drag/text_drag_base.h" +#include "core/components_ng/pattern/text_field/content_controller.h" #include "core/components_ng/pattern/text_field/text_editing_value_ng.h" #include "core/components_ng/pattern/text_field/text_field_accessibility_property.h" #include "core/components_ng/pattern/text_field/text_field_controller.h" #include "core/components_ng/pattern/text_field/text_field_event_hub.h" -#include "core/components_ng/pattern/text_field/text_field_layout_algorithm.h" #include "core/components_ng/pattern/text_field/text_field_layout_property.h" #include "core/components_ng/pattern/text_field/text_field_paint_method.h" #include "core/components_ng/pattern/text_field/text_field_paint_property.h" +#include "core/components_ng/pattern/text_field/text_input_response_area.h" +#include "core/components_ng/pattern/text_field/text_select_controller.h" #include "core/components_ng/pattern/text_field/text_selector.h" +#include "core/components_ng/pattern/text_input/text_input_layout_algorithm.h" #include "core/components_ng/property/property.h" #include "core/gestures/gesture_info.h" @@ -82,6 +89,8 @@ enum class SelectionMode { SELECT, SELECT_ALL, NONE }; enum class DragStatus { DRAGGING, ON_DROP, NONE }; +enum class CaretStatus { SHOW, HIDE, NONE }; + enum { ACTION_SELECT_ALL, // Smallest code unit. ACTION_UNDO, @@ -96,26 +105,6 @@ enum { ACTION_AUTOFILL, }; -struct CaretMetricsF { - void Reset() - { - offset.Reset(); - height = 0.0; - } - - OffsetF offset; - // When caret is close to different glyphs, the height will be different. - float height = 0.0; - std::string ToString() const - { - std::string result = "Offset: "; - result += offset.ToString(); - result += ", height: "; - result += std::to_string(height); - return result; - } -}; - struct PasswordModeStyle { Color bgColor; Color textColor; @@ -183,11 +172,7 @@ public: auto frameSize = geometryNode->GetFrameSize(); if (layoutProperty->GetShowErrorTextValue(false) && errorParagraph_) { auto contentOffset = geometryNode->GetContentOffset(); -#ifndef USE_GRAPHIC_TEXT_GINE auto errorTextWidth = errorParagraph_->GetLongestLine(); -#else - auto errorTextWidth = errorParagraph_->GetActualWidth(); -#endif RectF boundsRect(contentOffset.GetX(), frameOffset.GetY(), errorTextWidth, frameSize.Height() + ERROR_TEXT_BOUNDSRECT_MARGIN); textFieldOverlayModifier->SetBoundsRect(boundsRect); @@ -197,7 +182,8 @@ public: maxFrameHeight_ = frameSize.Height(); } maxFrameOffsetY_ = LessOrEqual(frameOffset.GetY(), maxFrameOffsetY_) - ? frameOffset.GetY() : maxFrameOffsetY_ - frameOffset.GetY(); + ? frameOffset.GetY() + : maxFrameOffsetY_ - frameOffset.GetY(); maxFrameHeight_ = LessOrEqual(frameSize.Height(), maxFrameHeight_) ? maxFrameHeight_ : frameSize.Height(); RectF boundsRect(frameOffset.GetX(), maxFrameOffsetY_, frameSize.Width(), maxFrameHeight_); textFieldOverlayModifier->SetBoundsRect(boundsRect); @@ -227,7 +213,11 @@ public: RefPtr CreateLayoutAlgorithm() override { - return MakeRefPtr(); + if (IsTextArea()) { + return MakeRefPtr(); + } else { + return MakeRefPtr(); + } } void OnModifyDone() override; @@ -235,25 +225,16 @@ public: void UpdateCaretPositionByTextEdit(); void UpdateCaretPositionByPressOffset(); void UpdateSelectionOffset(); - - CaretMetricsF CalcCursorOffsetByPosition(int32_t position, bool isStart = true); - - bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result); - - bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result) const; - - uint32_t GetDrawOverlayFlag() const - { - return drawOverlayFlag_; - } - - OffsetF MakeEmptyOffset() const; - + void CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity = TextAffinity::DOWNSTREAM); int32_t ConvertTouchOffsetToCaretPosition(const Offset& localOffset); + int32_t ConvertTouchOffsetToCaretPositionNG(const Offset& localOffset); void InsertValue(const std::string& insertValue) override; void DeleteBackward(int32_t length) override; void DeleteForward(int32_t length) override; + void UpdateRecordCaretIndex(int32_t index); + void CreateHandles() override; float GetTextOrPlaceHolderFontSize(); @@ -273,6 +254,10 @@ public: } const TextEditingValueNG& GetEditingValue() const; + std::string GetTextValue() const + { + return contentController_->GetTextValue(); + } #if defined(IOS_PLATFORM) const TextEditingValue& GetInputEditingValue() const override @@ -286,19 +271,19 @@ public: bool GetEditingBoxModel() const override; #endif - void UpdateEditingValue(std::string value, int32_t caretPosition) + void UpdateEditingValue(const std::string& value, int32_t caretPosition) { - textEditingValue_.text = std::move(value); - textEditingValue_.caretPosition = caretPosition; + contentController_->SetTextValue(value); + selectController_->UpdateCaretIndex(caretPosition); } void SetEditingValueToProperty(const std::string& newValueText); - void UpdatePositionOfParagraph(int32_t pos); + // void UpdatePositionOfParagraph(int32_t pos); void UpdateCaretPositionByTouch(const Offset& offset); void UpdateCaretOffsetByEvent(); bool IsReachedBoundary(float offset); - TextInputAction GetDefaultTextInputAction(); + virtual TextInputAction GetDefaultTextInputAction(); bool RequestKeyboard(bool isFocusViewChanged, bool needStartTwinkling, bool needShowSoftKeyboard); bool CloseKeyboard(bool forceClose) override; @@ -317,25 +302,24 @@ public: void OnVisibleChange(bool isVisible) override; void ClearEditingValue(); void HandleCounterBorder(); - - ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(TextInputAction, TextInputAction) - - float GetBaseLineOffset() const + std::wstring GetWideText() { - return baselineOffset_; + return contentController_->GetWideText(); } - const std::shared_ptr& GetParagraph() const + int32_t GetCaretIndex() { - return paragraph_; + return selectController_->GetCaretIndex(); } - const std::shared_ptr& GetCounterParagraph() const + ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(TextInputAction, TextInputAction) + + const RefPtr& GetParagraph() const { - return counterParagraph_; + return paragraph_; } - const std::shared_ptr& GetErrorParagraph() const + const RefPtr& GetErrorParagraph() const { return errorParagraph_; } @@ -354,7 +338,7 @@ public: bool DisplayPlaceHolder(); - const Offset& GetLastTouchOffset() + const OffsetF& GetLastTouchOffset() { return lastTouchOffset_; } @@ -364,39 +348,14 @@ public: return rightClickOffset_; } - float GetSelectionBaseOffsetX() const - { - return textSelector_.selectionBaseOffset.GetX(); - } - - float GetSelectionDestinationOffsetX() const - { - return textSelector_.selectionDestinationOffset.GetX(); - } - OffsetF GetCaretOffset() const { - return OffsetF(caretRect_.GetX(), caretRect_.GetY()); + return selectController_->GetCaretRect().GetOffset(); } float GetCaretOffsetX() const { - return caretRect_.GetX(); - } - - void SetCaretOffsetX(float offsetX) - { - caretRect_.SetLeft(offsetX); - } - - const RefPtr& GetSelectOverlay() - { - return selectOverlayProxy_; - } - - void SetSelectOverlay(const RefPtr& proxy) - { - selectOverlayProxy_ = proxy; + return selectController_->GetCaretRect().GetX(); } CaretUpdateType GetCaretUpdateType() const @@ -409,8 +368,6 @@ public: caretUpdateType_ = type; } - float AdjustTextRectOffsetX(); - float AdjustTextAreaOffsetY(); void AdjustTextSelectionRectOffsetX(); float GetPaddingTop() const @@ -493,9 +450,9 @@ public: return countHeight_; } - const TextSelector& GetTextSelector() + const RefPtr& GetTextSelectController() { - return textSelector_; + return selectController_; } void SetInSelectMode(SelectionMode selectionMode) @@ -510,7 +467,7 @@ public: bool IsSelected() const override { - return selectionMode_ != SelectionMode::NONE && !textSelector_.StartEqualToDest(); + return selectController_->IsSelected(); } bool IsUsingMouse() const @@ -544,25 +501,15 @@ public: void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override; OffsetF GetDragUpperLeftCoordinates() override; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector GetTextBoxes() override -#else - std::vector GetTextBoxes() override -#endif + std::vector GetTextBoxes() override { - return textBoxes_; + return selectController_->GetSelectedRects(); } - void CaretMoveToLastNewLineChar(); + // void CaretMoveToLastNewLineChar(); void ToJsonValue(std::unique_ptr& json) const override; void FromJson(const std::unique_ptr& json) override; void InitEditingValueText(std::string content); - void InitCaretPosition(std::string content); - const TextEditingValueNG& GetTextEditingValue() - { - return textEditingValue_; - } - bool SelectOverlayIsOn(); void CloseSelectOverlay() override; void CloseSelectOverlay(bool animation); void SetInputMethodStatus(bool keyboardShown) override @@ -588,50 +535,18 @@ public: #endif } float PreferredLineHeight(); - void SetNeedCloseOverlay(bool needClose) - { - needCloseOverlay_ = needClose; - } - const RefPtr& GetShowPasswordIconCtx() const - { - return showPasswordImageLoadingCtx_; - } void SearchRequestKeyboard(); - const RefPtr& GetShowPasswordIconCanvasImage() const - { - return showPasswordCanvasImage_; - } - - const RefPtr& GetHidePasswordIconCtx() const - { - return hidePasswordImageLoadingCtx_; - } - - const RefPtr& GetHidePasswordIconCanvasImage() const - { - return hidePasswordCanvasImage_; - } - bool GetTextObscured() const { return textObscured_; } - void SetTextObscured(bool obscured) - { - textObscured_ = obscured; - } - static std::u16string CreateObscuredText(int32_t len); static std::u16string CreateDisplayText( const std::string& content, int32_t nakedCharPosition, bool needObscureText); bool IsTextArea() const override; - const RectF& GetImageRect() const - { - return imageRect_; - } const RefPtr& GetTouchListener() { @@ -646,37 +561,16 @@ public: layoutProperty->GetShowPasswordIconValue(true); } - void SetShowUserDefinedIcon(bool enable) - { - showUserDefinedIcon_ = enable; - } - - void SetHideUserDefinedIcon(bool enable) - { - hideUserDefinedIcon_ = enable; - } - - void SetShowUserDefinedIconSrc(const std::string& iconSrc) - { - showUserDefinedIconSrc_ = iconSrc; - } - - void SetHideUserDefinedIconSrc(const std::string& iconSrc) - { - hideUserDefinedIconSrc_ = iconSrc; - } - void SetEnableTouchAndHoverEffect(bool enable) { enableTouchAndHoverEffect_ = enable; } - const RectF& GetCaretRect() const + RectF GetCaretRect() const { - return caretRect_; + return selectController_->GetCaretRect(); } - void UpdateCaretRectByPosition(int32_t position); float GetIconRightOffset(); float GetIconHotZoneSize(); float GetIconSize(); @@ -714,6 +608,7 @@ public: { return isMousePressed_; } + MouseStatus GetMouseStatus() const { return mouseStatus_; @@ -730,7 +625,6 @@ public: } void UpdateEditingValueToRecord(); - void UpdateEditingValueCaretPositionToRecord(); void UpdateScrollBarOffset() override; bool UpdateCurrentOffset(float offset, int32_t source) override @@ -772,7 +666,7 @@ public: float GetLineHeight() const override { - return caretRect_.Height(); + return selectController_->GetCaretRect().Height(); } OffsetF GetParentGlobalOffset() const override @@ -818,10 +712,6 @@ public: dragDropManager->RemoveDragFrameNode(frameNode->GetId()); } - void CreateHandles() override; - - void CreateHandles(bool animation); - bool IsDragging() const { return dragStatus_ == DragStatus::DRAGGING; @@ -841,18 +731,8 @@ public: Offset(IsTextArea() ? contentRect_.GetX() : textRect_.GetX(), IsTextArea() ? textRect_.GetY() : contentRect_.GetY()) - Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()); - for (const auto& textBoxes : textBoxes_) { -#ifndef USE_GRAPHIC_TEXT_GINE - bool isInRange = LessOrEqual(textBoxes.rect_.GetLeft(), offset.GetX()) && - LessOrEqual(offset.GetX(), textBoxes.rect_.GetRight()) && - LessOrEqual(textBoxes.rect_.GetTop(), offset.GetY()) && - LessOrEqual(offset.GetY(), textBoxes.rect_.GetBottom()); -#else - bool isInRange = LessOrEqual(textBoxes.rect.GetLeft(), offset.GetX()) && - LessOrEqual(offset.GetX(), textBoxes.rect.GetRight()) && - LessOrEqual(textBoxes.rect.GetTop(), offset.GetY()) && - LessOrEqual(offset.GetY(), textBoxes.rect.GetBottom()); -#endif + for (const auto& rect : selectController_->GetSelectedRects()) { + bool isInRange = rect.IsInRegion({ offset.GetX(), offset.GetY() }); if (isInRange) { return true; } @@ -894,6 +774,7 @@ public: void CheckScrollable(); void HandleClickEvent(GestureEvent& info); void HandleDoubleClickEvent(GestureEvent& info); + void HandleSingleClickEvent(GestureEvent& info); void HandleSelectionUp(); void HandleSelectionDown(); @@ -926,15 +807,11 @@ public: { needToRequestKeyboardOnFocus_ = needToRequest; } - static int32_t GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev = false); void SetUnitNode(const RefPtr& unitNode); + void AddCounterNode(); + void ClearCounterNode(); void SetShowError(); - float GetUnitWidth() const - { - return unitWidth_; - } - float GetUnderlineWidth() const { return static_cast(underlineWidth_.Value()); @@ -959,29 +836,8 @@ public: bool IsSelectAll() { - return abs(textSelector_.GetStart() - textSelector_.GetEnd()) >= - static_cast(StringUtils::ToWstring(textEditingValue_.text).length()); - } - - SelectMenuInfo GetSelectMenuInfo() const - { - return selectMenuInfo_; - } - - void UpdateSelectMenuInfo(bool hasData, bool isHideSelectionMenu) - { - selectMenuInfo_.showCopy = !GetEditingValue().text.empty() && AllowCopy() && IsSelected(); - selectMenuInfo_.showCut = selectMenuInfo_.showCopy && !GetEditingValue().text.empty() && IsSelected(); - selectMenuInfo_.showCopyAll = !GetEditingValue().text.empty() && !IsSelectAll(); - selectMenuInfo_.showPaste = hasData; - selectMenuInfo_.menuIsShow = (!GetEditingValue().text.empty() || hasData) && !isHideSelectionMenu; - } - - bool IsSearchParentNode() const; - - void MarkRedrawOverlay() - { - ++drawOverlayFlag_; + return abs(selectController_->GetStartIndex() - selectController_->GetEndIndex()) >= + static_cast(contentController_->GetWideText().length()); } void StopEditing(); @@ -996,16 +852,13 @@ public: contChange_ = false; } - bool GetContChange() + bool GetContChange() const { return contChange_; } std::string GetShowResultImageSrc() const; std::string GetHideResultImageSrc() const; - void OnAttachToFrameNode() override - { - caretUpdateType_ = CaretUpdateType::EVENT; - } + void OnAttachToFrameNode() override; bool GetTextInputFlag() const { @@ -1037,11 +890,6 @@ public: return inlineState_.frameRect.Width(); } - void ResetTouchAtLeftOffsetFlag() override - { - isTouchAtLeftOffset_ = true; - } - bool IsNormalInlineState() const; bool IsUnspecifiedOrTextType() const; void TextIsEmptyRect(RectF& rect); @@ -1060,11 +908,7 @@ public: void DumpAdvanceInfo() override; void OnColorConfigurationUpdate() override; - - void ShowPasswordIconChange() - { - caretUpdateType_ = CaretUpdateType::VISIBLE_PASSWORD_ICON; - } + bool NeedPaintSelect(); void SetIsCustomFont(bool isCustomFont) { @@ -1076,16 +920,6 @@ public: return isCustomFont_; } - void SetTextRectWillChange() - { - textRectWillChange_ = true; - } - - bool GetTextRectWillChange() const - { - return textRectWillChange_; - } - bool IsFocus() { return HasFocus(); @@ -1101,7 +935,56 @@ public: return isCounterIdealheight_; } + virtual RefPtr GetFocusHub() const; + + // override SelectOverlayClient methods. + void OnHandleMove(const RectF& handleRect, bool isFirstHandle) override; + void OnHandleMoveDone(const RectF& handleRect, bool isFirstHandle) override; + void OnHandleClosed(bool closedByGlobalEvent) override; + bool CheckHandleVisible(const RectF& paintRect) override; + bool CheckSelectionRectVisible() override; + bool OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extra) override; + void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) override + { + switch (menuId) { + case SelectOverlayMenuId::COPY: + HandleOnCopy(); + return; + case SelectOverlayMenuId::CUT: + HandleOnCut(); + return; + case SelectOverlayMenuId::SELECT_ALL: + HandleOnSelectAll(false); + return; + case SelectOverlayMenuId::PASTE: + HandleOnPaste(); + return; + } + } + + RefPtr GetClientHost() const override + { + return GetHost(); + } + + void OnObscuredChanged(bool isObscured); + + void SetResponseArea(const RefPtr& responseArea) + { + if (responseArea_) { + responseArea_->DestoryArea(); + responseArea_.Reset(); + } + responseArea_ = responseArea; + } + + const RefPtr& GetResponseArea() + { + return responseArea_; + } + private: + void GetTextSelectRectsInRangeAndWillChange(); bool HasFocus() const; void HandleTouchEvent(const TouchEventInfo& info); void HandleTouchDown(const Offset& offset); @@ -1112,7 +995,10 @@ private: void InitLongPressEvent(); void InitClickEvent(); #ifdef ENABLE_DRAG_FRAMEWORK + void InitDragEvent(); void InitDragDropEvent(); + std::function&, const std::string&)> OnDragStart(); + std::function&, const std::string&)> OnDragDrop(); void ClearDragDropEvent(); std::function GetThumbnailCallback(); #endif @@ -1129,9 +1015,13 @@ private: void HandleHoverEffect(MouseInfo& info, bool isHover); void OnHover(bool isHover); void HandleMouseEvent(MouseInfo& info); + void HandleRightMouseEvent(MouseInfo& info); + void HandleLeftMouseEvent(MouseInfo& info); + void HandleLeftMousePressEvent(MouseInfo& info); + void HandleLeftMouseMoveEvent(MouseInfo& info); + void HandleLeftMouseReleaseEvent(MouseInfo& info); void HandleLongPress(GestureEvent& info); void UpdateCaretPositionWithClamp(const int32_t& pos); - void UpdateSelectorByPosition(const int32_t& pos); // assert handles are inside the contentRect, reset them if not void CheckHandles(std::optional& firstHandle, std::optional& secondHandle, float firstHandleSize = 0.0f, float secondHandleSize = 0.0f); @@ -1141,23 +1031,24 @@ private: void CursorMoveOnClick(const Offset& offset); void UpdateCaretInfoToController() const; - void ProcessOverlay(bool animation = false); - void OnHandleMove(const RectF& handleRect, bool isFirstHandle); - void OnHandleMoveDone(const RectF& handleRect, bool isFirstHandle); + void ProcessOverlay(bool animation = false, bool isShowMenu = true); + SelectHandleInfo GetSelectHandleInfo(OffsetF info); + void UpdateFirstHandlePosition(bool needLayout = false); + void UpdateSecondHandlePosition(bool needLayout = false); + void UpdateDoubleHandlePosition(bool firstNeedLayout = false, bool secondNeedLayout = false); + // when moving one handle causes shift of textRect, update x position of the other handle - void UpdateOtherHandleOnMove(float dx, float dy); void SetHandlerOnMoveDone(); void OnDetachFromFrameNode(FrameNode* node) override; - bool UpdateCaretByPressOrLongPress(); - void UpdateTextSelectorByHandleMove(bool isMovingBase, int32_t position, OffsetF& offsetToParagraphBeginning); - void UpdateCaretByRightClick(); - void UpdateSelectionByDoubleClick(); void UpdateSelectionByMouseDoubleClick(); void AfterSelection(); void FireEventHubOnChange(const std::string& text); void FireOnChangeIfNeeded(); + void FireOnTextChangeEvent(); + + void FilterInitializeText(); void UpdateSelection(int32_t both); void UpdateSelection(int32_t start, int32_t end); @@ -1166,7 +1057,8 @@ private: void UpdateCaretPositionByLastTouchOffset(); bool UpdateCaretPositionByMouseMovement(); bool UpdateCaretPosition(); - bool UpdateCaretRect(); + void UpdateCaretRect(); + void AdjustTextInReasonableArea(); bool CharLineChanged(int32_t caretPosition); void ScheduleCursorTwinkling(); @@ -1183,35 +1075,19 @@ private: void Delete(int32_t start, int32_t end); bool OnDirtyLayoutWrapperSwap(const RefPtr& dirty, const DirtySwapConfig& config) override; - void BeforeCreateLayoutWrapper() override; + // void BeforeCreateLayoutWrapper() override; bool FilterWithRegex( const std::string& filter, const std::string& valueToUpdate, std::string& result, bool needToEscape = false); bool FilterWithAscii(const std::string& valueToUpdate, std::string& result); bool FilterWithEmail(std::string& result); void EditingValueFilter(std::string& valueToUpdate, std::string& result, bool isInsertValue = false); -#ifndef USE_GRAPHIC_TEXT_GINE - bool LastTouchIsInSelectRegion(const std::vector& boxes); - void GetTextRectsInRange(int32_t begin, int32_t end, std::vector& textBoxes); -#else - bool LastTouchIsInSelectRegion(const std::vector& boxes); - void GetTextRectsInRange(int32_t begin, int32_t end, std::vector& textBoxes); -#endif + bool LastTouchIsInSelectRegion(const std::vector& boxes); bool CursorInContentRegion(); float FitCursorInSafeArea(); bool OffsetInContentRegion(const Offset& offset); void SetDisabledStyle(); - void ProcessPasswordIcon(); - void UpdateUserDefineResource(ImageSourceInfo& sourceInfo); - void UpdateInternalResource(ImageSourceInfo& sourceInfo); - ImageSourceInfo GetImageSourceInfoFromTheme(bool checkHidePasswordIcon); - LoadSuccessNotifyTask CreateLoadSuccessCallback(bool checkHidePasswordIcon); - DataReadyNotifyTask CreateDataReadyCallback(bool checkHidePasswordIcon); - LoadFailNotifyTask CreateLoadFailCallback(bool checkHidePasswordIcon); - void OnImageDataReady(bool checkHidePasswordIcon); - void OnImageLoadSuccess(bool checkHidePasswordIcon); - void OnImageLoadFail(bool checkHidePasswordIcon); void CalculateDefaultCursor(); void RequestKeyboardOnFocus(); void SetNeedToRequestKeyboardOnFocus(); @@ -1226,38 +1102,27 @@ private: void SaveInlineStates(); void ApplyInlineStates(bool focusStatus); void RestorePreInlineStates(); - bool CheckHandleVisible(const RectF& paintRect); void SetTextRectOffset(); bool ResetObscureTickCountDown(); bool IsInPasswordMode() const; - void GetWordBoundaryPositon(int32_t offset, int32_t& start, int32_t& end); bool IsTouchAtLeftOffset(float currentOffsetX); void FilterExistText(); void UpdateErrorTextMargin(); + OffsetF GetTextPaintOffset() const; + void UpdateSelectController(); #if defined(ENABLE_STANDARD_INPUT) std::optional GetMiscTextConfig() const; #endif + bool IsSingleHandle() const; RectF frameRect_; RectF contentRect_; RectF textRect_; - RectF imageRect_; - std::shared_ptr paragraph_; - std::shared_ptr counterParagraph_; - std::shared_ptr errorParagraph_; - std::shared_ptr dragParagraph_; - std::shared_ptr textLineHeightUtilParagraph_; - std::shared_ptr placeholderLineHeightUtilParagraph_; + RefPtr paragraph_; + RefPtr errorParagraph_; + RefPtr dragParagraph_; TextStyle nextLineUtilTextStyle_; - std::shared_ptr nextLineUtilParagraph_; - - RefPtr showPasswordImageLoadingCtx_; - RefPtr hidePasswordImageLoadingCtx_; - - // password icon image related - RefPtr showPasswordCanvasImage_; - RefPtr hidePasswordCanvasImage_; RefPtr clickListener_; RefPtr touchListener_; @@ -1274,7 +1139,7 @@ private: TextDirection textDirection_ = TextDirection::LTR; OffsetF parentGlobalOffset_; - Offset lastTouchOffset_; + OffsetF lastTouchOffset_; PaddingPropertyF utilPadding_; OffsetF rightClickOffset_; OffsetF offsetDifference_; @@ -1285,19 +1150,10 @@ private: BorderWidthProperty lastDiffBorderWidth_; BorderColorProperty lastDiffBorderColor_; - bool showUserDefinedIcon_ = false; - bool hideUserDefinedIcon_ = false; - std::string showUserDefinedIconSrc_; - std::string hideUserDefinedIconSrc_; - bool isSingleHandle_ = false; - bool isFirstHandle_ = false; - float baselineOffset_ = 0.0f; - // relative to frameRect - RectF caretRect_; + HandleMoveStatus handleMoveStatus_; bool cursorVisible_ = false; bool focusEventInitialized_ = false; bool isMousePressed_ = false; - bool needCloseOverlay_ = true; bool textObscured_ = true; bool enableTouchAndHoverEffect_ = true; bool isUsingMouse_ = false; @@ -1309,22 +1165,13 @@ private: bool contChange_ = false; std::optional surfaceChangedCallbackId_; std::optional surfacePositionChangedCallbackId_; - float paragraphWidth_ = 0.0f; SelectionMode selectionMode_ = SelectionMode::NONE; CaretUpdateType caretUpdateType_ = CaretUpdateType::NONE; bool scrollable_ = true; - // controls redraw of overlay modifier, update when need to redraw - int32_t drawOverlayFlag_ = 0; - bool isTextInput_ = false; - bool inlineSelectAllFlag_ = false; - bool inlineFocusState_ = false; bool blockPress_ = false; - float inlineSingleLineHeight_ = 0.0f; - float inlinePadding_ = 0.0f; float previewWidth_ = 0.0f; float lastTextRectY_ = 0.0f; - bool needApplyInlineSize_ = false; std::optional barState_; InputStyle preInputStyle_ = InputStyle::DEFAULT; bool preErrorState_ = false; @@ -1336,7 +1183,6 @@ private: int32_t nakedCharPosition_ = -1; bool updateSelectionAfterObscure_ = false; float currentOffset_ = 0.0f; - float unitWidth_ = 0.0f; float countHeight_ = 0.0f; Dimension underlineWidth_ = UNDERLINE_WIDTH; Color underlineColor_; @@ -1352,12 +1198,9 @@ private: RefPtr textFieldController_; RefPtr textEditingController_; TextEditingValueNG textEditingValue_; - RefPtr selectOverlayProxy_; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector textBoxes_; -#else - std::vector textBoxes_; -#endif + std::vector textBoxes_; + // controls redraw of overlay modifier, update when need to redraw + bool changeSelectedRects_ = false; RefPtr textFieldOverlayModifier_; RefPtr textFieldContentModifier_; ACE_DISALLOW_COPY_AND_MOVE(TextFieldPattern); @@ -1371,15 +1214,21 @@ private: RefPtr clipboard_; std::vector operationRecords_; std::vector redoOperationRecords_; - std::vector textSelectorRecords_; - std::vector redoTextSelectorRecords_; std::vector menuOptionItems_; BorderRadiusProperty borderRadius_; PasswordModeStyle passwordModeStyle_; - PreInlineState inlineState_; - SelectMenuInfo selectMenuInfo_; + // inline + bool isTextInput_ = false; + bool inlineSelectAllFlag_ = false; + bool inlineFocusState_ = false; + float inlineSingleLineHeight_ = 0.0f; + float inlinePadding_ = 0.0f; + bool needApplyInlineSize_ = false; + PreInlineState inlineState_; + // inline --end + #if defined(ENABLE_STANDARD_INPUT) sptr textChangeListener_; #else @@ -1390,15 +1239,20 @@ private: bool imeShown_ = false; #endif bool isFocusedBeforeClick_ = false; - bool originalIsMenuShow_ = false; bool isCustomKeyboardAttached_ = false; std::function customKeyboardBulder_; - bool isTouchAtLeftOffset_ = true; bool isCustomFont_ = false; - bool textRectWillChange_ = false; bool hasClicked_ = false; bool isDoubleClick_ = false; TimeStamp lastClickTimeStamp_; + float paragraphWidth_ = 0.0f; + + bool leftMouseCanMove_ = false; + bool isSingleHandle_ = true; + RefPtr contentController_; + RefPtr selectController_; + CaretStatus caretStatus_ = CaretStatus::NONE; + RefPtr responseArea_; }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp new file mode 100644 index 00000000000..3be0ea9dc99 --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "base/geometry/dimension.h" +#include "base/geometry/ng/offset_t.h" +#include "base/geometry/ng/size_t.h" +#include "base/memory/referenced.h" +#include "base/utils/utils.h" +#include "core/common/ime/text_input_type.h" +#include "core/components_ng/layout/layout_property.h" +#include "core/components_ng/pattern/image/image_pattern.h" +#include "core/components_ng/pattern/stack/stack_pattern.h" +#include "core/components_ng/pattern/text_field/text_field_layout_property.h" +#include "core/components_ng/pattern/text_field/text_input_response_area.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" +#include "core/components_ng/property/measure_property.h" +#include "core/components_v2/inspector/inspector_constants.h" +#include "core/pipeline_ng/ui_task_scheduler.h" + +namespace OHOS::Ace::NG { +// TextInputResponseArea begin +void TextInputResponseArea::LayoutChild(LayoutWrapper* layoutWrapper) +{ + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto children = frameNode->GetChildren(); + CHECK_NULL_VOID(!children.empty()); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto textInputGeometryNode = layoutWrapper->GetGeometryNode(); + CHECK_NULL_VOID(textInputGeometryNode); + auto contentRect = textInputGeometryNode->GetContentRect(); + auto textInputFrameSize = textInputGeometryNode->GetFrameSize(); + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + CHECK_NULL_VOID(childWrapper); + auto childGeometryNode = childWrapper->GetGeometryNode(); + CHECK_NULL_VOID(childGeometryNode); + auto childFrameSize = childGeometryNode->GetFrameSize(); + auto childOffset = GetChildOffset(textInputFrameSize, contentRect, childFrameSize); + childGeometryNode->SetFrameOffset(childOffset); + childWrapper->GetGeometryNode()->SetFrameSize(childFrameSize); + areaRect_.SetSize(childFrameSize); + areaRect_.SetOffset(childOffset); + childWrapper->Layout(); +} + +SizeF TextInputResponseArea::Measure(LayoutWrapper* layoutWrapper) +{ + auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0); + auto textfieldLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + SizeF size(0, 0); + CHECK_NULL_RETURN(textfieldLayoutProperty, size); + auto childLayoutConstraint = textfieldLayoutProperty->CreateChildConstraint(); + CHECK_NULL_RETURN(childWrapper, size); + auto childLayoutProperty = childWrapper->GetLayoutProperty(); + auto&& layoutConstraint = childLayoutProperty->GetCalcLayoutConstraint(); + if (layoutConstraint && layoutConstraint->selfIdealSize) { + layoutConstraint->selfIdealSize->SetHeight( + CalcLength(layoutWrapper->GetGeometryNode()->GetFrameSize().Height())); + } + childWrapper->Measure(childLayoutConstraint); + auto geometryNode = childWrapper->GetGeometryNode(); + CHECK_NULL_RETURN(geometryNode, size); + return geometryNode->GetFrameSize(); +} // TextInputResponseArea end + +// PasswordResponseArea begin +void PasswordResponseArea::InitResponseArea(const WeakPtr& hostPattern) +{ + hostPattern_ = hostPattern; + auto textFieldPattern = DynamicCast(hostPattern.Upgrade()); + CHECK_NULL_VOID(textFieldPattern); + auto host = textFieldPattern->GetHost(); + CHECK_NULL_VOID(host); + if (!host->GetChildren().empty()) { + host->GetChildren(); + host->Clean(); + } + if (!IsShowPasswordIcon()) { + LOGD("show password icon is false"); + return; + } + auto passwordNode = CreateNode(); + CHECK_NULL_VOID(passwordNode); + passwordNode->MountToParent(host); +} + +RefPtr PasswordResponseArea::CreateNode() +{ + auto textFieldPattern = DynamicCast(hostPattern_.Upgrade()); + CHECK_NULL_RETURN(textFieldPattern, nullptr); + auto iconSize = textFieldPattern->GetIconSize(); + auto rightOffset = textFieldPattern->GetIconRightOffset(); + auto hotZoneSize = iconSize + rightOffset; + + auto stackNode = FrameNode::CreateFrameNode( + V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + auto stackLayoutProperty = stackNode->GetLayoutProperty(); + CHECK_NULL_RETURN(stackLayoutProperty, nullptr); + stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(hotZoneSize), std::nullopt)); + stackLayoutProperty->UpdateAlignment(Alignment::CENTER_LEFT); + AddEvent(stackNode); + stackNode->MarkModifyDone(); + + auto imageNode = FrameNode::CreateFrameNode( + V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr()); + imageNode->SetDraggable(false); + LoadImageSourceInfo(); + auto currentImageSourceInfo = GetCurrentSourceInfo(); + CHECK_NULL_RETURN(currentImageSourceInfo, nullptr); + auto imageLayoutProperty = imageNode->GetLayoutProperty(); + imageLayoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value()); + imageLayoutProperty->UpdateImageFit(ImageFit::FILL); + imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), + CalcLength(iconSize))); + imageNode->MarkModifyDone(); + imageNode->MountToParent(stackNode); + passwordNode_ = imageNode; + + return stackNode; +} + +void PasswordResponseArea::AddEvent(const RefPtr& node) +{ + CHECK_NULL_VOID(node); + auto focusHub = node->GetOrCreateFocusHub(); + CHECK_NULL_VOID(focusHub); + focusHub->SetFocusable(true); + + if (!clickListener_) { + auto gesture = node->GetOrCreateGestureEventHub(); + auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) { + auto button = weak.Upgrade(); + CHECK_NULL_VOID(button); + button->OnPasswordIconClicked(); + }; + clickListener_ = MakeRefPtr(std::move(clickCallback)); + gesture->AddClickEvent(clickListener_); + } + // TODO mouse hover event +} + +void PasswordResponseArea::OnPasswordIconClicked() +{ + isObscured_ = !isObscured_; + UpdateImageSource(); + auto textFieldPattern = DynamicCast(hostPattern_.Upgrade()); + CHECK_NULL_VOID(textFieldPattern); + textFieldPattern->OnObscuredChanged(isObscured_); +} + +SizeF PasswordResponseArea::Measure(LayoutWrapper* layoutWrapper) +{ + if (!IsShowPasswordIcon()) { + LOGD("show password icon is false"); + return SizeF(0, 0); + } + return TextInputResponseArea::Measure(layoutWrapper); +} + +void PasswordResponseArea::Layout(LayoutWrapper* layoutWrapper) +{ + if (!IsShowPasswordIcon()) { + LOGD("show password icon is false"); + return; + } + LayoutChild(layoutWrapper); +} + +OffsetF PasswordResponseArea::GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize) +{ + return OffsetF(parentSize.Width() - childSize.Width(), 0); +} + +void PasswordResponseArea::LoadImageSourceInfo() +{ + auto textFieldPattern = hostPattern_.Upgrade(); + CHECK_NULL_VOID(textFieldPattern); + auto layoutProperty = textFieldPattern->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + ImageSourceInfo showSystemSourceInfo; + showSystemSourceInfo.SetResourceId(InternalResource::ResourceId::SHOW_PASSWORD_SVG); + showIcon_ = layoutProperty->GetShowPasswordSourceInfoValue(showSystemSourceInfo); + + ImageSourceInfo hideSystemSourceInfo; + hideSystemSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG); + hideIcon_ = layoutProperty->GetHidePasswordSourceInfoValue(hideSystemSourceInfo); +} + +void PasswordResponseArea::UpdateImageSource() +{ + auto frameNode = passwordNode_.Upgrade(); + CHECK_NULL_VOID(frameNode); + auto layoutProperty = frameNode->GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto currentImageSourceInfo = GetCurrentSourceInfo(); + CHECK_NULL_VOID(currentImageSourceInfo); + layoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value()); + auto imagePattern = frameNode->GetPattern(); + CHECK_NULL_VOID(imagePattern); + imagePattern->LoadImageDataIfNeed(); +} + +void PasswordResponseArea::DestoryArea() +{ + TextInputResponseArea::DestoryArea(); + clickListener_.Reset(); + isObscured_ = true; + hostPattern_.Reset(); + passwordNode_.Reset(); + showIcon_ = std::nullopt; + hideIcon_ = std::nullopt; +} + +bool PasswordResponseArea::IsShowPasswordIcon() +{ + auto textFieldPattern = hostPattern_.Upgrade(); + CHECK_NULL_RETURN(textFieldPattern, false); + auto layoutProperty = textFieldPattern->GetLayoutProperty(); + CHECK_NULL_RETURN(layoutProperty, false); + return layoutProperty->GetShowPasswordIconValue(true) && + layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD; +} // PasswordResponseArea end + +// UnitResponseArea begin +void UnitResponseArea::InitResponseArea(const WeakPtr& hostPattern) +{ + hostPattern_ = hostPattern; + auto textFieldPattern = DynamicCast(hostPattern.Upgrade()); + CHECK_NULL_VOID(textFieldPattern); + auto host = textFieldPattern->GetHost(); + CHECK_NULL_VOID(host); + if (!host->GetChildren().empty()) { + host->GetChildren(); + host->Clean(); + } + if (!IsShowUnit()) { + return; + } + auto unitNode = unitNode_.Upgrade();; + CHECK_NULL_VOID(unitNode); + unitNode->MountToParent(host); +} + +SizeF UnitResponseArea::Measure(LayoutWrapper* layoutWrapper) +{ + if (!IsShowUnit()) { + LOGD("not show unit"); + return SizeF(0, 0); + } + return TextInputResponseArea::Measure(layoutWrapper); +} + +void UnitResponseArea::Layout(LayoutWrapper* layoutWrapper) +{ + if (!IsShowUnit()) { + LOGD("not show unit"); + return; + } + LayoutChild(layoutWrapper); +} + +OffsetF UnitResponseArea::GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize) +{ + return OffsetF(contentRect.GetX() + contentRect.Width(), 0); +} + +bool UnitResponseArea::IsShowUnit() +{ + auto textFieldPattern = hostPattern_.Upgrade(); + CHECK_NULL_RETURN(textFieldPattern, false); + auto layoutProperty = textFieldPattern->GetLayoutProperty(); + CHECK_NULL_RETURN(layoutProperty, false); + return layoutProperty->GetShowUnderlineValue(false) && + layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::UNSPECIFIED; +} + +void UnitResponseArea::DestoryArea() +{ + TextInputResponseArea::DestoryArea(); + hostPattern_.Reset(); + unitNode_.Reset(); +} // UnitResponseArea end + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h new file mode 100644 index 00000000000..afd7f6c960c --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_RESPONSE_AREA_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_RESPONSE_AREA_H + +#include "base/geometry/ng/size_t.h" +#include "base/memory/ace_type.h" +#include "base/memory/referenced.h" +#include "core/components_ng/event/click_event.h" +#include "core/components_ng/layout/layout_wrapper.h" +#include "core/components_ng/pattern/pattern.h" +#include "core/image/image_source_info.h" + +namespace OHOS::Ace::NG { +class TextInputResponseArea : public virtual AceType { + DECLARE_ACE_TYPE(TextInputResponseArea, AceType); + +public: + TextInputResponseArea() = default; + ~TextInputResponseArea() = default; + + virtual void InitResponseArea(const WeakPtr& hostPattern) = 0; + + virtual SizeF Measure(LayoutWrapper* layoutWrapper) = 0; + + virtual void Layout(LayoutWrapper* layoutWrapper) = 0; + + virtual void DestoryArea() + { + areaRect_.Reset(); + } + + virtual OffsetF GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize) = 0; + + RectF GetAreaRect() + { + return areaRect_; + } + +protected: + void LayoutChild(LayoutWrapper* layoutWrapper); + WeakPtr hostPattern_; + RectF areaRect_; +}; + +class PasswordResponseArea : public TextInputResponseArea { + DECLARE_ACE_TYPE(PasswordResponseArea, TextInputResponseArea); + +public: + PasswordResponseArea() = default; + ~PasswordResponseArea() = default; + + void InitResponseArea(const WeakPtr& hostPattern) override; + + SizeF Measure(LayoutWrapper* layoutWrapper) override; + + void Layout(LayoutWrapper* layoutWrapper) override; + + OffsetF GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize) override; + + void AddEvent(const RefPtr& node); + + void DestoryArea() override; + + void SetObscured(bool isObscured) + { + isObscured_ = isObscured; + } + +private: + void LoadImageSourceInfo(); + void UpdateImageSource(); + bool IsShowPasswordIcon(); + void OnPasswordIconClicked(); + RefPtr CreateNode(); + std::optional GetCurrentSourceInfo() + { + return isObscured_ ? hideIcon_ : showIcon_; + } + bool isObscured_ = true; + std::optional showIcon_; + std::optional hideIcon_; + RefPtr clickListener_; + WeakPtr passwordNode_; +}; + +class UnitResponseArea : public TextInputResponseArea { + DECLARE_ACE_TYPE(UnitResponseArea, TextInputResponseArea); + +public: + UnitResponseArea(const RefPtr& unitNode) : unitNode_(WeakClaim(AceType::RawPtr(unitNode))) {} + ~UnitResponseArea() = default; + + void SetUnitNode(const RefPtr& unitNode) + { + unitNode_ = WeakClaim(AceType::RawPtr(unitNode)); + } + + void InitResponseArea(const WeakPtr& hostPattern) override; + + SizeF Measure(LayoutWrapper* layoutWrapper) override; + + void Layout(LayoutWrapper* layoutWrapper) override; + + OffsetF GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize) override; + + void DestoryArea() override; + +private: + bool IsShowUnit(); + WeakPtr unitNode_; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_RESPONSE_AREA_H diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp new file mode 100644 index 00000000000..84cd3a4db7f --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "core/components_ng/pattern/text_field/text_select_controller.h" + +#include +#include + +#include "base/geometry/ng/rect_t.h" +#include "base/geometry/offset.h" +#include "base/utils/utils.h" +#include "core/components_ng/pattern/text_field/text_field_layout_property.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" + +namespace OHOS::Ace::NG { + +void TextSelectController::UpdateHandleIndex(int32_t firstHandleIndex, int32_t secondHandleIndex) +{ + firstHandleInfo_.index = firstHandleIndex; + secondHandleInfo_.index = secondHandleIndex; + caretInfo_.index = secondHandleInfo_.index; + CalculateHandleOffset(); + FireSelectEvent(); +} + +void TextSelectController::UpdateCaretIndex(int32_t index) +{ + auto newIndex = std::clamp(index, 0, static_cast(contentController_->GetWideText().length())); + caretInfo_.index = newIndex; + firstHandleInfo_.index = newIndex; + secondHandleInfo_.index = newIndex; + UpdateRecordCaretIndex(caretInfo_.index); +} + +RectF TextSelectController::CalculateEmptyValueCaretRect() const +{ + RectF rect; + auto pattern = pattern_.Upgrade(); + CHECK_NULL_RETURN(pattern, rect); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_RETURN(textFiled, rect); + auto layoutProperty = textFiled->GetLayoutProperty(); + CHECK_NULL_RETURN(layoutProperty, rect); + rect.SetLeft(contentRect_.Left()); + rect.SetTop(contentRect_.Top()); + rect.SetHeight(caretInfo_.rect.Height()); + switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { + case TextAlign::START: + rect.SetLeft(contentRect_.GetX()); + return rect; + case TextAlign::CENTER: + rect.SetLeft(static_cast(contentRect_.GetX()) + contentRect_.Width() / 2.0f); + return rect; + case TextAlign::END: + rect.SetLeft(static_cast(contentRect_.GetX()) + contentRect_.Width() - + static_cast(caretInfo_.rect.Width())); + return rect; + default: + return rect; + } +} + +void TextSelectController::CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) +{ + CHECK_NULL_VOID(paragraph_); + paragraph_->CalcCaretMetricsByPosition(extent, caretCaretMetric, textAffinity); + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + auto textRect = textFiled->GetTextRect(); + caretCaretMetric.offset.AddX(textRect.GetX()); + caretCaretMetric.offset.AddY(textRect.GetY()); +} + +void TextSelectController::CalcCaretMetricsByPositionNearTouchOffset( + int32_t extent, CaretMetricsF& caretMetrics, const OffsetF& touchOffset) +{ + CHECK_NULL_VOID(paragraph_); + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + auto textRect = textFiled->GetTextRect(); + paragraph_->CalcCaretMetricsByPosition(extent, caretMetrics, touchOffset - textRect.GetOffset()); + caretMetrics.offset.AddX(textRect.GetX()); + caretMetrics.offset.AddY(textRect.GetY()); +} + +void TextSelectController::UpdateCaretRectByPositionNearTouchOffset(int32_t position, const Offset& touchOffset) +{ + CaretMetricsF caretMetrics; + CalcCaretMetricsByPositionNearTouchOffset(position, caretMetrics, + OffsetF(static_cast(touchOffset.GetX()), static_cast(touchOffset.GetY()))); + caretInfo_.UpdateOffset(caretMetrics.offset); + UpdateCaretHeight(caretMetrics.height); +} + +void TextSelectController::UpdateCaretInfoByOffset(const Offset& localOffset) +{ + auto index = ConvertTouchOffsetToPosition(localOffset); + UpdateCaretIndex(index); + if (!contentController_->IsEmpty()) { + UpdateCaretRectByPositionNearTouchOffset(index, localOffset); + } + MoveCaretToContentRect(GetCaretIndex()); +} + +int32_t TextSelectController::ConvertTouchOffsetToPosition(const Offset& localOffset) +{ + CHECK_NULL_RETURN(paragraph_, 0); + if (contentController_->IsEmpty()) { + return 0; + } + auto pattern = pattern_.Upgrade(); + CHECK_NULL_RETURN(pattern, 0); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_RETURN(textFiled, 0); + auto textRect = textFiled->GetTextRect(); + auto offset = localOffset - Offset(textRect.GetX(), textRect.GetY()); + return paragraph_->GetGlyphIndexByCoordinate(offset); +} + +void TextSelectController::UpdateSelectByOffset(const Offset& localOffset) +{ + CHECK_NULL_VOID(paragraph_ && !contentController_->IsEmpty()); + int32_t start = 0; + int32_t end = 0; + auto pos = ConvertTouchOffsetToPosition(localOffset); + // Ensure that the end is selected. + if (pos >= static_cast(paragraph_->GetParagraphText().length())) { + pos -= 1; + } + if (!paragraph_->GetWordBoundary(pos, start, end)) { + start = pos; + end = std::min(static_cast(contentController_->GetWideText().length()), + pos + GetGraphemeClusterLength(contentController_->GetWideText(), pos, true)); + } + UpdateHandleIndex(start, end); + if (IsSelected()) { + MoveSecondHandleToContentRect(GetSecondHandleIndex()); + } +} + +int32_t TextSelectController::GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev) +{ + char16_t aroundChar = 0; + if (checkPrev) { + if (static_cast(extend) <= text.length()) { + aroundChar = text[std::max(0, extend - 1)]; + } + } else { + if (static_cast(extend) <= (text.length())) { + aroundChar = text[std::min(static_cast(text.length() - 1), extend)]; + } + } + return StringUtils::NotInUtf16Bmp(aroundChar) ? 2 : 1; +} + +void TextSelectController::CalculateHandleOffset() +{ + // calculate firstHandleOffset, secondHandleOffset and handlePaintSize + if (contentController_->IsEmpty()) { + caretInfo_.rect = CalculateEmptyValueCaretRect(); + return; + } + CaretMetricsF secondHandleMetrics; + CalcCaretMetricsByPosition(GetSecondHandleIndex(), secondHandleMetrics, TextAffinity::UPSTREAM); + OffsetF secondHandleOffset = secondHandleMetrics.offset; + RectF secondHandle; + secondHandle.SetOffset(secondHandleOffset); + secondHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), secondHandleMetrics.height }); + secondHandle.SetHeight(secondHandleMetrics.height); + secondHandleInfo_.rect = secondHandle; + + if (!IsSelected()) { + return; + } + + CaretMetricsF firstHandleMetrics; + CalcCaretMetricsByPosition(GetFirstHandleIndex(), firstHandleMetrics, TextAffinity::DOWNSTREAM); + OffsetF firstHandleOffset = firstHandleMetrics.offset; + + RectF firstHandle; + firstHandle.SetOffset(firstHandleOffset); + firstHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), firstHandleMetrics.height }); + firstHandleInfo_.rect = firstHandle; +} + +std::string TextSelectController::ToString() const +{ + std::string result; + result.append("first handle offset: "); + result.append(std::to_string(firstHandleInfo_.index)); + result.append(", second handle offset: "); + result.append(std::to_string(secondHandleInfo_.index)); + return result; +} + +std::vector TextSelectController::GetSelectedRects() const +{ + if (!IsSelected()) { + return {}; + } + std::vector selectedRects; + CHECK_NULL_RETURN(paragraph_, selectedRects); + paragraph_->GetRectsForRange(GetStartIndex(), GetEndIndex(), selectedRects); + return selectedRects; +} + +void TextSelectController::MoveHandleToContentRect(RectF& handleRect) +{ + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + auto textRect = textFiled->GetTextRect(); + if (textRect.Height() > contentRect_.Height()) { + auto contentBottomBoundary = contentRect_.GetY() + contentRect_.Height(); + if (handleRect.GetY() < contentRect_.GetY()) { + auto dy = contentRect_.GetY() - handleRect.GetY(); + textRect.SetOffset(OffsetF(textRect.GetX(), textRect.GetY() + dy)); + handleRect.SetOffset(OffsetF(handleRect.GetX(), handleRect.GetY() + dy)); + } else if (handleRect.GetY() + handleRect.Height() > contentBottomBoundary) { + auto dy = handleRect.GetY() + handleRect.Height() - contentBottomBoundary; + textRect.SetOffset(OffsetF(textRect.GetX(), textRect.GetY() - dy)); + handleRect.SetOffset(OffsetF(handleRect.GetX(), handleRect.GetY() - dy)); + } + } + + if (textRect.Width() > contentRect_.Width()) { + auto contentRightBoundary = contentRect_.GetX() + contentRect_.Width(); + if (handleRect.GetX() < contentRect_.GetX()) { + auto dx = contentRect_.GetX() - handleRect.GetX(); + textRect.SetOffset(OffsetF(textRect.GetX() + dx, textRect.GetY())); + handleRect.SetOffset(OffsetF(handleRect.GetX() + dx, handleRect.GetY())); + } else if (handleRect.GetX() + handleRect.Width() > contentRightBoundary) { + auto dx = handleRect.GetX() + handleRect.Width() - contentRightBoundary; + textRect.SetOffset(OffsetF(textRect.GetX() - dx, textRect.GetY())); + handleRect.SetOffset(OffsetF(handleRect.GetX() - dx, handleRect.GetY())); + } + } + textFiled->SetTextRect(textRect); +} + +void TextSelectController::MoveFirstHandleToContentRect(int32_t index) +{ + CaretMetricsF firstHandleMetrics; + firstHandleInfo_.index = index; + CalcCaretMetricsByPosition(GetFirstHandleIndex(), firstHandleMetrics, TextAffinity::DOWNSTREAM); + OffsetF firstHandleOffset = firstHandleMetrics.offset; + + RectF firstHandle; + firstHandle.SetOffset(firstHandleOffset); + firstHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), firstHandleMetrics.height }); + MoveHandleToContentRect(firstHandle); + firstHandleInfo_.rect = firstHandle; + UpdateSecondHandleOffset(); + FireSelectEvent(); +} + +void TextSelectController::MoveSecondHandleToContentRect(int32_t index) +{ + CaretMetricsF secondHandleMetrics; + secondHandleInfo_.index = index; + CalcCaretMetricsByPosition(GetSecondHandleIndex(), secondHandleMetrics, TextAffinity::UPSTREAM); + OffsetF secondHandleOffset = secondHandleMetrics.offset; + RectF secondHandle; + secondHandle.SetOffset(secondHandleOffset); + secondHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), secondHandleMetrics.height }); + MoveHandleToContentRect(secondHandle); + secondHandleInfo_.rect = secondHandle; + UpdateFirstHandleOffset(); + FireSelectEvent(); +} + +void TextSelectController::MoveCaretToContentRect(int32_t index) +{ + CaretMetricsF CaretMetrics; + caretInfo_.index = index; + firstHandleInfo_.index = index; + secondHandleInfo_.index = index; + CalcCaretMetricsByPosition(GetCaretIndex(), CaretMetrics, TextAffinity::UPSTREAM); + OffsetF CaretOffset = CaretMetrics.offset; + RectF caretRect; + caretRect.SetOffset(CaretOffset); + caretRect.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), CaretMetrics.height }); + MoveHandleToContentRect(caretRect); + caretInfo_.rect = caretRect; + UpdateRecordCaretIndex(caretInfo_.index); +} + +void TextSelectController::UpdateFirstHandleOffset() +{ + CaretMetricsF caretMetrics; + CalcCaretMetricsByPosition(GetFirstHandleIndex(), caretMetrics, TextAffinity::DOWNSTREAM); + firstHandleInfo_.rect.SetOffset(caretMetrics.offset); + firstHandleInfo_.rect.SetHeight(caretMetrics.height); +} + +void TextSelectController::UpdateSecondHandleOffset() +{ + CaretMetricsF caretMetrics; + CalcCaretMetricsByPosition(GetSecondHandleIndex(), caretMetrics, TextAffinity::UPSTREAM); + secondHandleInfo_.rect.SetOffset(caretMetrics.offset); + secondHandleInfo_.rect.SetHeight(caretMetrics.height); +} + +void TextSelectController::TextSelectController::UpdateCaretOffset() +{ + if (contentController_->IsEmpty()) { + caretInfo_.rect = CalculateEmptyValueCaretRect(); + return; + } + CaretMetricsF caretMetrics; + CalcCaretMetricsByPosition(GetCaretIndex(), caretMetrics, TextAffinity::DOWNSTREAM); + caretInfo_.rect.SetOffset(caretMetrics.offset); + caretInfo_.rect.SetHeight(caretMetrics.height); +} + +void TextSelectController::UpdateSecondHandleInfoByMouseOffset(const Offset& localOffset) +{ + auto index = ConvertTouchOffsetToPosition(localOffset); + caretInfo_.index = index; + UpdateCaretOffset(); + MoveSecondHandleToContentRect(index); +} + +void TextSelectController::FireSelectEvent() +{ + if (!onAccessibilityCallback_ || !IsSelected()) { + return; + } + bool needReport = false; + if (GetFirstIndex().has_value()) { + needReport |= GetFirstIndex().value() != firstHandleInfo_.index; + } + + if (GetSecondIndex().has_value()) { + needReport |= GetFirstIndex().value() != secondHandleInfo_.index; + } + + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + auto eventHub = textFiled->GetEventHub(); + CHECK_NULL_VOID(eventHub); + + if (needReport) { + UpdateFirstIndex(firstHandleInfo_.index); + UpdateSecondIndex(secondHandleInfo_.index); + onAccessibilityCallback_(); + eventHub->FireOnSelectionChange(firstHandleInfo_.index, secondHandleInfo_.index); + } + +} + +void TextSelectController::UpdateRecordCaretIndex(int32_t index) const +{ + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + textFiled->UpdateRecordCaretIndex(index); +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h new file mode 100644 index 00000000000..d1789490e20 --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_TEXT_SELECT_CONTROLLER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_TEXT_SELECT_CONTROLLER_H + +#include +#include +#include + +#include "base/geometry/ng/offset_t.h" +#include "base/geometry/ng/rect_t.h" +#include "base/memory/ace_type.h" +#include "base/memory/referenced.h" +#include "core/components_ng/pattern/pattern.h" +#include "core/components_ng/pattern/text_field/content_controller.h" +#include "core/components_ng/pattern/text_field/text_field_layout_property.h" +#include "core/components_ng/property/property.h" +#include "core/components_ng/render/paragraph.h" + +namespace OHOS::Ace::NG { +namespace { + +using OnAccessibilityCallback = std::function; + +} // namespace + +class TextSelectController : public Property { + DECLARE_ACE_TYPE(TextSelectController, AceType); + +public: + explicit TextSelectController(const WeakPtr& pattern) : pattern_(pattern) {} + ~TextSelectController() override = default; + void SetOnAccessibility(OnAccessibilityCallback&& onAccessibilityCallback) + { + if (onAccessibilityCallback) { + onAccessibilityCallback_ = std::move(onAccessibilityCallback); + } + } + + void FireSelectEvent(); + void UpdateRecordCaretIndex(int32_t index) const; + + void UpdateHandleIndex(int32_t handleIndex) + { + UpdateHandleIndex(handleIndex, handleIndex); + } + + inline int32_t GetStartIndex() const + { + return std::min(firstHandleInfo_.index, secondHandleInfo_.index); + } + + inline int32_t GetEndIndex() const + { + return std::max(firstHandleInfo_.index, secondHandleInfo_.index); + } + + int32_t GetCaretIndex() const + { + return caretInfo_.index; + } + + int32_t GetFirstHandleIndex() const + { + return firstHandleInfo_.index; + } + + RectF GetFirstHandleRect() const + { + return firstHandleInfo_.rect; + } + + int32_t GetSecondHandleIndex() const + { + return secondHandleInfo_.index; + } + + RectF GetSecondHandleRect() const + { + return secondHandleInfo_.rect; + } + + OffsetF GetFirstHandleOffset() const + { + return firstHandleInfo_.rect.GetOffset(); + } + + OffsetF GetSecondHandleOffset() const + { + return secondHandleInfo_.rect.GetOffset(); + } + + void UpdateCaretHeight(float height) + { + caretInfo_.rect.SetHeight(height); + secondHandleInfo_.rect.SetHeight(height); + } + + RectF GetCaretRect() const + { + return caretInfo_.rect; + } + + double GetSelectHeight() const + { + return std::max(firstHandleInfo_.rect.Height(), secondHandleInfo_.rect.Height()); + } + + void InitContentController(const RefPtr& controller) + { + contentController_ = controller; + } + + inline bool IsSelected() const + { + return firstHandleInfo_.index >= 0 && secondHandleInfo_.index >= 0 && + firstHandleInfo_.index != secondHandleInfo_.index; + } + + inline bool IsSelectedAll() const + { + return firstHandleInfo_.index == 0 && secondHandleInfo_.index >= 0 && + abs(firstHandleInfo_.index - secondHandleInfo_.index) == + static_cast(contentController_->GetWideText().length()); + } + + void UpdateParagraph(const RefPtr& paragraph) + { + paragraph_ = paragraph; + } + + void UpdateContentRect(const RectF& rect) + { + contentRect_ = rect; + } + + void UpdateCaretWidth(float width) + { + caretInfo_.rect.SetWidth(width); + } + + HandleInfoNG GetFirstHandleInfo() const + { + return firstHandleInfo_; + } + + HandleInfoNG GetSecondHandleInfo() const + { + return secondHandleInfo_; + } + + HandleInfoNG GetCaretInfo() const + { + return caretInfo_; + } + + void UpdateHandleIndex(int32_t firstHandleIndex, int32_t secondHandleIndex); + void UpdateCaretIndex(int32_t index); + void UpdateCaretInfoByOffset(const Offset& localOffset); + void UpdateSecondHandleInfoByMouseOffset(const Offset& localOffset); + void UpdateSelectByOffset(const Offset& localOffset); + void UpdateCaretOffset(); + void UpdateFirstHandleOffset(); + void UpdateSecondHandleOffset(); + void MoveFirstHandleToContentRect(int32_t index); + void MoveSecondHandleToContentRect(int32_t index); + void MoveCaretToContentRect(int32_t index); + void MoveHandleToContentRect(RectF& handleRect); + static int32_t GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev = false); + void CalculateHandleOffset(); + std::vector GetSelectedRects() const; + RectF CalculateEmptyValueCaretRect() const; + std::string ToString() const; + +private: + void CalcCaretMetricsByPosition(int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity); + void CalcCaretMetricsByPositionNearTouchOffset( + int32_t extent, CaretMetricsF& caretMetrics, const OffsetF& touchOffset); + // The cursor needs to fit the line where the touch is located. + void UpdateCaretRectByPositionNearTouchOffset(int32_t position, const Offset& touchOffset); + int32_t ConvertTouchOffsetToPosition(const Offset& localOffset); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(FirstIndex, int32_t, PROPERTY_UPDATE_RENDER); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(SecondIndex, int32_t, PROPERTY_UPDATE_RENDER); + + RectF contentRect_; + HandleInfoNG firstHandleInfo_; + HandleInfoNG secondHandleInfo_; + HandleInfoNG caretInfo_; + RefPtr paragraph_; + RefPtr contentController_; + OnAccessibilityCallback onAccessibilityCallback_; + WeakPtr pattern_; +}; + +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_TEXT_SELECT_CONTROLLER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_selector.h b/frameworks/core/components_ng/pattern/text_field/text_selector.h index c81f5505cde..b11f451ec3f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_selector.h +++ b/frameworks/core/components_ng/pattern/text_field/text_selector.h @@ -49,6 +49,24 @@ enum class CaretUpdateType { * Stands for selection indexes * We use base/destination to indicate the start/end position because of uncertain direction. */ +struct HandleInfo { + int32_t index = 0; + RectF rect; + + void AddRectY(float deltaY) + { + auto newOffset = rect.GetOffset(); + newOffset.AddY(deltaY); + rect.SetOffset(newOffset); + } + + void AddRectX(float deltaX) + { + auto newOffset = rect.GetOffset(); + newOffset.AddX(deltaX); + rect.SetOffset(newOffset); + } +}; struct TextSelector { TextSelector() = default; TextSelector(int32_t base, int32_t destination) : baseOffset(base), destinationOffset(destination) {} @@ -60,7 +78,7 @@ struct TextSelector { } } - void FireAccessibilityCallback() + void FireAccessibilityCallback() const { if (onAccessibilityCallback_) { onAccessibilityCallback_(); diff --git a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp new file mode 100644 index 00000000000..812b4dafddb --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/components_ng/pattern/text_input/text_input_layout_algorithm.h" + +#include "core/components_ng/pattern/text_field/text_field_pattern.h" + +namespace OHOS::Ace::NG { +std::optional TextInputLayoutAlgorithm::MeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) +{ + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(frameNode, std::nullopt); + auto textFieldLayoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_RETURN(pattern, std::nullopt); + + // Construct text style. + TextStyle textStyle; + std::string textContent; + bool showPlaceHolder = false; + ConstructTextStyles(frameNode, textStyle, textContent, showPlaceHolder); + + auto isInlineStyle = pattern->IsNormalInlineState(); + + auto isPasswordType = + textFieldLayoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD; + + // Create paragraph. + auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder && !isInlineStyle; + if (pattern->IsDragging() && !showPlaceHolder) { + CreateParagraph(textStyle, pattern->GetDragContents(), textContent, + isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, disableTextAlign); + } else { + CreateParagraph(textStyle, textContent, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, + pattern->GetNakedCharPosition(), disableTextAlign); + } + + // constraint size. + auto contentIdealSize = CalculateConstraintSize(contentConstraint, layoutWrapper); + + autoWidth_ = textFieldLayoutProperty->GetWidthAutoValue(false); + + // errorParagraph Layout. + if (textFieldLayoutProperty->GetShowErrorTextValue(false)) { + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_RETURN(pipeline, std::nullopt); + auto textFieldTheme = pipeline->GetTheme(); + CHECK_NULL_RETURN(textFieldTheme, std::nullopt); + CreateErrorParagraph(textFieldLayoutProperty->GetErrorTextValue(""), textFieldTheme); + if (errorParagraph_) { + errorParagraph_->Layout(std::numeric_limits::infinity()); + } + } + + // Used for empty text. + preferredHeight_ = pattern->PreferredLineHeight(); + + // Paragraph layout. + if (isInlineStyle) { + return InlineMeasureContent(contentConstraint, layoutWrapper, contentIdealSize); + } else if (showPlaceHolder) { + return PlaceHolderMeasureContent(contentIdealSize, 0); + } else { + return TextInputMeasureConetnt(contentIdealSize, 0); + } +} + +void TextInputLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) +{ + const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint(); + OptionalSizeF frameSize = + CreateIdealSize(layoutConstraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT_MAIN_AXIS); + const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); + const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + float contentWidth = 0.0f; + float contentHeight = 0.0f; + if (content) { + auto contentSize = content->GetRect().GetSize(); + contentWidth = contentSize.Width(); + contentHeight = contentSize.Height(); + } + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto textFieldTheme = pipeline->GetTheme(); + CHECK_NULL_VOID(textFieldTheme); + auto defaultHeight = textFieldTheme->GetHeight().ConvertToPx(); + if (!frameSize.Height().has_value()) { + if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && + calcLayoutConstraint->maxSize.value().Height().has_value()) { + frameSize.SetHeight(std::max(layoutConstraint->maxSize.Height(), layoutConstraint->minSize.Height())); + } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { + auto height = contentHeight + pattern->GetVerticalPaddingSum() < defaultHeight + ? defaultHeight + : contentHeight + pattern->GetVerticalPaddingSum(); + frameSize.SetHeight(std::min(layoutConstraint->maxSize.Height(), static_cast(height))); + } else { + frameSize.SetHeight(layoutConstraint->minSize.Height()); + } + } + auto textfieldLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(textfieldLayoutProperty); + + if (textfieldLayoutProperty->GetWidthAutoValue(false)) { + frameSize.SetWidth(std::min(textRect_.Width(), contentWidth) + pattern->GetHorizontalPaddingSum()); + } + + if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { + frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); + } else { + auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, + layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), + layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); + frameSize.SetWidth(finalSize.Width()); + frameSize.SetHeight(finalSize.Height()); + } + layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); + + auto responseArea = pattern->GetResponseArea(); + if (responseArea && content) { + auto childWidth = responseArea->Measure(layoutWrapper).Width(); + content->SetSize(SizeF(contentWidth - childWidth, contentHeight)); + } +} + +void TextInputLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) +{ + // update child position. + auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); + CHECK_NULL_VOID(content); + auto contentSize = content->GetRect().GetSize(); + auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); + CHECK_NULL_VOID(layoutProperty); + auto context = layoutWrapper->GetHostNode()->GetContext(); + CHECK_NULL_VOID(context); + parentGlobalOffset_ = layoutWrapper->GetHostNode()->GetPaintRectOffset() - context->GetRootRect().GetOffset(); + auto align = Alignment::CENTER; + bool hasAlign = false; + if (layoutWrapper->GetLayoutProperty()->GetPositionProperty()) { + align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align); + hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value(); + } + // Update content position. + OffsetF contentOffset = Alignment::GetAlignPosition(size, contentSize, align); + content->SetOffset(OffsetF(pattern->GetPaddingLeft(), contentOffset.GetY())); + auto paintProperty = pattern->GetPaintProperty(); + CHECK_NULL_VOID(paintProperty); + if (paragraph_->GetLongestLine() <= contentSize.Width()) { + // adjust text rect to the basic padding + float textRectOffsetX = 0.0f; + if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { + textRectOffsetX = pattern->GetPaddingLeft(); + } else { + textRectOffsetX = pattern->GetPaddingLeft() + pattern->GetBorderLeft(); + } + auto isEmptyTextEditValue = pattern->GetTextValue().empty(); + auto isInlineStyle = pattern->IsNormalInlineState(); + if (!isEmptyTextEditValue && !isInlineStyle) { + switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { + case TextAlign::START: + break; + case TextAlign::CENTER: + textRectOffsetX += (contentSize.Width() - textRect_.Width()) * 0.5f; + break; + case TextAlign::END: + textRectOffsetX += contentSize.Width() - textRect_.Width(); + break; + default: + break; + } + } + textRect_.SetOffset(OffsetF(textRectOffsetX, contentOffset.GetY())); + } else { + textRect_.SetOffset({ pattern->GetTextRect().GetOffset().GetX(), contentOffset.GetY() }); + } + auto responseArea = pattern->GetResponseArea(); + if (responseArea) { + responseArea->Layout(layoutWrapper); + } +} + +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.h new file mode 100644 index 00000000000..eeb1051e46f --- /dev/null +++ b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_PATTERN_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_PATTERN_H + +#include "core/components_ng/pattern/text_field/text_field_layout_algorithm.h" +namespace OHOS::Ace::NG { +class TextInputLayoutAlgorithm : public TextFieldLayoutAlgorithm { + DECLARE_ACE_TYPE(TextInputLayoutAlgorithm, TextFieldLayoutAlgorithm); + +public: + TextInputLayoutAlgorithm() = default; + ~TextInputLayoutAlgorithm() override = default; + + void Measure(LayoutWrapper* layoutWrapper) override; + std::optional MeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) override; + void Layout(LayoutWrapper* layoutWrapper) override; +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_PATTERN_H \ No newline at end of file diff --git a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp index 9cb4e6faaed..69320b89b8a 100644 --- a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp +++ b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp @@ -20,8 +20,8 @@ #include "core/components_ng/base/ui_node.h" #include "core/components_ng/render/adapter/pixelmap_image.h" #include "core/components_ng/render/adapter/txt_font_collection.h" -#include "core/components_ng/render/drawing_prop_convertor.h" #include "core/components_ng/render/drawing.h" +#include "core/components_ng/render/drawing_prop_convertor.h" namespace OHOS::Ace::NG { namespace { @@ -88,6 +88,7 @@ void TxtParagraph::PushStyle(const TextStyle& style) #else Rosen::TextStyle txtStyle; #endif + textAlign_ = style.GetTextAlign(); Constants::ConvertTxtStyle(style, PipelineContext::GetCurrentContext(), txtStyle); builder_->PushStyle(txtStyle); } @@ -144,7 +145,7 @@ void TxtParagraph::Build() #endif if (paraStyle_.leadingMargin) { - SetIndents( { paraStyle_.leadingMargin->size.Width() }); + SetIndents({ paraStyle_.leadingMargin->size.Width() }); } } @@ -262,19 +263,22 @@ void TxtParagraph::Paint(SkCanvas* skCanvas, float x, float y) #endif } -int32_t TxtParagraph::GetHandlePositionForClick(const Offset& offset) +// ToDo:adjust index +int32_t TxtParagraph::GetGlyphIndexByCoordinate(const Offset& offset) { if (!paragraph_) { return 0; } + int32_t index; #ifndef USE_GRAPHIC_TEXT_GINE - return static_cast(paragraph_->GetGlyphPositionAtCoordinate(offset.GetX(), offset.GetY()).position); + index = static_cast(paragraph_->GetGlyphPositionAtCoordinate(offset.GetX(), offset.GetY()).position); #else - return static_cast(paragraph_->GetGlyphIndexByCoordinate(offset.GetX(), offset.GetY()).index); + index = static_cast(paragraph_->GetGlyphIndexByCoordinate(offset.GetX(), offset.GetY()).index); #endif + return index; } -bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) +bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result) { if (!paragraph_) { return false; @@ -339,11 +343,13 @@ bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& r prevChar = text_[std::max(0, index - 1)]; if (prevChar == NEWLINE_CODE) { // Return the start of next line. - result.offset.SetX(0.0); + result.offset.SetX(MakeEmptyOffsetX()); #ifndef USE_GRAPHIC_TEXT_GINE result.offset.SetY(textBox.rect.fBottom); + result.height = textBox.rect.fBottom - textBox.rect.fTop; #else result.offset.SetY(textBox.rect.GetBottom()); + result.height = textBox.rect.GetBottom() - textBox.rect.GetTop(); #endif return true; } @@ -372,7 +378,21 @@ bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& r return true; } -bool TxtParagraph::ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) +float TxtParagraph::MakeEmptyOffsetX() +{ + auto width = GetMaxWidth(); + switch (textAlign_) { + case TextAlign::CENTER: + return width * 0.5f; + case TextAlign::END: + return width; + case TextAlign::START: + default: + return 0.0f; + } +} + +bool TxtParagraph::ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result) { if (!paragraph_ || static_cast(extent) >= GetParagraphLength()) { return false; @@ -417,7 +437,7 @@ bool TxtParagraph::ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& return true; } -void TxtParagraph::GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) +void TxtParagraph::GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) { #ifndef USE_GRAPHIC_TEXT_GINE CHECK_NULL_VOID(paragraph_); @@ -431,12 +451,14 @@ void TxtParagraph::GetRectsForRange(int32_t start, int32_t end, std::vector(rect.Left()), static_cast(rect.Top()), + static_cast(rect.Width()), static_cast(rect.Height())); selectedRects.emplace_back(selectionRect); } } -void TxtParagraph::GetRectsForPlaceholders(std::vector& selectedRects) +void TxtParagraph::GetRectsForPlaceholders(std::vector& selectedRects) { CHECK_NULL_VOID(paragraph_); #ifndef USE_GRAPHIC_TEXT_GINE @@ -448,11 +470,57 @@ void TxtParagraph::GetRectsForPlaceholders(std::vector& selectedRects) return; } for (const auto& box : boxes) { - auto selectionRect = Constants::ConvertSkRect(box.rect); + auto rect = Constants::ConvertSkRect(box.rect); + RectF selectionRect(static_cast(rect.Left()), static_cast(rect.Top()), + static_cast(rect.Width()), static_cast(rect.Height())); selectedRects.emplace_back(selectionRect); } } +bool TxtParagraph::CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) +{ + CaretMetricsF metrics; + bool computeSuccess = false; + if (textAffinity == TextAffinity::DOWNSTREAM) { + computeSuccess = + ComputeOffsetForCaretDownstream(extent, metrics) || ComputeOffsetForCaretUpstream(extent, metrics); + } else { + computeSuccess = + ComputeOffsetForCaretUpstream(extent, metrics) || ComputeOffsetForCaretDownstream(extent, metrics); + } + if (computeSuccess) { + if (metrics.height <= 0 || std::isnan(metrics.height)) { + // The reason may be text lines is exceed the paragraph maxline. + LOGD("Illegal caret height. Consider release restriction of paragraph max_line."); + return false; + } + caretCaretMetric = metrics; + return true; + } + return false; +} + +bool TxtParagraph::CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, const OffsetF& lastTouchOffset) +{ + CaretMetricsF metricsUpstream; + CaretMetricsF metricsDownstream; + auto downStreamSuccess = ComputeOffsetForCaretDownstream(extent, metricsDownstream); + auto upStreamSuccess = ComputeOffsetForCaretUpstream(extent, metricsUpstream); + if (downStreamSuccess || upStreamSuccess) { + if (metricsDownstream.offset.GetY() < lastTouchOffset.GetY() && downStreamSuccess) { + caretCaretMetric = metricsDownstream; + } else if (upStreamSuccess) { + caretCaretMetric = metricsUpstream; + } else { + caretCaretMetric = metricsDownstream; + } + return true; + } + return false; +} + void TxtParagraph::SetIndents(const std::vector& indents) { #ifndef USE_GRAPHIC_TEXT_GINE @@ -483,4 +551,9 @@ bool TxtParagraph::GetWordBoundary(int32_t offset, int32_t& start, int32_t& end) #endif return true; } + +std::u16string TxtParagraph::GetParagraphText() +{ + return text_; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/render/adapter/txt_paragraph.h b/frameworks/core/components_ng/render/adapter/txt_paragraph.h index 2e465deed75..cdb93fdffa6 100644 --- a/frameworks/core/components_ng/render/adapter/txt_paragraph.h +++ b/frameworks/core/components_ng/render/adapter/txt_paragraph.h @@ -73,13 +73,18 @@ public: void Paint(SkCanvas* skCanvas, float x, float y) override; // interfaces for calculate the the specified paragraph position - int32_t GetHandlePositionForClick(const Offset& offset) override; - void GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) override; - void GetRectsForPlaceholders(std::vector& selectedRects) override; - bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) override; - bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) override; + int32_t GetGlyphIndexByCoordinate(const Offset& offset) override; + void GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) override; + void GetRectsForPlaceholders(std::vector& selectedRects) override; + bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result) override; + bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result) override; + bool CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) override; + bool CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, const OffsetF& lastTouchOffset) override; void SetIndents(const std::vector& indents) override; bool GetWordBoundary(int32_t offset, int32_t& start, int32_t& end) override; + std::u16string GetParagraphText() override; private: void CreateBuilder(); @@ -87,6 +92,7 @@ private: { return text_.length() + placeHolderIndex_ + 1; } + float MakeEmptyOffsetX(); ParagraphStyle paraStyle_; #ifndef USE_GRAPHIC_TEXT_GINE @@ -100,6 +106,7 @@ private: #endif std::u16string text_; int32_t placeHolderIndex_ = -1; + TextAlign textAlign_; ACE_DISALLOW_COPY_AND_MOVE(TxtParagraph); }; diff --git a/frameworks/core/components_ng/render/paragraph.h b/frameworks/core/components_ng/render/paragraph.h index df82e7e8abf..0584a9ea064 100644 --- a/frameworks/core/components_ng/render/paragraph.h +++ b/frameworks/core/components_ng/render/paragraph.h @@ -52,6 +52,32 @@ struct ParagraphStyle { double fontSize = 14.0; }; +struct CaretMetricsF { + CaretMetricsF() = default; + CaretMetricsF(const OffsetF& position, float h) + { + offset = position; + height = h; + } + void Reset() + { + offset.Reset(); + height = 0.0; + } + + OffsetF offset; + // When caret is close to different glyphs, the height will be different. + float height = 0.0f; + std::string ToString() const + { + std::string result = "Offset: "; + result += offset.ToString(); + result += ", height: "; + result += std::to_string(height); + return result; + } +}; + // Paragraph is interface for drawing text and text paragraph. class Paragraph : public virtual AceType { DECLARE_ACE_TYPE(NG::Paragraph, AceType) @@ -80,13 +106,18 @@ public: virtual float GetLongestLine() = 0; virtual float GetMaxWidth() = 0; virtual float GetAlphabeticBaseline() = 0; - virtual int32_t GetHandlePositionForClick(const Offset& offset) = 0; - virtual void GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) = 0; - virtual void GetRectsForPlaceholders(std::vector& selectedRects) = 0; - virtual bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) = 0; - virtual bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) = 0; + virtual int32_t GetGlyphIndexByCoordinate(const Offset& offset) = 0; + virtual void GetRectsForRange(int32_t start, int32_t end, std::vector& selectedRects) = 0; + virtual void GetRectsForPlaceholders(std::vector& selectedRects) = 0; + virtual bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetricsF& result) = 0; + virtual bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result) = 0; + virtual bool CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity) = 0; + virtual bool CalcCaretMetricsByPosition( + int32_t extent, CaretMetricsF& caretCaretMetric, const OffsetF& lastTouchOffset) = 0; virtual void SetIndents(const std::vector& indents) = 0; virtual bool GetWordBoundary(int32_t offset, int32_t& start, int32_t& end) = 0; + virtual std::u16string GetParagraphText() = 0; // interfaces for painting virtual void Paint(RSCanvas& canvas, float x, float y) = 0; diff --git a/frameworks/core/components_ng/test/mock/pattern/text/mock_overlay_modifier.cpp b/frameworks/core/components_ng/test/mock/pattern/text/mock_overlay_modifier.cpp index c768e663967..d66e7e53916 100644 --- a/frameworks/core/components_ng/test/mock/pattern/text/mock_overlay_modifier.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/text/mock_overlay_modifier.cpp @@ -24,9 +24,9 @@ void TextOverlayModifier::SetPrintOffset(const OffsetF& paintOffset) {} void TextOverlayModifier::SetSelectedColor(uint32_t selectedColor) {} -void TextOverlayModifier::SetSelectedRects(const std::vector& selectedRects) {} +void TextOverlayModifier::SetSelectedRects(const std::vector& selectedRects) {} -bool TextOverlayModifier::IsSelectedRectsChanged(const std::vector& selectedRects) +bool TextOverlayModifier::IsSelectedRectsChanged(const std::vector& selectedRects) { return true; } diff --git a/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp b/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp index ab4ea13b5dc..8d60167ec4e 100644 --- a/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp @@ -94,7 +94,7 @@ size_t TextLayoutAlgorithm::GetLineCount() const void TextLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) {} -void TextLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) {} +void TextLayoutAlgorithm::GetPlaceholderRects(std::vector& rects) {} ParagraphStyle TextLayoutAlgorithm::GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const { diff --git a/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp b/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp index ed213c3c90e..6e1764f8144 100644 --- a/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp +++ b/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp @@ -48,11 +48,7 @@ float TextPattern::GetLineHeight() const return {}; } -#ifndef USE_GRAPHIC_TEXT_GINE -std::vector TextPattern::GetTextBoxes() -#else -std::vector TextPattern::GetTextBoxes() -#endif +std::vector TextPattern::GetTextBoxes() { return {}; } diff --git a/frameworks/core/components_ng/test/pattern/rich_editor/rich_editor_test_ng.cpp b/frameworks/core/components_ng/test/pattern/rich_editor/rich_editor_test_ng.cpp index 515d6abd889..b389413d2cc 100755 --- a/frameworks/core/components_ng/test/pattern/rich_editor/rich_editor_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/rich_editor/rich_editor_test_ng.cpp @@ -530,7 +530,7 @@ HWTEST_F(RichEditorTestNg, RichEditorCursorMove001, TestSize.Level1) ASSERT_NE(richEditorPattern, nullptr); auto paragraph = AceType::MakeRefPtr(); richEditorPattern->paragraphs_.AddParagraph({ .paragraph = paragraph }); - EXPECT_CALL(*paragraph, GetHandlePositionForClick).Times(2).WillRepeatedly(Return(2)); + EXPECT_CALL(*paragraph, GetGlyphIndexByCoordinate).Times(2).WillRepeatedly(Return(2)); AddSpan(INIT_VALUE_1); richEditorPattern->caretPosition_ = 2; richEditorPattern->CursorMoveLeft(); diff --git a/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp b/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp index f69aaeba5ae..f48534e70a8 100644 --- a/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp @@ -2361,11 +2361,11 @@ HWTEST_F(TextTestNg, TextOverlayModifierTest001, TestSize.Level1) OffsetF paintOffset; textOverlayModifier.SetPrintOffset(paintOffset); textOverlayModifier.SetSelectedColor(SELECTED_COLOR); - std::vector rectList; - rectList.push_back(Rect(RECT_X_VALUE, RECT_Y_VALUE, RECT_WIDTH_VALUE, RECT_HEIGHT_VALUE)); + std::vector rectList; + rectList.push_back(RectF(RECT_X_VALUE, RECT_Y_VALUE, RECT_WIDTH_VALUE, RECT_HEIGHT_VALUE)); textOverlayModifier.SetSelectedRects(rectList); // change selectedRects_ and call IsSelectedRectsChanged function - Rect secondRect(RECT_SECOND_X_VALUE, RECT_Y_VALUE, RECT_WIDTH_VALUE, RECT_HEIGHT_VALUE); + RectF secondRect(RECT_SECOND_X_VALUE, RECT_Y_VALUE, RECT_WIDTH_VALUE, RECT_HEIGHT_VALUE); textOverlayModifier.selectedRects_[0] = secondRect; Testing::MockCanvas canvas; EXPECT_CALL(canvas, Save()).WillRepeatedly(Return()); @@ -2876,7 +2876,7 @@ HWTEST_F(TextTestNg, ShowSelectOverlay004, TestSize.Level1) HWTEST_F(TextTestNg, IsDraggable001, TestSize.Level1) { auto paragraph = MockParagraph::GetOrCreateMockParagraph(); - std::vector rects { Rect(0, 0, 20, 20) }; + std::vector rects { RectF(0, 0, 20, 20) }; EXPECT_CALL(*paragraph, GetRectsForRange(_, _, _)).WillRepeatedly(SetArgReferee<2>(rects)); auto [host, pattern] = Init(); @@ -2930,19 +2930,14 @@ HWTEST_F(TextTestNg, DragBase001, TestSize.Level1) // test GetTextBoxes and GetLineHeight auto paragraph = MockParagraph::GetOrCreateMockParagraph(); pattern->paragraph_ = paragraph; - std::vector rects { Rect(0, 0, 20, 20) }; + std::vector rects { RectF(0, 0, 20, 20) }; EXPECT_CALL(*paragraph, GetRectsForRange(_, _, _)).WillRepeatedly(SetArgReferee<2>(rects)); pattern->textSelector_.Update(0, 20); auto boxes = pattern->GetTextBoxes(); EXPECT_EQ(boxes.size(), 1); -#ifndef USE_GRAPHIC_TEXT_GINE - EXPECT_EQ(boxes[0].rect_.GetLeft(), 0); - EXPECT_EQ(boxes[0].rect_.GetRight(), 20); -#else - EXPECT_EQ(boxes[0].rect.GetLeft(), 0); - EXPECT_EQ(boxes[0].rect.GetRight(), 20); -#endif + EXPECT_EQ(boxes[0].Left(), 0); + EXPECT_EQ(boxes[0].Right(), 20); auto height = pattern->GetLineHeight(); EXPECT_EQ(height, 20); @@ -3686,7 +3681,7 @@ HWTEST_F(TextTestNg, HandleLongPress002, TestSize.Level1) EXPECT_CALL(*paragraph, ComputeOffsetForCaretDownstream).WillRepeatedly(Return(true)); EXPECT_CALL(*paragraph, ComputeOffsetForCaretUpstream).WillRepeatedly(Return(true)); EXPECT_CALL(*paragraph, GetWordBoundary).WillRepeatedly(Return(false)); - std::vector rects { Rect(0, 0, 20, 20) }; + std::vector rects { RectF(0, 0, 20, 20) }; EXPECT_CALL(*paragraph, GetRectsForRange(_, _, _)).Times(2).WillRepeatedly(SetArgReferee<2>(rects)); /** * @tc.steps: step1. create frameNode and pattern @@ -3957,7 +3952,7 @@ HWTEST_F(TextTestNg, TextSelectorTest001, TestSize.Level1) HWTEST_F(TextTestNg, TextPaintMethodTest003, TestSize.Level1) { auto paragraph = MockParagraph::GetOrCreateMockParagraph(); - std::vector rects { Rect(0, 0, 20, 20) }; + std::vector rects { RectF(0, 0, 20, 20) }; EXPECT_CALL(*paragraph, GetRectsForRange(_, _, _)).WillOnce(SetArgReferee<2>(rects)); /** * @tc.steps: step1. create textFrameNode and geometryNode. @@ -3990,7 +3985,7 @@ HWTEST_F(TextTestNg, TextPaintMethodTest003, TestSize.Level1) textPattern, paragraph, BASE_LINE_OFFSET_VALUE, textContentModifier, textOverlayModifier); auto paintWrapper = AceType::MakeRefPtr(renderContext, geometryNode, paintProperty); textPaintMethod.UpdateContentModifier(AceType::RawPtr(paintWrapper)); - EXPECT_EQ(textContentModifier->drawObscuredRects_, std::vector()); + EXPECT_EQ(textContentModifier->drawObscuredRects_, std::vector()); /** * @tc.steps: step4. set textForDisplay_ to CREATE_VALUE. @@ -4002,7 +3997,7 @@ HWTEST_F(TextTestNg, TextPaintMethodTest003, TestSize.Level1) * @tc.expected: The drawObscuredRects_ of textContentModifier is not empty. */ textPaintMethod.UpdateContentModifier(AceType::RawPtr(paintWrapper)); - EXPECT_NE(textContentModifier->drawObscuredRects_, std::vector()); + EXPECT_NE(textContentModifier->drawObscuredRects_, std::vector()); /** * @tc.steps: step6. push UNKNOWN_REASON and PLACEHOLDER to reasons. @@ -4143,8 +4138,8 @@ HWTEST_F(TextTestNg, TextContentModifier004, TestSize.Level1) textContentModifier->SetDefaultTextColor(textStyle); SizeF contentSize(TEXT_CONTENT_SIZE, TEXT_CONTENT_SIZE); textContentModifier->SetContentSize(contentSize); - std::vector drawObscuredRects; - Rect textRect; + std::vector drawObscuredRects; + RectF textRect; textRect.SetHeight(TEXT_RECT_WIDTH); textRect.SetWidth(TEXT_RECT_WIDTH); textRect.SetTop(TEXT_RECT_TOP_ONE); @@ -4283,7 +4278,7 @@ HWTEST_F(TextTestNg, TextModelGetFont001, TestSize.Level1) HWTEST_F(TextTestNg, BetweenSelectedPosition001, TestSize.Level1) { auto paragraph = MockParagraph::GetOrCreateMockParagraph(); - std::vector rects { Rect(0, 0, 20, 20) }; + std::vector rects { RectF(0, 0, 20, 20) }; EXPECT_CALL(*paragraph, GetRectsForRange(_, _, _)).WillRepeatedly(SetArgReferee<2>(rects)); /** * @tc.steps: step1. create frameNode and pattern and some environment for running process. @@ -4637,11 +4632,11 @@ HWTEST_F(TextTestNg, GetDragUpperLeftCoordinates001, TestSize.Level1) auto ret = pattern->GetDragUpperLeftCoordinates(); EXPECT_EQ(ret, OffsetF(0, 0)); - pattern->dragBoxes_.push_back({ {}, Testing::TextDirection::LTR }); + pattern->dragBoxes_.push_back({}); ret = pattern->GetDragUpperLeftCoordinates(); EXPECT_EQ(ret, OffsetF(0, 0)); - pattern->dragBoxes_.push_back({ { 1, 2, 3, 4 }, Testing::TextDirection::LTR }); + pattern->dragBoxes_.push_back({ 1, 2, 3, 4 }); ret = pattern->GetDragUpperLeftCoordinates(); EXPECT_EQ(ret, OffsetF(0, 0)); } diff --git a/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp b/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp index 333ab930e0e..6deb119f5ef 100644 --- a/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp @@ -17,6 +17,8 @@ #define private public #define protected public +#include "test/mock/core/render/mock_paragraph.h" + #include "core/components/common/layout/constants.h" #include "core/components_ng/pattern/root/root_pattern.h" #include "core/components_ng/pattern/text_field/text_editing_value_ng.h" @@ -33,8 +35,8 @@ #include "core/components_ng/pattern/text_field/text_field_pattern.h" #include "core/components_ng/pattern/text_field/text_selector.h" #include "core/components_ng/test/mock/pattern/text_field/mock_text_input_connection.h" -#include "core/components_ng/test/mock/rosen/mock_canvas.h" #include "core/components_ng/test/mock/render/mock_render_context.h" +#include "core/components_ng/test/mock/rosen/mock_canvas.h" #include "core/components_ng/test/mock/theme/mock_theme_manager.h" #include "core/components_v2/inspector/inspector_constants.h" #include "core/pipeline_ng/test/mock/mock_pipeline_base.h" @@ -128,7 +130,7 @@ void TextFieldPatternTestNg::RunSetUp() auto pipeline = MockPipelineBase::GetCurrent(); auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor()); pattern_->clipboard_ = clipboard; - pattern_->paragraph_ = std::make_shared(); + pattern_->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); } RefPtr TextFieldPatternTestNg::CreatTextFieldNode( @@ -1055,7 +1057,7 @@ HWTEST_F(TextFieldPatternTestNg, CheckScrollable004, TestSize.Level1) EXPECT_FALSE(textFieldPattern->scrollable_); layoutProperty->UpdateShowCounter(true); - textFieldPattern->counterParagraph_ = std::make_shared(); + textFieldPattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldPattern->CheckScrollable(); EXPECT_FALSE(textFieldPattern->scrollable_); } @@ -1469,38 +1471,6 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldPatternOnTextAreaScroll001, TestSize.L EXPECT_EQ(pattern->textRect_.GetY(), 10.0f); } -/** - * @tc.name: MakeEmptyOffset - * @tc.desc: test MakeEmptyOffset. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, MakeEmptyOffset, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create the TextFieldPattern. - * @tc.expected: step1. Check the TextFieldPattern success. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - - /** - * @tc.steps: step2. Call the MakeEmptyOffset. - * @tc.expected: step2. Check the return value. - */ - auto width = pattern->contentRect_.Width(); - std::pair textAlignPairs[] = { std::make_pair(TextAlign::CENTER, OffsetF(width * 0.5f, 0.0f)), - std::make_pair(TextAlign::END, OffsetF(width, 0.0f)), std::make_pair(TextAlign::START, OffsetF()), - std::make_pair(TextAlign::JUSTIFY, OffsetF()) }; - for (auto pair : textAlignPairs) { - layoutProperty->UpdateTextAlign(pair.first); - EXPECT_EQ(pattern->MakeEmptyOffset(), pair.second); - } -} - /** * @tc.name: onDraw001 * @tc.desc: Verify that the onDraw interface calls normally and exits without exception. @@ -1587,17 +1557,10 @@ HWTEST_F(TextFieldPatternTestNg, PaintSelection003, TestSize.Level1) pattern->selectionMode_ = SelectionMode::SELECT; pattern->textSelector_.baseOffset = 1; pattern->textSelector_.destinationOffset = 0; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector textBoxes; - RSTypographyProperties::TextBox textBox; - textBoxes.emplace_back(textBox); - pattern->textBoxes_ = textBoxes; -#else - std::vector textBoxs; - RSTypographyProperties::TextRect textBox; + std::vector textBoxs; + RectF textBox; textBoxs.emplace_back(textBox); pattern->textBoxes_ = textBoxs; -#endif EdgeEffect edgeEffect; auto scrollEdgeEffect = AceType::MakeRefPtr(edgeEffect); TextFieldOverlayModifier textFieldOverlayModifier(pattern, scrollEdgeEffect); @@ -1645,7 +1608,7 @@ HWTEST_F(TextFieldPatternTestNg, PaintCursor001, TestSize.Level1) auto pattern = frameNode->GetPattern(); ASSERT_NE(pattern, nullptr); pattern->selectionMode_ = SelectionMode::NONE; - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); EdgeEffect edgeEffect; auto scrollEdgeEffect = AceType::MakeRefPtr(edgeEffect); TextFieldOverlayModifier textFieldOverlayModifier(pattern, scrollEdgeEffect); @@ -2274,7 +2237,7 @@ HWTEST_F(TextFieldPatternTestNg, onDraw003, TestSize.Level1) /** * @tc.steps: step2. paragraph_ Pointer instantiation. */ - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); auto textFieldContentModifier = AceType::MakeRefPtr(pattern); textFieldContentModifier->contentOffset_ = AceType::MakeRefPtr(OffsetF()); textFieldContentModifier->contentSize_ = AceType::MakeRefPtr(SizeF()); @@ -2822,37 +2785,19 @@ HWTEST_F(TextFieldPatternTestNg, AdjustTextSelectionRectOffsetX, TestSize.Level1 textFieldPattern->contentRect_.SetLeft(60.0f); textFieldPattern->contentRect_.SetWidth(100.0f); textFieldPattern->textRect_.SetLeft(0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - RSTypographyProperties::TextBox textBox; -#else - RSTypographyProperties::TextRect textBox; -#endif + RectF textBox; textFieldPattern->textBoxes_.emplace_back(textBox); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetRight(-30.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetRight(-30.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetWidth(-30.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 60.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetLeft(-20.0f); - textFieldPattern->textBoxes_.begin()->rect_.SetRight(-10.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetLeft(-20.0f); - textFieldPattern->textBoxes_.begin()->rect.SetRight(-10.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetLeft(-20.0f); + textFieldPattern->textBoxes_.begin()->SetWidth(10.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 60.0f); EXPECT_EQ(textFieldPattern->unitWidth_, 0.0f); - -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetRight(110.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetRight(110.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetWidth(120.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 60.0f); } @@ -2876,54 +2821,28 @@ HWTEST_F(TextFieldPatternTestNg, AdjustTextSelectionRectOffsetX001, TestSize.Lev textFieldPattern->contentRect_.SetLeft(0.0f); textFieldPattern->contentRect_.SetWidth(100.0f); textFieldPattern->textRect_.SetLeft(0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - RSTypographyProperties::TextBox textBox; -#else - RSTypographyProperties::TextRect textBox; -#endif + RectF textBox; textFieldPattern->textBoxes_.emplace_back(textBox); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetRight(50.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetRight(50.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetWidth(50.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetLeft(-20.0f); - textFieldPattern->textBoxes_.begin()->rect_.SetRight(-10.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetLeft(-20.0f); - textFieldPattern->textBoxes_.begin()->rect.SetRight(-10.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetLeft(-20.0f); + textFieldPattern->textBoxes_.begin()->SetWidth(10.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetLeft(0.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetLeft(0.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetLeft(0.0f); textFieldPattern->textRect_.SetLeft(0.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetLeft(100.0f); - textFieldPattern->textBoxes_.begin()->rect_.SetRight(200.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetLeft(100.0f); - textFieldPattern->textBoxes_.begin()->rect.SetRight(200.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetLeft(100.0f); + textFieldPattern->textBoxes_.begin()->SetWidth(100.0f); textFieldPattern->textRect_.SetLeft(0.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 0.0f); -#ifndef USE_GRAPHIC_TEXT_GINE - textFieldPattern->textBoxes_.begin()->rect_.SetLeft(300.0f); -#else - textFieldPattern->textBoxes_.begin()->rect.SetLeft(300.0f); -#endif + textFieldPattern->textBoxes_.begin()->SetLeft(300.0f); textFieldPattern->textRect_.SetLeft(0.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 0.0f); @@ -3251,8 +3170,8 @@ HWTEST_F(TextFieldPatternTestNg, onDraw005, TestSize.Level1) bool value = true; textFieldContentModifier.showErrorState_ = AceType::MakeRefPtr(value); textFieldContentModifier.showCounter_ = AceType::MakeRefPtr(value); - pattern->counterParagraph_ = std::make_shared(); - pattern->errorParagraph_ = std::make_shared(); + pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); + pattern->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldContentModifier.onDraw(context); } @@ -3399,7 +3318,7 @@ HWTEST_F(TextFieldPatternTestNg, CreateCounterParagraph001, TestSize.Level1) constexpr int32_t maxLength = 10; const RefPtr theme = AceType::MakeRefPtr(); EXPECT_EQ(textFieldLayoutAlgorithm.counterParagraph_, nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = std::make_shared(); + textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldLayoutAlgorithm.CreateCounterParagraph(textLength, maxLength, theme); EXPECT_NE(textFieldLayoutAlgorithm.counterParagraph_, nullptr); } @@ -3424,7 +3343,7 @@ HWTEST_F(TextFieldPatternTestNg, CreateCounterParagraph002, TestSize.Level1) constexpr int32_t maxLength = 10; const RefPtr theme = AceType::MakeRefPtr(); EXPECT_EQ(textFieldLayoutAlgorithm.counterParagraph_, nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = std::make_shared(); + textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldLayoutAlgorithm.CreateCounterParagraph(textLength, maxLength, theme); EXPECT_NE(textFieldLayoutAlgorithm.counterParagraph_, nullptr); } @@ -3446,7 +3365,7 @@ HWTEST_F(TextFieldPatternTestNg, GetCounterParagraph, TestSize.Level1) * @tc.expected: The member variable value of textFieldLayoutAlgorithm is the value set above. */ EXPECT_EQ(textFieldLayoutAlgorithm.GetCounterParagraph(), nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = std::make_shared(); + textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); EXPECT_NE(textFieldLayoutAlgorithm.GetCounterParagraph(), nullptr); } @@ -3634,7 +3553,7 @@ HWTEST_F(TextFieldPatternTestNg, PaintCursor002, TestSize.Level1) auto pattern = frameNode->GetPattern(); ASSERT_NE(pattern, nullptr); pattern->selectionMode_ = SelectionMode::NONE; - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); EdgeEffect edgeEffect; auto scrollEdgeEffect = AceType::MakeRefPtr(edgeEffect); TextFieldOverlayModifier textFieldOverlayModifier(pattern, scrollEdgeEffect); @@ -3649,7 +3568,7 @@ HWTEST_F(TextFieldPatternTestNg, PaintCursor002, TestSize.Level1) */ textFieldOverlayModifier.cursorVisible_ = AceType::MakeRefPtr(true); textFieldOverlayModifier.showCounter_ = AceType::MakeRefPtr(true); - pattern->counterParagraph_ = std::make_shared(); + pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldOverlayModifier.PaintCursor(context); } @@ -3670,13 +3589,8 @@ HWTEST_F(TextFieldPatternTestNg, PaintSelection004, TestSize.Level1) pattern->selectionMode_ = SelectionMode::SELECT; pattern->textSelector_.baseOffset = 1; pattern->textSelector_.destinationOffset = 0; -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector textBoxes; - RSTypographyProperties::TextBox textBox; -#else - std::vector textBoxes; - RSTypographyProperties::TextRect textBox; -#endif + std::vector textBoxes; + RectF textBox; textBoxes.emplace_back(textBox); pattern->textBoxes_ = textBoxes; EdgeEffect edgeEffect; @@ -3696,7 +3610,7 @@ HWTEST_F(TextFieldPatternTestNg, PaintSelection004, TestSize.Level1) * @tc.expected: Check the properties set successfully. */ textFieldOverlayModifier.showCounter_ = AceType::MakeRefPtr(true); - pattern->counterParagraph_ = std::make_shared(); + pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldOverlayModifier.inputStyle_ = InputStyle::DEFAULT; textFieldOverlayModifier.PaintSelection(context); } @@ -4284,10 +4198,10 @@ HWTEST_F(TextFieldPatternTestNg, OnDirtyLayoutWrapperSwap, TestSize.Level2) DirtySwapConfig dirtySwapConfig; EXPECT_TRUE(textFieldPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, dirtySwapConfig)); - layoutAlgorithm->paragraph_ = std::make_shared(); - layoutAlgorithm->counterParagraph_ = std::make_shared(); - layoutAlgorithm->errorParagraph_ = std::make_shared(); - layoutAlgorithm->errorParagraph_ = std::make_shared(); + layoutAlgorithm->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); + layoutAlgorithm->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); + layoutAlgorithm->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); + layoutAlgorithm->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldPattern->needToRefreshSelectOverlay_ = true; textFieldPattern->mouseStatus_ = MouseStatus::RELEASED; auto focusHub = frameNode->GetOrCreateFocusHub(); @@ -4585,7 +4499,7 @@ HWTEST_F(TextFieldPatternTestNg, TFLayoutAlgorithmMeasureContent, TestSize.Level layoutWrapper.Update(AceType::WeakClaim(AceType::RawPtr(frameNode)), cloneGeometryNode, cloneLayoutProperty); layoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_EQ(layoutWrapper.GetGeometryNode()->GetFrameSize().Width(), 0); - pattern->counterParagraph_ = std::make_shared(); + pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_EQ(layoutWrapper.GetGeometryNode()->GetFrameSize().Width(), 0); cloneLayoutProperty->UpdateShowErrorText(true); @@ -4791,15 +4705,9 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectionOffset, TestSize.Level2) EXPECT_EQ(pattern->GetTextSelector().selectionBaseOffset.GetX(), 4); EXPECT_EQ(pattern->GetTextSelector().selectionDestinationOffset.GetX(), 8); -#ifndef USE_GRAPHIC_TEXT_GINE - std::vector textBoxes; - RSTypographyProperties::TextBox firstTextBox; - RSTypographyProperties::TextBox secondTextBox; -#else - std::vector textBoxes; - RSTypographyProperties::TextRect firstTextBox; - RSTypographyProperties::TextRect secondTextBox; -#endif + std::vector textBoxes; + RectF firstTextBox; + RectF secondTextBox; textBoxes.emplace_back(firstTextBox); textBoxes.emplace_back(secondTextBox); pattern->textBoxes_ = textBoxes; @@ -5508,7 +5416,7 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionDown, TestSize.Level2) * @tc.steps: step3. in text area and call HandleSelectionDown. * @tc.expected: Check the value of the updated property. */ - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutProperty->UpdateMaxLines(2); pattern->selectionMode_ = SelectionMode::SELECT; pattern->HandleSelectionDown(); @@ -5555,7 +5463,7 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionUp, TestSize.Level2) * @tc.steps: step3. in text area and call HandleSelectionUp. * @tc.expected: Check the value of the updated property. */ - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutProperty->UpdateMaxLines(2); pattern->selectionMode_ = SelectionMode::SELECT; pattern->HandleSelectionUp(); @@ -6016,7 +5924,7 @@ HWTEST_F(TextFieldPatternTestNg, OnKeyEvent, TestSize.Level1) ASSERT_NE(pattern, nullptr); auto context = PipelineContext::GetCurrentContext(); context->SetTextFieldManager(AceType::MakeRefPtr()); - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); pattern->imeAttached_ = true; KeyEvent event; @@ -6228,8 +6136,8 @@ HWTEST_F(TextFieldPatternTestNg, FitInSafeArea, TestSize.Level1) dy = pattern->AdjustTextAreaOffsetY(); EXPECT_EQ(dy, 195.0f); EXPECT_EQ(pattern->caretRect_.GetX(), CARE_RECT_DANGEROUS.GetX()); - int32_t charPosition[3] = {-1, 0, 2}; - auto content = pattern->CreateDisplayText(TEXT_CONTENT, charPosition[1], true);; + int32_t charPosition[3] = { -1, 0, 2 }; + auto content = pattern->CreateDisplayText(TEXT_CONTENT, charPosition[1], true); for (int i = 0; i < 3; i++) { content = pattern->CreateDisplayText(TEXT_CONTENT, charPosition[i], true); content = pattern->CreateDisplayText(TEXT_CONTENT, charPosition[i], false); @@ -6276,7 +6184,7 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectorByPosition001, TestSize.Level1) ASSERT_NE(frameNode, nullptr); auto pattern = frameNode->GetPattern(); ASSERT_NE(pattern, nullptr); - pattern->paragraph_ = std::make_shared(); + pattern->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); /* * @tc.steps: step2. call UpdateSelectorByPosition function. * @tc.expected: The UpdateSelectorByPosition function will exit without exception. @@ -6642,11 +6550,11 @@ HWTEST_F(TextFieldPatternTestNg, UpdateCaretOffsetByEvent, TestSize.Level1) } /** - * @tc.name: CalcCursorOffsetByPosition - * @tc.desc: test CalcCursorOffsetByPosition + * @tc.name: CalcCaretMetricsByPosition + * @tc.desc: test CalcCaretMetricsByPosition * @tc.type: FUNC */ -HWTEST_F(TextFieldPatternTestNg, CalcCursorOffsetByPosition, TestSize.Level1) +HWTEST_F(TextFieldPatternTestNg, CalcCaretMetricsByPosition, TestSize.Level1) { /** * @tc.steps: step1. Create TextFieldPattern. @@ -6661,14 +6569,16 @@ HWTEST_F(TextFieldPatternTestNg, CalcCursorOffsetByPosition, TestSize.Level1) frameNode->GetOrCreateFocusHub()->currentFocus_ = true; /** - * @tc.steps: step2. set clipboard avoid nullptr and call CalcCursorOffsetByPosition. + * @tc.steps: step2. set clipboard avoid nullptr and call CalcCaretMetricsByPosition. * @tc.expected: Check it is not nullptr. */ textFieldPattern->textEditingValue_.caretPosition = 10; textFieldPattern->textEditingValue_.text = TEXT_VALUE; auto position = textFieldPattern->textEditingValue_.caretPosition; - textFieldPattern->CalcCursorOffsetByPosition(position, false); - textFieldPattern->CalcCursorOffsetByPosition(position, true); + CaretMetricsF baseMetrics; + CaretMetricsF destinationMetrics; + textFieldPattern->CalcCaretMetricsByPosition(position, baseMetrics); + textFieldPattern->CalcCaretMetricsByPosition(position, destinationMetrics, TextAffinity::UPSTREAM); /** * @tc.steps: step3. set contentSize and textSize. contentWidth less than textWidth. @@ -6709,20 +6619,20 @@ HWTEST_F(TextFieldPatternTestNg, GetDragUpperLeftCoordinates, TestSize.Level1) pattern_->textBoxes_.clear(); EXPECT_EQ(pattern_->GetDragUpperLeftCoordinates(), OffsetF(0.0f, 0.0f)); - RSTextRect front = {}; - front.rect.top_ = 0; - front.rect.left_ = 0; + RectF front = {}; + front.SetTop(0.0f); + front.SetLeft(0.0f); pattern_->textBoxes_.push_back(front); - RSTextRect back = {}; - back.rect.top_ = 10; + RectF back = {}; + back.SetTop(10.0f); pattern_->textBoxes_.push_back(back); EXPECT_EQ(pattern_->GetDragUpperLeftCoordinates(), OffsetF(0.0f, 0.0f)); pattern_->textBoxes_.clear(); - front.rect.top_ = -100; - front.rect.left_ = -100; + front.SetTop(-100.0f); + front.SetLeft(-100.0f); pattern_->textBoxes_.push_back(front); - back.rect.top_ = -100; + back.SetTop(-100.0f); pattern_->textBoxes_.push_back(back); EXPECT_EQ(pattern_->GetDragUpperLeftCoordinates(), OffsetF(0.0f, 0.0f)); } @@ -6841,7 +6751,7 @@ HWTEST_F(TextFieldPatternTestNg, TextAreaInputRectUpdate, TestSize.Level1) * @tc.steps: step2. call TextAreaInputRectUpdate. * @tc.expected: Check result. */ - RectF rect (0, 0, 100, 100); + RectF rect(0, 0, 100, 100); layoutProperty_->UpdateMaxLines(1); pattern_->TextAreaInputRectUpdate(rect); EXPECT_EQ(rect.Left(), 0); @@ -6867,7 +6777,7 @@ HWTEST_F(TextFieldPatternTestNg, TextAreaInputRectUpdate, TestSize.Level1) { TextAlign::START, 10, 0, 1, 0 }, { TextAlign::START, 0, 0, 10, 0 }, { TextAlign::CENTER, 10, 4.5, 1, 5 }, - {TextAlign::CENTER, 0, 0, 10, 0 }, + { TextAlign::CENTER, 0, 0, 10, 0 }, { TextAlign::END, 10, 7.5, 1, 8.5 }, { TextAlign::END, 0, 0, 10, -1.5 }, { TextAlign::LEFT, 0, 0, 10, 0 }, @@ -6995,9 +6905,7 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelection001, TestSize.Level1) pattern->textSelector_.destinationOffset = end; }; - auto switchNormalMode = [pattern = pattern_]() { - pattern->selectionMode_ = SelectionMode::NONE; - }; + auto switchNormalMode = [pattern = pattern_]() { pattern->selectionMode_ = SelectionMode::NONE; }; pattern_->UpdateEditingValue("ABCD", 4); pattern_->HandleSelectionEnd(); @@ -7041,9 +6949,7 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelection002, TestSize.Level1) pattern->textSelector_.destinationOffset = end; }; - auto switchNormalMode = [pattern = pattern_]() { - pattern->selectionMode_ = SelectionMode::NONE; - }; + auto switchNormalMode = [pattern = pattern_]() { pattern->selectionMode_ = SelectionMode::NONE; }; /** * @tc.steps: step1. call HandleSelectionLineEnd. @@ -7112,9 +7018,7 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelection003, TestSize.Level1) pattern->textSelector_.destinationOffset = end; }; - auto switchNormalMode = [pattern = pattern_]() { - pattern->selectionMode_ = SelectionMode::NONE; - }; + auto switchNormalMode = [pattern = pattern_]() { pattern->selectionMode_ = SelectionMode::NONE; }; /** * @tc.steps: step3. call HandleSelectionHome. @@ -7163,11 +7067,9 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelection004, TestSize.Level1) pattern->textSelector_.destinationOffset = end; }; - auto switchNormalMode = [pattern = pattern_]() { - pattern->selectionMode_ = SelectionMode::NONE; - }; + auto switchNormalMode = [pattern = pattern_]() { pattern->selectionMode_ = SelectionMode::NONE; }; - /** + /** * @tc.steps: step3. call HandleSelectionLineBegin. * @tc.expected: Check result. */ diff --git a/frameworks/core/components_v2/inspector/inspector_constants.cpp b/frameworks/core/components_v2/inspector/inspector_constants.cpp index 7a175c0a404..e94b60e476d 100644 --- a/frameworks/core/components_v2/inspector/inspector_constants.cpp +++ b/frameworks/core/components_v2/inspector/inspector_constants.cpp @@ -304,6 +304,7 @@ const char BADGE_ETS_TAG[] = "Badge"; // search const char SEARCH_COMPONENT_TAG[] = "SearchComponent"; const char SEARCH_ETS_TAG[] = "Search"; +const char SEARCH_Field_ETS_TAG[] = "SearchField"; // formComponent const char FORM_COMPONENT_TAG[] = "FormComponent"; diff --git a/frameworks/core/components_v2/inspector/inspector_constants.h b/frameworks/core/components_v2/inspector/inspector_constants.h index 0a3cd4d95b5..d1472c649cf 100644 --- a/frameworks/core/components_v2/inspector/inspector_constants.h +++ b/frameworks/core/components_v2/inspector/inspector_constants.h @@ -313,6 +313,7 @@ ACE_EXPORT extern const char BADGE_ETS_TAG[]; // search ACE_EXPORT extern const char SEARCH_COMPONENT_TAG[]; ACE_EXPORT extern const char SEARCH_ETS_TAG[]; +extern const char SEARCH_Field_ETS_TAG[]; // formComponent ACE_EXPORT extern const char FORM_COMPONENT_TAG[]; diff --git a/test/mock/core/render/mock_paragraph.h b/test/mock/core/render/mock_paragraph.h index e6404d10ff2..920e097f348 100644 --- a/test/mock/core/render/mock_paragraph.h +++ b/test/mock/core/render/mock_paragraph.h @@ -40,19 +40,24 @@ public: MOCK_METHOD0(GetLongestLine, float()); MOCK_METHOD0(GetMaxWidth, float()); MOCK_METHOD0(GetAlphabeticBaseline, float()); + MOCK_METHOD0(GetParagraphText, std::u16string()); MOCK_METHOD1(PushStyle, void(const TextStyle& style)); MOCK_METHOD1(AddText, void(const std::u16string& text)); MOCK_METHOD1(Layout, void(float width)); - MOCK_METHOD1(GetHandlePositionForClick, int32_t(const Offset& offset)); + MOCK_METHOD1(GetGlyphIndexByCoordinate, int32_t(const Offset& offset)); MOCK_METHOD1(AddPlaceholder, int32_t(const PlaceholderRun& span)); - MOCK_METHOD1(GetRectsForPlaceholders, void(std::vector& selectedRects)); + MOCK_METHOD1(GetRectsForPlaceholders, void(std::vector& selectedRects)); MOCK_METHOD1(SetIndents, void(const std::vector& indents)); - MOCK_METHOD2(ComputeOffsetForCaretDownstream, bool(int32_t extent, CaretMetrics& result)); - MOCK_METHOD2(ComputeOffsetForCaretUpstream, bool(int32_t extent, CaretMetrics& result)); - MOCK_METHOD3(GetRectsForRange, void(int32_t start, int32_t end, std::vector& selectedRects)); + MOCK_METHOD2(ComputeOffsetForCaretDownstream, bool(int32_t extent, CaretMetricsF& result)); + MOCK_METHOD2(ComputeOffsetForCaretUpstream, bool(int32_t extent, CaretMetricsF& result)); + MOCK_METHOD3(GetRectsForRange, void(int32_t start, int32_t end, std::vector& selectedRects)); MOCK_METHOD3(Paint, void(RSCanvas& canvas, float x, float y)); MOCK_METHOD3(Paint, void(SkCanvas* skCanvas, float x, float y)); MOCK_METHOD3(GetWordBoundary, bool(int32_t offset, int32_t& start, int32_t& end)); + MOCK_METHOD3( + CalcCaretMetricsByPosition, bool(int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity)); + MOCK_METHOD3( + CalcCaretMetricsByPosition, bool(int32_t extent, CaretMetricsF& caretCaretMetric, OffsetF lastTouchOffsetF)); static RefPtr GetOrCreateMockParagraph(); static void TearDown(); -- Gitee From b22531effb8e7378713f5dd5a1a1b30a0b7a1acd Mon Sep 17 00:00:00 2001 From: wangtao Date: Tue, 17 Oct 2023 18:37:52 +0800 Subject: [PATCH 02/31] =?UTF-8?q?SelectOverlay=20=E9=81=BF=E5=85=8D?= =?UTF-8?q?=E5=A4=9A=E4=BD=99=E7=9A=84=20Close=20=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao --- .../select_overlay/select_overlay_client.cpp | 55 +++++++++++++++---- .../select_overlay/select_overlay_client.h | 8 +++ .../select_overlay/select_overlay_proxy.cpp | 7 +++ .../select_overlay/select_overlay_proxy.h | 1 + .../select_overlay/select_overlay_pattern.cpp | 6 ++ .../select_overlay/select_overlay_pattern.h | 1 + .../pattern/text_field/text_field_pattern.cpp | 40 ++++++++------ .../pattern/text_field/text_field_pattern.h | 4 ++ .../text_field/text_select_controller.cpp | 2 + 9 files changed, 96 insertions(+), 28 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp index 4b2c097ce46..c57660745f1 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -90,9 +90,7 @@ void SelectOverlayClient::RequestOpenSelectOverlay(ClientOverlayInfo showOverlay } else { showMode = HandleShowMode::NONE; } - if (!selectOverlayProxy_ || selectOverlayProxy_->IsClosed()) { - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(pipeline); + auto getSelectOverlay = [&]() -> std::optional { SelectOverlayInfo overlayInfo = selectOverlayInfo_; if (showOverlayInfo.overlayInfoModifier) { showOverlayInfo.overlayInfoModifier(overlayInfo); @@ -104,23 +102,58 @@ void SelectOverlayClient::RequestOpenSelectOverlay(ClientOverlayInfo showOverlay if (!GetMenuOptionItems().empty()) { overlayInfo.menuOptionItems = GetMenuOptionItems(); } - if (!OnPreShowSelectOverlay(overlayInfo, showOverlayInfo.extraInfo)) { - return; + if (OnPreShowSelectOverlay(overlayInfo, showOverlayInfo.extraInfo)) { + return overlayInfo; } + return std::nullopt; + }; + auto currentShowMode = IsShowingSingleHandle() ? HandleShowMode::SINGLE : HandleShowMode::DOUBLE; + if (showMode != currentShowMode) { + RequestCloseSelectOverlay(true); + } + if (SelectOverlayIsOn()) { + auto overlayInfo = getSelectOverlay(); + CHECK_NULL_VOID(overlayInfo); + UpdateShowingSelectOverlay(showMode, *overlayInfo); + return; + } + if (!SelectOverlayIsOn()) { + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto overlayInfo = getSelectOverlay(); + CHECK_NULL_VOID(overlayInfo); LOGD("first handle visibility %{public}d, second handle visibility %{public}d, select rect visibility " "%{public}d", overlayInfo.firstHandle.isShow, overlayInfo.secondHandle.isShow, overlayInfo.isSelectRegionVisible); selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( - overlayInfo, WeakClaim(this), showOverlayInfo.animation); + *overlayInfo, WeakClaim(this), showOverlayInfo.animation); StartListeningScrollableParent(GetClientHost()); - return; } - if (showMode == HandleShowMode::DOUBLE) { - selectOverlayProxy_->UpdateFirstAndSecondHandleInfo(*firstHandleInfo, *secondHandleInfo); +} + +void SelectOverlayClient::UpdateShowingSelectOverlay(HandleShowMode mode, const SelectOverlayInfo& overlayInfo) +{ + if (mode == HandleShowMode::SINGLE) { + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + proxy->UpdateSelectMenuInfo([newMenuInfo = overlayInfo.menuInfo](SelectMenuInfo& menuInfo) { + menuInfo.showPaste = newMenuInfo.showPaste; + menuInfo.showCopyAll = true; + }); + proxy->UpdateSecondSelectHandleInfo(overlayInfo.secondHandle); return; } - if (showMode == HandleShowMode::SINGLE) { - selectOverlayProxy_->UpdateSecondSelectHandleInfo(*secondHandleInfo); + + if (mode == HandleShowMode::DOUBLE) { + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + proxy->UpdateSelectMenuInfo([newMenuInfo = overlayInfo.menuInfo](SelectMenuInfo& menuInfo) { + menuInfo.showPaste = newMenuInfo.showPaste; + menuInfo.showCopyAll = newMenuInfo.showCopyAll; + menuInfo.showCopy = newMenuInfo.showCopy; + menuInfo.showCut = newMenuInfo.showCut; + }); + proxy->UpdateFirstAndSecondHandleInfo(overlayInfo.firstHandle, overlayInfo.secondHandle); } } diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h index cbac38c20fb..49649c87eed 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h @@ -136,6 +136,13 @@ public: void UpdateSelectMenuVisibility(bool isVisible); + bool IsShowingSingleHandle() + { + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_RETURN(proxy, false); + return proxy->IsSingleHandle(); + } + protected: const RefPtr& GetSelectOverlayProxy() { @@ -149,6 +156,7 @@ protected: } private: + void UpdateShowingSelectOverlay(HandleShowMode mode, const SelectOverlayInfo& overlayInfo); ParentScrollableCallback scrollCallback_; ScrollableParentInfo scrollableParentInfo_; SelectOverlayInfo selectOverlayInfo_; diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp index 465f62c81dd..d570a1ded20 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp @@ -146,4 +146,11 @@ bool SelectOverlayProxy::IsHandleShow() CHECK_NULL_RETURN(pattern, false); return pattern->IsHandleShow(); } + +bool SelectOverlayProxy::IsSingleHandle() +{ + auto pattern = GetSelectOverlayPattern(selectOverlayId_); + CHECK_NULL_RETURN(pattern, false); + return pattern->IsSingleHandle(); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h index 7de93856245..943ff819033 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.h @@ -64,6 +64,7 @@ public: void DisableMenu(bool isDisabled); bool IsMenuShow(); bool IsHandleShow(); + bool IsSingleHandle(); private: int32_t selectOverlayId_ = 0; diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp index 36502d946a6..f2598280edb 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp @@ -549,6 +549,12 @@ bool SelectOverlayPattern::IsHandleShow() return info_->firstHandle.isShow || info_->secondHandle.isShow; } +bool SelectOverlayPattern::IsSingleHandle() +{ + CHECK_NULL_RETURN(info_, false); + return info_->isSingleHandle; +} + void SelectOverlayPattern::StartHiddenHandleTask() { auto host = GetHost(); diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h index 689cd91ac2c..1f5749e84e0 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.h @@ -145,6 +145,7 @@ public: bool IsMenuShow(); bool IsHandleShow(); + bool IsSingleHandle(); void SetHasShowAnimation(bool animation) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 50da04e93f9..6a631cf26bf 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -324,7 +324,7 @@ void TextFieldPattern::UpdateCaretInfoToController() const // todo确定更新 // return: true if text rect offset will NOT be further changed by caret position void TextFieldPattern::UpdateCaretRect() { - CHECK_NULL_VOID(!selectController_->IsSelected()); + CHECK_NULL_VOID(!IsSelected()); auto focusHub = GetFocusHub(); if (focusHub && !focusHub->IsCurrentFocus()) { CloseSelectOverlay(true); @@ -629,12 +629,13 @@ void TextFieldPattern::HandleSetSelection(int32_t start, int32_t end, bool showH { // todo LOGI("HandleSetSelection %{public}d, %{public}d", start, end); - CloseSelectOverlay(); StopTwinkling(); UpdateSelection(start, end); AdjustTextSelectionRectOffsetX(); if (showHandle) { ProcessOverlay(); + } else { + CloseSelectOverlay(); } UpdateCaretInfoToController(); auto tmpHost = GetHost(); @@ -871,8 +872,8 @@ void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) } else { UpdateSelection(0, textSize); } - if (selectController_->IsSelected()) { - isSingleHandle_ = false; + if (IsSelected()) { + SetIsSingleHandle(false); } updateSelectionAfterObscure_ = ResetObscureTickCountDown(); GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); @@ -885,9 +886,9 @@ void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) textRect_.SetLeft(textRect_.GetX() - offsetX); } selectController_->MoveSecondHandleToContentRect(textSize); - CloseSelectOverlay(true); StopTwinkling(); if (isKeyEvent || inlineSelectAllFlag_) { + CloseSelectOverlay(true); return; } ProcessOverlay(true); @@ -1421,6 +1422,11 @@ void TextFieldPattern::HandleClickEvent(GestureEvent& info) } else { HandleSingleClickEvent(info); } + if (ResetObscureTickCountDown()) { + auto host = GetHost(); + CHECK_NULL_VOID(host); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } } void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) @@ -1436,12 +1442,11 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) return; } auto layoutProperty = GetLayoutProperty(); - CloseSelectOverlay(true); - ResetObscureTickCountDown(); auto hasFocus = HasFocus(); if (!hasFocus) { if (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately()) { LOGW("Request focus failed, cannot open input method"); + CloseSelectOverlay(true); StopTwinkling(); return; } @@ -1449,10 +1454,12 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) auto lastCaretIndex = selectController_->GetCaretIndex(); selectController_->UpdateCaretInfoByOffset(info.GetLocalLocation()); StartTwinkling(); - isSingleHandle_ = true; + SetIsSingleHandle(true); if (lastCaretIndex == selectController_->GetCaretIndex() && hasFocus && caretStatus_ == CaretStatus::SHOW && - !isUsingMouse_ && !selectController_->IsSelected()) { + !isUsingMouse_ && !IsSelected()) { ProcessOverlay(true); + } else { + CloseSelectOverlay(true); } if (RequestKeyboard(false, true, true)) { @@ -1466,12 +1473,11 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) void TextFieldPattern::HandleDoubleClickEvent(GestureEvent& info) { selectController_->UpdateSelectByOffset(info.GetLocalLocation()); - if (selectController_->IsSelected()) { + if (IsSelected()) { StopTwinkling(); - isSingleHandle_ = false; + SetIsSingleHandle(false); } if (!isUsingMouse_) { - CloseSelectOverlay(); ProcessOverlay(true); } auto host = GetHost(); @@ -1904,8 +1910,8 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) selectController_->UpdateSelectByOffset(info.GetLocalLocation()); if (IsSelected()) { StopTwinkling(); - isSingleHandle_ = false; } + SetIsSingleHandle(!IsSelected()); ProcessOverlay(true); host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -2341,7 +2347,7 @@ void TextFieldPattern::HandleLeftMouseEvent(MouseInfo& info) void TextFieldPattern::HandleLeftMousePressEvent(MouseInfo& info) { - if (selectController_->IsSelected() && BetweenSelectedPosition(info.GetGlobalLocation())) { + if (IsSelected() && BetweenSelectedPosition(info.GetGlobalLocation())) { blockPress_ = true; return; } @@ -4728,7 +4734,7 @@ bool TextFieldPattern::CheckHandleVisible(const RectF& paintRect) bool TextFieldPattern::CheckSelectionRectVisible() { - if (!selectController_->IsSelected()) { + if (!IsSelected()) { return false; } std::vector selectedRects; @@ -4873,7 +4879,7 @@ void TextFieldPattern::UpdateSelectController() bool TextFieldPattern::IsSingleHandle() const { - return contentController_->IsEmpty() || !selectController_->IsSelected(); + return contentController_->IsEmpty() || !IsSelected(); } void TextFieldPattern::OnAttachToFrameNode() @@ -4894,7 +4900,7 @@ bool TextFieldPattern::NeedPaintSelect() CHECK_NULL_RETURN(paintProperty, false); auto firstHandle = paintProperty->GetFirstHandleInfo(); auto secondHandle = paintProperty->GetSecondHandleInfo(); - if (!selectController_->IsSelected()) { + if (!IsSelected()) { if (!firstHandle.has_value() || !secondHandle.has_value()) { paintProperty->UpdateFirstHandleInfo(selectController_->GetCaretInfo()); paintProperty->UpdateSecondHandleInfo(selectController_->GetCaretInfo()); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 30d319fa447..2df1fc16764 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -1115,6 +1115,10 @@ private: std::optional GetMiscTextConfig() const; #endif bool IsSingleHandle() const; + void SetIsSingleHandle(bool isSingleHandle) + { + isSingleHandle_ = isSingleHandle; + } RectF frameRect_; RectF contentRect_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 84cd3a4db7f..419da9fa3e3 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -151,6 +151,8 @@ void TextSelectController::UpdateSelectByOffset(const Offset& localOffset) UpdateHandleIndex(start, end); if (IsSelected()) { MoveSecondHandleToContentRect(GetSecondHandleIndex()); + } else { + MoveCaretToContentRect(GetCaretIndex()); } } -- Gitee From 0df406926cb13ffc0b63282d1e6b6f88d3fe8892 Mon Sep 17 00:00:00 2001 From: wangtao Date: Wed, 18 Oct 2023 09:16:23 +0800 Subject: [PATCH 03/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E6=A1=86=E6=9D=A5=E5=9B=9E=E7=82=B9=E5=87=BB?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E9=81=BF=E8=AE=A9=E9=94=AE=E7=9B=98=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao --- .../pattern/text_field/text_field_pattern.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 6a631cf26bf..7cdc865dfc8 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1461,12 +1461,7 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) } else { CloseSelectOverlay(true); } - - if (RequestKeyboard(false, true, true)) { - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); // 事件可能重复上报待整改 - } + needToRequestKeyboardInner_ = true; host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } -- Gitee From c4e09b2aa334591ae8e42e9477370d4d3832fbfb Mon Sep 17 00:00:00 2001 From: liyujie Date: Wed, 18 Oct 2023 15:05:32 +0800 Subject: [PATCH 04/31] fix unittest compile and add text field unittest cases Signed-off-by: liyujie Change-Id: I336aea05181befb54ce6433f1ad13831b5413374 --- frameworks/core/common/container.h | 16 +- .../core/components_ng/base/frame_node.cpp | 1 - .../pattern/overlay/overlay_manager.h | 23 +- .../pattern/text/text_model_ng.h | 1 - .../text_field/text_field_controller.cpp | 17 +- .../pattern/text_field/text_field_pattern.cpp | 4 +- .../pattern/text_field/text_field_pattern.h | 24 +- .../drag_drop/drag_drop_proxy/BUILD.gn | 5 +- .../select_overlay_manager/BUILD.gn | 5 +- .../select_overlay_proxy/BUILD.gn | 5 +- .../test/mock/render/mock_render_context.h | 9 +- .../core/components_ng/test/pattern/BUILD.gn | 8 +- .../test/pattern/app_bar/BUILD.gn | 1 - .../test/pattern/bubble/BUILD.gn | 5 +- .../test/pattern/button/BUILD.gn | 1 - .../test/pattern/calendar/BUILD.gn | 5 +- .../test/pattern/calendar_picker/BUILD.gn | 1 - .../test/pattern/container_modal/BUILD.gn | 1 - .../test/pattern/counter/BUILD.gn | 5 +- .../test/pattern/dialog/BUILD.gn | 5 +- .../components_ng/test/pattern/form/BUILD.gn | 1 - .../components_ng/test/pattern/gauge/BUILD.gn | 1 - .../components_ng/test/pattern/grid/BUILD.gn | 1 - .../test/pattern/grid/grid_test_ng.cpp | 8 +- .../test/pattern/grid_container/BUILD.gn | 5 +- .../test/pattern/hyperlink/BUILD.gn | 5 +- .../components_ng/test/pattern/image/BUILD.gn | 5 +- .../test/pattern/image_animator/BUILD.gn | 5 +- .../test/pattern/indexer/BUILD.gn | 1 - .../components_ng/test/pattern/list/BUILD.gn | 1 - .../test/pattern/list/list_test_ng.cpp | 6 - .../test/pattern/marquee/BUILD.gn | 5 +- .../components_ng/test/pattern/menu/BUILD.gn | 5 +- .../test/pattern/menu/menu_test_ng.cpp | 5 +- .../test/pattern/navigation/BUILD.gn | 235 +---- .../test/pattern/navigator/BUILD.gn | 11 +- .../navigator/navigator_pattern_test_ng.cpp | 13 +- .../test/pattern/navrouter/BUILD.gn | 1 - .../test/pattern/option/BUILD.gn | 5 +- .../test/pattern/overlay/BUILD.gn | 292 +----- .../overlay/overlay_manager_test_ng.cpp | 14 +- .../components_ng/test/pattern/panel/BUILD.gn | 1 - .../test/pattern/picker/BUILD.gn | 3 +- ...er_test_ng.cpp => date_picker_test_ng.cpp} | 0 .../test/pattern/progress/BUILD.gn | 5 +- .../test/pattern/refresh/BUILD.gn | 1 - .../test/pattern/rich_editor/BUILD.gn | 1 - .../test/pattern/scroll/BUILD.gn | 1 - .../test/pattern/search/BUILD.gn | 1 - .../test/pattern/search/search_test_ng.cpp | 27 +- .../test/pattern/security_component/BUILD.gn | 129 +-- ..._ng.cpp => security_component_test_ng.cpp} | 0 .../test/pattern/select/BUILD.gn | 1 - .../test/pattern/select_overlay/BUILD.gn | 196 +--- .../test/pattern/side_bar/BUILD.gn | 1 - .../test/pattern/slider/BUILD.gn | 1 - .../test/pattern/stepper/BUILD.gn | 1 - .../test/pattern/swiper/BUILD.gn | 5 +- .../components_ng/test/pattern/tabs/BUILD.gn | 182 +--- .../test/pattern/tabs/tabs_test_ng.cpp | 2 +- .../components_ng/test/pattern/test_ng.cpp | 6 +- .../core/components_ng/test/pattern/test_ng.h | 12 +- .../components_ng/test/pattern/text/BUILD.gn | 167 +-- .../pattern/text/mock/mock_text_theme.cpp | 35 - .../test/pattern/text/text_test_ng.cpp | 3 - .../test/pattern/text_clock/BUILD.gn | 5 +- .../test/pattern/text_field/BUILD.gn | 19 + .../text_field_test_ng.cpp} | 990 +----------------- .../test/pattern/text_picker/BUILD.gn | 3 +- ...er_test_ng.cpp => text_picker_test_ng.cpp} | 0 .../{texttimer => text_timer}/BUILD.gn | 5 +- .../text_timer_test_ng.cpp | 0 .../test/pattern/textfield/BUILD.gn | 223 ---- .../test/pattern/time_picker/BUILD.gn | 3 +- ...er_test_ng.cpp => time_picker_test_ng.cpp} | 0 .../test/pattern/waterflow/BUILD.gn | 1 - .../window_scene/mock_window_pattern.cpp | 40 - test/mock/core/render/mock_paragraph.h | 4 +- test/unittest/BUILD.gn | 8 + test/unittest/ace_unittest.gni | 3 + .../base/frame_node/frame_node_test_ng.cpp | 8 +- .../unittest/core/base/view_abstract/BUILD.gn | 6 +- test/unittest/core/pattern/badge/BUILD.gn | 5 +- .../unittest/core/pattern/text_field/BUILD.gn | 5 +- .../pattern/text_field/text_field_test.cpp | 523 ++++----- test/unittest/core/pattern/video/BUILD.gn | 1 - test/unittest/core/pipeline/BUILD.gn | 1 + 87 files changed, 472 insertions(+), 2929 deletions(-) rename frameworks/core/components_ng/test/pattern/picker/{datepicker_test_ng.cpp => date_picker_test_ng.cpp} (100%) rename frameworks/core/components_ng/test/pattern/security_component/{security_component_model_test_ng.cpp => security_component_test_ng.cpp} (100%) delete mode 100644 frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp create mode 100644 frameworks/core/components_ng/test/pattern/text_field/BUILD.gn rename frameworks/core/components_ng/test/pattern/{textfield/textfield_test_ng.cpp => text_field/text_field_test_ng.cpp} (87%) rename frameworks/core/components_ng/test/pattern/text_picker/{textpicker_test_ng.cpp => text_picker_test_ng.cpp} (100%) rename frameworks/core/components_ng/test/pattern/{texttimer => text_timer}/BUILD.gn (86%) rename frameworks/core/components_ng/test/pattern/{texttimer => text_timer}/text_timer_test_ng.cpp (100%) delete mode 100644 frameworks/core/components_ng/test/pattern/textfield/BUILD.gn rename frameworks/core/components_ng/test/pattern/time_picker/{timepicker_test_ng.cpp => time_picker_test_ng.cpp} (100%) delete mode 100644 test/mock/core/pattern/window_scene/mock_window_pattern.cpp diff --git a/frameworks/core/common/container.h b/frameworks/core/common/container.h index 143cfebf8f1..84089921454 100755 --- a/frameworks/core/common/container.h +++ b/frameworks/core/common/container.h @@ -312,7 +312,7 @@ public: return false; } - virtual void NotifyConfigurationChange(bool, const OnConfigurationChange& configurationChange = {false, false}) {} + virtual void NotifyConfigurationChange(bool, const OnConfigurationChange& configurationChange = { false, false }) {} virtual void HotReload() {} void SetIsModule(bool isModule) @@ -358,20 +358,14 @@ public: static bool LessThanAPIVersion(PlatformVersion version) { - if (PipelineBase::GetCurrentContext() && - PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < static_cast(version)) { - return true; - } - return false; + return PipelineBase::GetCurrentContext() && + PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < static_cast(version); } static bool GreatOrEqualAPIVersion(PlatformVersion version) { - if (PipelineBase::GetCurrentContext() && - PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= static_cast(version)) { - return true; - } - return false; + return PipelineBase::GetCurrentContext() && + PipelineBase::GetCurrentContext()->GetMinPlatformVersion() >= static_cast(version); } protected: diff --git a/frameworks/core/components_ng/base/frame_node.cpp b/frameworks/core/components_ng/base/frame_node.cpp index 01aa43e5280..b709dfa1c01 100644 --- a/frameworks/core/components_ng/base/frame_node.cpp +++ b/frameworks/core/components_ng/base/frame_node.cpp @@ -975,7 +975,6 @@ void FrameNode::CreateLayoutTask(bool forceUseMainThread) Layout(); } SetRootMeasureNode(false); - return; } std::optional FrameNode::CreateRenderTask(bool forceUseMainThread) diff --git a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h index 0310c25e7ee..3d92fe9ce96 100644 --- a/frameworks/core/components_ng/pattern/overlay/overlay_manager.h +++ b/frameworks/core/components_ng/pattern/overlay/overlay_manager.h @@ -90,10 +90,7 @@ public: bool HasPopupInfo(int32_t targetId) const { - if (popupMap_.find(targetId) != popupMap_.end()) { - return true; - } - return false; + return popupMap_.find(targetId) != popupMap_.end(); } void ShowMenu(int32_t targetId, const NG::OffsetF& offset, RefPtr menu = nullptr); @@ -256,12 +253,12 @@ public: void RemoveEventColumn(); #endif // ENABLE_DRAG_FRAMEWORK void BindContentCover(bool isShow, std::function&& callback, - std::function()>&& buildNodeFunc, NG::ModalStyle& modalStyle, - std::function&& onAppear, std::function&& onDisappear, int32_t targetId); + std::function()>&& buildNodeFunc, NG::ModalStyle& modalStyle, std::function&& onAppear, + std::function&& onDisappear, int32_t targetId); void BindSheet(bool isShow, std::function&& callback, - std::function()>&& buildNodeFunc, NG::SheetStyle& sheetStyle, - std::function&& onAppear, std::function&& onDisappear, int32_t targetId); + std::function()>&& buildNodeFunc, NG::SheetStyle& sheetStyle, std::function&& onAppear, + std::function&& onDisappear, int32_t targetId); void DestroySheet(const RefPtr& sheetNode, int32_t targetId); @@ -349,14 +346,14 @@ private: std::stack> modalStack_; std::list> modalList_; WeakPtr lastModalNode_; - float sheetHeight_ {0.0}; + float sheetHeight_ { 0.0 }; WeakPtr rootNodeWeak_; int32_t dialogCount_ = 0; #ifdef ENABLE_DRAG_FRAMEWORK - bool hasPixelMap_ {false}; - bool hasFilter_ {false}; - bool hasEvent_ {false}; - bool isOnAnimation_ {false}; + bool hasPixelMap_ { false }; + bool hasFilter_ { false }; + bool hasEvent_ { false }; + bool isOnAnimation_ { false }; WeakPtr pixmapColumnNodeWeak_; WeakPtr filterColumnNodeWeak_; WeakPtr eventColumnNodeWeak_; diff --git a/frameworks/core/components_ng/pattern/text/text_model_ng.h b/frameworks/core/components_ng/pattern/text/text_model_ng.h index cb5bd14b1c1..aa57413a27d 100644 --- a/frameworks/core/components_ng/pattern/text/text_model_ng.h +++ b/frameworks/core/components_ng/pattern/text/text_model_ng.h @@ -62,7 +62,6 @@ public: void SetOnDrop(NG::OnDragDropFunc&& onDrop) override; void SetDraggable(bool draggable) override; void SetMenuOptionItems(std::vector&& menuOptionsItems) override; - }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp index e45665d0f34..3909c9eeca1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp @@ -60,14 +60,14 @@ Rect TextFieldController::GetTextContentRect() rect.SetTop(y); textFieldPattern->UpdateRectByAlignment(rect); if (textFieldPattern->IsOperation()) { - return Rect(rect.GetX(), rect.GetY(), rect.Width(), rect.Height()); + return { rect.GetX(), rect.GetY(), rect.Width(), rect.Height() }; } if (NearEqual(rect.GetX(), -Infinity())) { - return Rect(textFieldPattern->GetPaddingLeft(), rect.GetY(), 0, 0); + return { textFieldPattern->GetPaddingLeft(), rect.GetY(), 0, 0 }; } - return Rect(rect.GetX(), rect.GetY(), 0, 0); + return { rect.GetX(), rect.GetY(), 0, 0 }; } - return Rect(0, 0, 0, 0); + return { 0, 0, 0, 0 }; } int32_t TextFieldController::GetTextContentLinesNum() @@ -79,15 +79,14 @@ int32_t TextFieldController::GetTextContentLinesNum() return lines; } RectF textRect = textFieldPattern->GetTextRect(); - - if ((int32_t)textFieldPattern->GetLineHeight() == 0) { + + if (static_cast(textFieldPattern->GetLineHeight()) == 0) { return lines; } - lines = (int32_t)textRect.Height() / (int32_t)textFieldPattern->GetLineHeight(); + lines = static_cast(textRect.Height()) / static_cast(textFieldPattern->GetLineHeight()); return lines; - } else { - lines = getTextContentLinesNum_(); } + lines = getTextContentLinesNum_(); return lines; } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 7cdc865dfc8..59dbfbbe8bb 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1162,9 +1162,9 @@ void TextFieldPattern::HandleTouchUp() } } +#ifdef ENABLE_DRAG_FRAMEWORK void TextFieldPattern::InitDragEvent() { -#ifdef ENABLE_DRAG_FRAMEWORK auto host = GetHost(); CHECK_NULL_VOID(host); auto layoutProperty = host->GetLayoutProperty(); @@ -1177,10 +1177,8 @@ void TextFieldPattern::InitDragEvent() ClearDragDropEvent(); RemoveDragFrameNodeFromManager(host); } -#endif // ENABLE_DRAG_FRAMEWORK } -#ifdef ENABLE_DRAG_FRAMEWORK std::function TextFieldPattern::GetThumbnailCallback() { auto callback = [weak = WeakClaim(this)](const Offset& point) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 2df1fc16764..82d3ccc3de7 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -221,9 +221,6 @@ public: } void OnModifyDone() override; - - void UpdateCaretPositionByTextEdit(); - void UpdateCaretPositionByPressOffset(); void UpdateSelectionOffset(); void CalcCaretMetricsByPosition( int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity = TextAffinity::DOWNSTREAM); @@ -277,10 +274,7 @@ public: selectController_->UpdateCaretIndex(caretPosition); } void SetEditingValueToProperty(const std::string& newValueText); - - // void UpdatePositionOfParagraph(int32_t pos); void UpdateCaretPositionByTouch(const Offset& offset); - void UpdateCaretOffsetByEvent(); bool IsReachedBoundary(float offset); virtual TextInputAction GetDefaultTextInputAction(); @@ -495,7 +489,6 @@ public: bool CursorMoveUp() override; bool CursorMoveDown() override; void SetCaretPosition(int32_t position); - void SetTextSelection(int32_t selectionStart, int32_t selectionEnd); void HandleSetSelection(int32_t start, int32_t end, bool showHandle = true) override; void HandleExtendAction(int32_t action) override; void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override; @@ -915,7 +908,7 @@ public: isCustomFont_ = isCustomFont; } - bool GetIsCustomFont() + bool GetIsCustomFont() const { return isCustomFont_; } @@ -1002,8 +995,6 @@ private: void ClearDragDropEvent(); std::function GetThumbnailCallback(); #endif - bool CaretPositionCloseToTouchPosition(); - void CreateSingleHandle(bool animation = false, bool isMenuShow = true); int32_t UpdateCaretPositionOnHandleMove(const OffsetF& localOffset); bool HasStateStyle(UIState state) const; @@ -1022,9 +1013,6 @@ private: void HandleLeftMouseReleaseEvent(MouseInfo& info); void HandleLongPress(GestureEvent& info); void UpdateCaretPositionWithClamp(const int32_t& pos); - // assert handles are inside the contentRect, reset them if not - void CheckHandles(std::optional& firstHandle, std::optional& secondHandle, - float firstHandleSize = 0.0f, float secondHandleSize = 0.0f); void ShowSelectOverlay(const std::optional& firstHandle, const std::optional& secondHandle, bool animation = false, bool isMenuShow = true); @@ -1053,9 +1041,7 @@ private: void UpdateSelection(int32_t both); void UpdateSelection(int32_t start, int32_t end); void FireOnSelectionChange(int32_t start, int32_t end); - void UpdateDestinationToCaretByEvent(); void UpdateCaretPositionByLastTouchOffset(); - bool UpdateCaretPositionByMouseMovement(); bool UpdateCaretPosition(); void UpdateCaretRect(); void AdjustTextInReasonableArea(); @@ -1075,14 +1061,6 @@ private: void Delete(int32_t start, int32_t end); bool OnDirtyLayoutWrapperSwap(const RefPtr& dirty, const DirtySwapConfig& config) override; - // void BeforeCreateLayoutWrapper() override; - - bool FilterWithRegex( - const std::string& filter, const std::string& valueToUpdate, std::string& result, bool needToEscape = false); - bool FilterWithAscii(const std::string& valueToUpdate, std::string& result); - bool FilterWithEmail(std::string& result); - void EditingValueFilter(std::string& valueToUpdate, std::string& result, bool isInsertValue = false); - bool LastTouchIsInSelectRegion(const std::vector& boxes); bool CursorInContentRegion(); float FitCursorInSafeArea(); bool OffsetInContentRegion(const Offset& offset); diff --git a/frameworks/core/components_ng/test/manager/drag_drop/drag_drop_proxy/BUILD.gn b/frameworks/core/components_ng/test/manager/drag_drop/drag_drop_proxy/BUILD.gn index 55e8425d7c8..7c062a1b564 100644 --- a/frameworks/core/components_ng/test/manager/drag_drop/drag_drop_proxy/BUILD.gn +++ b/frameworks/core/components_ng/test/manager/drag_drop/drag_drop_proxy/BUILD.gn @@ -16,8 +16,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("drag_drop_proxy_test_ng") { type = "new" module_output = "manager" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "drag_drop_proxy_test_ng.cpp", - ] + sources = [ "drag_drop_proxy_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_manager/BUILD.gn b/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_manager/BUILD.gn index 0208e0ab653..82609b393a1 100644 --- a/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_manager/BUILD.gn +++ b/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_manager/BUILD.gn @@ -16,8 +16,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("select_overlay_manager_test_ng") { type = "new" module_output = "manager" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "select_overlay_manager_test_ng.cpp", - ] + sources = [ "select_overlay_manager_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_proxy/BUILD.gn b/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_proxy/BUILD.gn index ac21b7055c6..185411a129a 100644 --- a/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_proxy/BUILD.gn +++ b/frameworks/core/components_ng/test/manager/select_overlay/select_overlay_proxy/BUILD.gn @@ -16,8 +16,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("select_overlay_proxy_test_ng") { type = "new" module_output = "manager" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "select_overlay_proxy_test_ng.cpp", - ] + sources = [ "select_overlay_proxy_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/mock/render/mock_render_context.h b/frameworks/core/components_ng/test/mock/render/mock_render_context.h index 19b1338b79e..dd71c2f3d44 100644 --- a/frameworks/core/components_ng/test/mock/render/mock_render_context.h +++ b/frameworks/core/components_ng/test/mock/render/mock_render_context.h @@ -18,6 +18,8 @@ #include "gmock/gmock.h" +#include "base/geometry/ng/point_t.h" +#include "base/geometry/ng/rect_t.h" #include "core/components_ng/render/render_context.h" namespace OHOS::Ace::NG { @@ -27,7 +29,6 @@ public: ~MockRenderContext() override = default; MOCK_METHOD4(SetBounds, void(float, float, float, float)); - MOCK_METHOD0(GetPaintRectWithTransform, RectF()); MOCK_METHOD1(GetPointWithTransform, void(PointF&)); MOCK_METHOD2(AddChild, void(const RefPtr& renderContext, int index)); MOCK_METHOD1(AnimateHoverEffectScale, void(bool)); @@ -48,6 +49,12 @@ public: return transInfo_; } + RectF GetPaintRectWithTransform() override + { + return rect_; + } + + RectF rect_; Color blendColor_ = Color::TRANSPARENT; std::vector transInfo_ = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; }; diff --git a/frameworks/core/components_ng/test/pattern/BUILD.gn b/frameworks/core/components_ng/test/pattern/BUILD.gn index 48879e53502..519cd006e2a 100644 --- a/frameworks/core/components_ng/test/pattern/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/BUILD.gn @@ -48,7 +48,7 @@ group("pattern_unittest") { "marquee:marquee_test_ng", "menu:menu_test_ng", "navigation:navigation_test_ng", - "navigator:navigator_event_hub_test_ng", + "navigator:navigator_test_ng", "navrouter:navrouter_test_ng", "option:option_test_ng", "overlay:overlay_manager_test_ng", @@ -68,7 +68,7 @@ group("pattern_unittest") { "scroll_bar:scroll_bar_test_ng", "scrollable:scrollable_test_ng", "search:search_test_ng", - "security_component:security_component_pattern_test_ng", + "security_component:security_component_test_ng", "select:select_pattern_test_ng", "select_overlay:select_overlay_test_ng", "shape:shape_test_ng", @@ -81,9 +81,9 @@ group("pattern_unittest") { "text:text_test_ng", "text_clock:text_clock_test_ng", "text_drag:text_drag_test_ng", + "text_field:text_field_test_ng", "text_picker:text_picker_test_ng", - "textfield:textfield_test_ng", - "texttimer:text_timer_test_ng", + "text_timer:text_timer_test_ng", "time_picker:time_picker_test_ng", "waterflow:water_flow_test_ng", "web:web_pattern_unit_test", diff --git a/frameworks/core/components_ng/test/pattern/app_bar/BUILD.gn b/frameworks/core/components_ng/test/pattern/app_bar/BUILD.gn index fe776336669..b2dd156b524 100644 --- a/frameworks/core/components_ng/test/pattern/app_bar/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/app_bar/BUILD.gn @@ -19,7 +19,6 @@ ace_unittest("app_bar_test_ng") { "$ace_root/frameworks/core/components_ng/test/mock/pattern/ui_extension/mock_ui_extension_model_ng.cpp", "$ace_root/frameworks/core/components_ng/test/mock/theme/mock_theme_constants.cpp", "$ace_root/test/mock/adapter/mock_app_bar_helper_impl.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "app_bar_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/bubble/BUILD.gn b/frameworks/core/components_ng/test/pattern/bubble/BUILD.gn index d9a5ee1cbff..c466d9c5ae5 100644 --- a/frameworks/core/components_ng/test/pattern/bubble/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/bubble/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("bubble_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "bubble_test_ng.cpp", - ] + sources = [ "bubble_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/button/BUILD.gn b/frameworks/core/components_ng/test/pattern/button/BUILD.gn index a13d274d36e..7be30fd6440 100644 --- a/frameworks/core/components_ng/test/pattern/button/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/button/BUILD.gn @@ -16,7 +16,6 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("button_test_ng") { type = "new" sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "button_test_ng.cpp", "toggle_button_test_ng.cpp", ] diff --git a/frameworks/core/components_ng/test/pattern/calendar/BUILD.gn b/frameworks/core/components_ng/test/pattern/calendar/BUILD.gn index 3b36194e1d3..079949642bb 100644 --- a/frameworks/core/components_ng/test/pattern/calendar/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/calendar/BUILD.gn @@ -16,8 +16,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("calendar_test_ng") { flutter_skia = true type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "calendar_test_ng.cpp", - ] + sources = [ "calendar_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/calendar_picker/BUILD.gn b/frameworks/core/components_ng/test/pattern/calendar_picker/BUILD.gn index 2871dc0e705..f16a09e79e8 100644 --- a/frameworks/core/components_ng/test/pattern/calendar_picker/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/calendar_picker/BUILD.gn @@ -18,7 +18,6 @@ ace_unittest("calendar_picker_test_ng") { sources = [ "$ace_root/frameworks/core/components/picker/picker_data.cpp", "$ace_root/frameworks/core/components/test/unittest/mock/subwindow_mock.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "calendar_picker_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/container_modal/BUILD.gn b/frameworks/core/components_ng/test/pattern/container_modal/BUILD.gn index 6d54a6f6e78..19be9b28548 100644 --- a/frameworks/core/components_ng/test/pattern/container_modal/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/container_modal/BUILD.gn @@ -19,7 +19,6 @@ ace_unittest("container_modal_test_ng") { "$ace_root/frameworks/core/components_ng/test/mock/theme/mock_theme_constants.cpp", "$ace_root/frameworks/core/components_ng/test/mock/theme/mock_theme_utils.cpp", "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "container_modal_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/counter/BUILD.gn b/frameworks/core/components_ng/test/pattern/counter/BUILD.gn index 65946181df1..df8e3639364 100644 --- a/frameworks/core/components_ng/test/pattern/counter/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/counter/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("counter_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "counter_test_ng.cpp", - ] + sources = [ "counter_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/dialog/BUILD.gn b/frameworks/core/components_ng/test/pattern/dialog/BUILD.gn index 4d3cd40ff2b..097b9a7bed3 100644 --- a/frameworks/core/components_ng/test/pattern/dialog/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/dialog/BUILD.gn @@ -17,8 +17,5 @@ ace_unittest("dialog_test_ng") { flutter_skia = true render = true type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "dialog_test_ng.cpp", - ] + sources = [ "dialog_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/form/BUILD.gn b/frameworks/core/components_ng/test/pattern/form/BUILD.gn index 8605f21ab3f..ad769e95838 100644 --- a/frameworks/core/components_ng/test/pattern/form/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/form/BUILD.gn @@ -27,7 +27,6 @@ ace_unittest("form_test_ng") { "$ace_root/frameworks/core/components_ng/test/pattern/form/mock/mock_rosen_render_context.cpp", "$ace_root/frameworks/core/components_ng/test/pattern/form/mock/mock_rs_surface_mode.cpp", "$ace_root/frameworks/core/components_ng/test/pattern/form/mock/mock_sub_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "form_test_ng.cpp", ] diff --git a/frameworks/core/components_ng/test/pattern/gauge/BUILD.gn b/frameworks/core/components_ng/test/pattern/gauge/BUILD.gn index c7f33c8b028..0f9734c64fa 100644 --- a/frameworks/core/components_ng/test/pattern/gauge/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/gauge/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("gauge_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/common/font_loader.cpp", - "$ace_root/frameworks/core/common/font_manager.cpp", "gauge_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/grid/BUILD.gn b/frameworks/core/components_ng/test/pattern/grid/BUILD.gn index 1a2b2856f92..453239c03a0 100644 --- a/frameworks/core/components_ng/test/pattern/grid/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/grid/BUILD.gn @@ -22,7 +22,6 @@ ace_unittest("grid_test_ng") { "$ace_root/frameworks/bridge/js_frontend/engine/common/js_constants.cpp", "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", "$ace_root/frameworks/core/components_v2/grid/grid_event.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "grid_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp b/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp index c82c49c1e99..3d865c104be 100644 --- a/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp @@ -2627,8 +2627,9 @@ HWTEST_F(GridTestNg, EventHub001, TestSize.Level1) gridModelNG.SetColumnsTemplate("1fr 1fr 1fr 1fr"); CreateVerticalItem(8); }); - RectF gridRect(0.f, 0.f, DEVICE_WIDTH, DEVICE_HEIGHT); - MockGetPaintRectWithTransform(frameNode_, gridRect); + RectF gridRect(0.f, 0.f, DEVICE_WIDTH, GRID_HEIGHT); + auto mockRenderContext = AceType::DynamicCast(frameNode_->renderContext_); + mockRenderContext->rect_ = gridRect; /** * @tc.steps: step1. call GetInsertPosition func. @@ -4308,7 +4309,8 @@ HWTEST_F(GridTestNg, ScrollLayout001, TestSize.Level1) }); const float smallerHeight = DEVICE_HEIGHT - ITEM_HEIGHT; RectF gridRect(0.f, 0.f, DEVICE_WIDTH, smallerHeight); - MockGetPaintRectWithTransform(frameNode_, gridRect); + auto mockRenderContext = AceType::DynamicCast(frameNode_->renderContext_); + mockRenderContext->rect_ = gridRect; /** * @tc.steps: step1. Change to smaller mainSize diff --git a/frameworks/core/components_ng/test/pattern/grid_container/BUILD.gn b/frameworks/core/components_ng/test/pattern/grid_container/BUILD.gn index 222bcc64f3b..c275cf6e257 100644 --- a/frameworks/core/components_ng/test/pattern/grid_container/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/grid_container/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("grid_container_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "grid_container_test_ng.cpp", - ] + sources = [ "grid_container_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/hyperlink/BUILD.gn b/frameworks/core/components_ng/test/pattern/hyperlink/BUILD.gn index b200430de89..b1216a848ff 100644 --- a/frameworks/core/components_ng/test/pattern/hyperlink/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/hyperlink/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("hyperlink_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "hyperlink_test_ng.cpp", - ] + sources = [ "hyperlink_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/image/BUILD.gn b/frameworks/core/components_ng/test/pattern/image/BUILD.gn index 17f728dfee5..01275927045 100644 --- a/frameworks/core/components_ng/test/pattern/image/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/image/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("image_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "image_test_ng.cpp", - ] + sources = [ "image_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/image_animator/BUILD.gn b/frameworks/core/components_ng/test/pattern/image_animator/BUILD.gn index fd9e7eade2b..2702b31461d 100644 --- a/frameworks/core/components_ng/test/pattern/image_animator/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/image_animator/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("image_animator_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "image_animator_test_ng.cpp", - ] + sources = [ "image_animator_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/indexer/BUILD.gn b/frameworks/core/components_ng/test/pattern/indexer/BUILD.gn index 9e8b47c2978..21e962330b8 100644 --- a/frameworks/core/components_ng/test/pattern/indexer/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/indexer/BUILD.gn @@ -19,7 +19,6 @@ ace_unittest("indexer_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "indexer_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/list/BUILD.gn b/frameworks/core/components_ng/test/pattern/list/BUILD.gn index 4b41765cc5d..22fa5f2ab90 100644 --- a/frameworks/core/components_ng/test/pattern/list/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/list/BUILD.gn @@ -21,7 +21,6 @@ ace_unittest("list_test_ng") { "$ace_root/frameworks/bridge/common/utils/utils.cpp", "$ace_root/frameworks/bridge/js_frontend/engine/common/js_constants.cpp", "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "list_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/list/list_test_ng.cpp b/frameworks/core/components_ng/test/pattern/list/list_test_ng.cpp index 804a13d22f6..a497e830310 100644 --- a/frameworks/core/components_ng/test/pattern/list/list_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/list/list_test_ng.cpp @@ -2939,7 +2939,6 @@ HWTEST_F(ListTestNg, Event005, TestSize.Level1) listModelNG.SetOnScrollStart(scrollStart); listModelNG.SetOnScrollStop(scrollStop); }); - MockGetPaintRectWithTransform(frameNode_); pattern_->OnScrollCallback(100.f, SCROLL_FROM_START); EXPECT_TRUE(isScrollStartCalled); @@ -2993,7 +2992,6 @@ HWTEST_F(ListTestNg, EventHub001, TestSize.Level1) CreateListWithItem([onItemDragStart](ListModelNG listModelNG) { listModelNG.SetOnItemDragStart(onItemDragStart); }); - MockGetPaintRectWithTransform(frameNode_); auto jsonStr = eventHub_->GetDragExtraParams("", Point(0, 250), DragEventType::MOVE); EXPECT_EQ(jsonStr, "{\"insertIndex\":2}"); @@ -5033,7 +5031,6 @@ HWTEST_F(ListTestNg, Pattern005, TestSize.Level1) auto startFunc = GetDefaultSwiperBuilder(START_NODE_SIZE); CreateListItemWithSwiper(startFunc, nullptr, V2::SwipeEdgeEffect::None); }); - MockGetPaintRectWithTransform(frameNode_); // Set swiperItem_ to list pattern DragSwiperItem(0, 1.f); @@ -5096,7 +5093,6 @@ HWTEST_F(ListTestNg, Pattern006, TestSize.Level1) listModelNG.SetLanes(2); CreateListItem(VIEWPORT_NUMBER); }); - MockGetPaintRectWithTransform(frameNode_); /** * @tc.steps: step1. When lanes > 1, call GetItemIndexByPosition @@ -5120,7 +5116,6 @@ HWTEST_F(ListTestNg, Pattern007, TestSize.Level1) * @tc.expected: Would return the last itemIndex */ CreateList([](ListModelNG listModelNG) { CreateListItem(VIEWPORT_NUMBER); }); - MockGetPaintRectWithTransform(frameNode_); const Point point = Point(0, 1000.f); int32_t itemIndex = pattern_->GetItemIndexByPosition(point.GetX(), point.GetY()); EXPECT_EQ(itemIndex, VIEWPORT_NUMBER); @@ -5138,7 +5133,6 @@ HWTEST_F(ListTestNg, Pattern008, TestSize.Level1) * @tc.expected: Would return 0 */ CreateList(); - MockGetPaintRectWithTransform(frameNode_); const Point point = Point(0, 1000.f); int32_t itemIndex = pattern_->GetItemIndexByPosition(point.GetX(), point.GetY()); EXPECT_EQ(itemIndex, 0); diff --git a/frameworks/core/components_ng/test/pattern/marquee/BUILD.gn b/frameworks/core/components_ng/test/pattern/marquee/BUILD.gn index c8fc05a0817..6e1f66fb5b3 100644 --- a/frameworks/core/components_ng/test/pattern/marquee/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/marquee/BUILD.gn @@ -16,8 +16,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("marquee_test_ng") { type = "new" flutter_skia = true - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "marquee_test_ng.cpp", - ] + sources = [ "marquee_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/menu/BUILD.gn b/frameworks/core/components_ng/test/pattern/menu/BUILD.gn index d9e4c16fa8e..a44356ac820 100644 --- a/frameworks/core/components_ng/test/pattern/menu/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/menu/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("menu_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "menu_test_ng.cpp", - ] + sources = [ "menu_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/menu/menu_test_ng.cpp b/frameworks/core/components_ng/test/pattern/menu/menu_test_ng.cpp index 74925008e8a..b8118e40aba 100644 --- a/frameworks/core/components_ng/test/pattern/menu/menu_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/menu/menu_test_ng.cpp @@ -3561,7 +3561,7 @@ HWTEST_F(MenuTestNg, MenuItemSetSelectedChangeEvent001, TestSize.Level1) MenuItemProperties itemOption; MneuItemModelInstance.Create(itemOption); MneuItemModelInstance.SetSelectedChangeEvent(changeEvent); - + auto itemNode = AceType::DynamicCast(ViewStackProcessor::GetInstance()->Finish()); ASSERT_NE(itemNode, nullptr); @@ -4797,9 +4797,6 @@ HWTEST_F(MenuTestNg, MenuLayoutAlgorithmTestNg038, TestSize.Level1) /** * @tc.steps: step2. target is null but the geometry node of target is null */ - auto mockRenderContext = AceType::DynamicCast(target->GetRenderContext()); - ASSERT_NE(mockRenderContext, nullptr); - EXPECT_CALL(*mockRenderContext, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF(0.0f, 0.0f, 0.0f, 0.0f))); menuLayoutAlgorithm->InitTargetSizeAndPosition(nullptr, true); /** diff --git a/frameworks/core/components_ng/test/pattern/navigation/BUILD.gn b/frameworks/core/components_ng/test/pattern/navigation/BUILD.gn index 6af05792bbc..d854a30198b 100755 --- a/frameworks/core/components_ng/test/pattern/navigation/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/navigation/BUILD.gn @@ -11,231 +11,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("navigation_test_ng") { - module_out_path = pattern_test_output_path - +ace_unittest("navigation_test_ng") { + type = "new" + render = true sources = [ - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/test/mock/mock_animatable_dimension.cpp", - "$ace_root/frameworks/base/test/mock/mock_drag_window.cpp", - "$ace_root/frameworks/base/test/mock/mock_frame_report.cpp", "$ace_root/frameworks/base/test/mock/mock_mouse_style.cpp", - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_subwindow_manager.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", "$ace_root/frameworks/base/thread/background_task_executor.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/animation/friction_motion.cpp", - "$ace_root/frameworks/core/animation/spring_curve.cpp", - "$ace_root/frameworks/core/animation/spring_model.cpp", - "$ace_root/frameworks/core/animation/spring_motion.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_animator.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_scheduler.cpp", - "$ace_root/frameworks/core/common/clipboard/clipboard_proxy.cpp", - "$ace_root/frameworks/core/common/container_scope.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", "$ace_root/frameworks/core/common/test/mock/mock_layout_inspector.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/border.cpp", - "$ace_root/frameworks/core/components/common/properties/border_edge.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow_config.cpp", - "$ace_root/frameworks/core/components/common/properties/text_style.cpp", "$ace_root/frameworks/core/components/font/constants_converter.cpp", - "$ace_root/frameworks/core/components/scroll/scrollable.cpp", "$ace_root/frameworks/core/components/xcomponent/native_interface_xcomponent_impl.cpp", - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_abstract.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/long_press_event.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_measure_layout_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node_base.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/grid_container/grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/linear_layout/linear_layout_utils.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/multi_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/sub_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/bar_item_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/bar_item_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/bar_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/nav_bar_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/nav_bar_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/nav_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_content_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_group_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/navigation_stack.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/title_bar_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/title_bar_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/title_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/tool_bar_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigation/tool_bar_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigator/navigator_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigator/navigator_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navrouter/navdestination_group_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navrouter/navdestination_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navrouter/navdestination_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navrouter/navdestination_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/effect/scroll_fade_effect.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/span_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/span_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/property/accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/divider_painter.cpp", - "$ace_root/frameworks/core/components_ng/render/image_painter.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/syntax/for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/flex/mock_flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_bar_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/mock_scrollable_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/select_overlay/mock_select_overlay_node.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_drawing_convertor.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_property.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock/mock_image_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock_icon_theme.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_layout_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp", - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - "$ace_root/frameworks/core/event/back_end_event_manager.cpp", - "$ace_root/frameworks/core/gestures/pan_recognizer.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/image/image_source_info.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/base/mock_jank_frame_report.cpp", - "$ace_root/test/mock/core/common/mock_ace_engine.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "$ace_root/test/mock/core/render/mock_font_collection.cpp", - "$ace_root/test/mock/core/render/mock_paragraph.cpp", - "$ace_root/test/mock/interfaces/mock_ace_forward_compatibility.cpp", - "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", + "$ace_root/test/mock/base/mock_subwindow.cpp", "bar_item_test_ng.cpp", "nav_bar_test_ng.cpp", "navdestination_test_ng.cpp", @@ -243,18 +30,4 @@ ohos_unittest("navigation_test_ng") { "title_bar_test_ng.cpp", "tool_bar_test_ng.cpp", ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/frameworks/core/components/theme:build_theme_code", - "$ace_root/test/unittest:ace_engine_unittest_flutter_deps", - "$ace_root/test/unittest:ace_unittest_log", - "$ace_root/test/unittest:ace_unittest_trace", - "$cjson_root:cjson", - "$graphic_2d_path/rosen/modules/2d_engine/rosen_text:rosen_text", - "$graphic_2d_path/rosen/modules/render_service_base:librender_service_base", - "//third_party/googletest:gmock_main", - ] - - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] } diff --git a/frameworks/core/components_ng/test/pattern/navigator/BUILD.gn b/frameworks/core/components_ng/test/pattern/navigator/BUILD.gn index e89f8aee276..e5c2eb0be72 100644 --- a/frameworks/core/components_ng/test/pattern/navigator/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/navigator/BUILD.gn @@ -11,17 +11,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") -import("//foundation/arkui/ace_engine/ace_config.gni") -import( - "//foundation/arkui/ace_engine/frameworks/core/components_ng/components.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ace_unittest("navigator_event_hub_test_ng") { +ace_unittest("navigator_test_ng") { + type = "new" sources = [ - "$ace_root/frameworks/core/components_ng/pattern/navigator/navigator_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigator/navigator_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/navigator/navigator_pattern.cpp", "navigator_event_hub_test_ng.cpp", + "navigator_pattern_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/navigator/navigator_pattern_test_ng.cpp b/frameworks/core/components_ng/test/pattern/navigator/navigator_pattern_test_ng.cpp index a6d6d58c6bd..9d1ebae47b5 100644 --- a/frameworks/core/components_ng/test/pattern/navigator/navigator_pattern_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/navigator/navigator_pattern_test_ng.cpp @@ -16,10 +16,10 @@ #include "gtest/gtest.h" #define private public - #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/pattern/navigator/navigator_event_hub.h" #include "core/components_ng/pattern/navigator/navigator_model.h" +#include "core/components_ng/pattern/navigator/navigator_model_ng.h" #include "core/components_ng/pattern/navigator/navigator_pattern.h" using namespace testing; @@ -48,12 +48,13 @@ protected: RefPtr NavigatorPatternTestNg::CreateNavigator(const TestProperty& testProperty) { - NavigatorModel::GetInstance()->Create(); + NavigatorModelNG navigator; + navigator.Create(); if (testProperty.typeValue.has_value()) { - NavigatorModel::GetInstance()->SetType(testProperty.typeValue.value()); - NavigatorModel::GetInstance()->SetUri(testProperty.url.value()); - NavigatorModel::GetInstance()->SetActive(testProperty.active.value()); - NavigatorModel::GetInstance()->SetParams(testProperty.params.value()); + navigator.SetType(testProperty.typeValue.value()); + navigator.SetUri(testProperty.url.value()); + navigator.SetActive(testProperty.active.value()); + navigator.SetParams(testProperty.params.value()); } RefPtr element = ViewStackProcessor::GetInstance()->Finish(); // TextView pop diff --git a/frameworks/core/components_ng/test/pattern/navrouter/BUILD.gn b/frameworks/core/components_ng/test/pattern/navrouter/BUILD.gn index ed52b3fa8c1..7d02b750295 100644 --- a/frameworks/core/components_ng/test/pattern/navrouter/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/navrouter/BUILD.gn @@ -20,7 +20,6 @@ ace_unittest("navrouter_test_ng") { sources = [ "$ace_root/frameworks/base/test/mock/mock_mouse_style.cpp", "$ace_root/frameworks/core/components/test/unittest/mock/subwindow_mock.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "navrouter_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/option/BUILD.gn b/frameworks/core/components_ng/test/pattern/option/BUILD.gn index bcb531800e2..ec9b63bf26e 100644 --- a/frameworks/core/components_ng/test/pattern/option/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/option/BUILD.gn @@ -17,8 +17,5 @@ ace_unittest("option_test_ng") { render = true flutter_skia = true type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "option_test_ng.cpp", - ] + sources = [ "option_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/overlay/BUILD.gn b/frameworks/core/components_ng/test/pattern/overlay/BUILD.gn index 7d3d9935c2e..7a813c932b4 100644 --- a/frameworks/core/components_ng/test/pattern/overlay/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/overlay/BUILD.gn @@ -13,297 +13,11 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("overlay_manager_test_ng") { - module_out_path = pattern_test_output_path - +ace_unittest("overlay_manager_test_ng") { + type = "new" sources = [ - "$ace_root/frameworks/base/subwindow/subwindow_manager.cpp", - "$ace_root/frameworks/base/test/mock/mock_animatable_dimension.cpp", "$ace_root/frameworks/base/test/mock/mock_measure_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/chain_animation.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/animation/friction_motion.cpp", - "$ace_root/frameworks/core/animation/spring_curve.cpp", - "$ace_root/frameworks/core/animation/spring_model.cpp", - "$ace_root/frameworks/core/animation/spring_motion.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_animator.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_scheduler.cpp", - "$ace_root/frameworks/core/common/ace_engine.cpp", - "$ace_root/frameworks/core/common/container.cpp", - "$ace_root/frameworks/core/common/container_scope.cpp", - "$ace_root/frameworks/core/common/frontend.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_watch_dog.cpp", - "$ace_root/frameworks/core/components/common/properties/border.cpp", - "$ace_root/frameworks/core/components/common/properties/border_edge.cpp", - "$ace_root/frameworks/core/components/common/properties/edge.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow_config.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkbox/checkbox_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkbox/checkbox_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkbox/checkbox_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkbox/checkbox_paint_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkbox/checkbox_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_paint_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/checkboxgroup/checkboxgroup_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/dialog/dialog_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/dialog/dialog_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/multi_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/sub_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/modal_presentation_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/sheet_drag_bar_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/sheet_drag_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/sheet_presentation_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/overlay/sheet_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/root/root_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/effect/scroll_fade_controller.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/effect/scroll_fade_effect.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_spring_effect.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scrollable/nestable_scroll_container.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scrollable/scrollable_paint_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scrollable/scrollable_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/page_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/stage_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/stage_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/stage_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/pattern/toast/toast_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/toast/toast_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/toast/toast_view.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/event/scrollable_event/mock_scrollable.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/flex/mock_flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_bar_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_fade_painter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/moc_refresh_coordination.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp", - "$ace_root/frameworks/core/event/back_end_event_manager.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/base/mock_jank_frame_report.cpp", - "overlay_manager_test_ng.cpp", - ] - - sources += [ - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/geometry/quaternion.cpp", - "$ace_root/frameworks/base/geometry/transform_util.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/common/clipboard/clipboard_proxy.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - "$ace_root/frameworks/core/components/common/properties/text_style.cpp", - "$ace_root/frameworks/core/components/picker/picker_animation.cpp", "$ace_root/frameworks/core/components/picker/picker_data.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/ace_trace_mock.cpp", - "$ace_root/frameworks/core/components/theme/icon_theme.cpp", - "$ace_root/frameworks/core/components/theme/theme_attributes.cpp", - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/long_press_event.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/dialog/dialog_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/dialog/dialog_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/dialog/dialog_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_group_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_group_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_group_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_group_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_group_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_lanes_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/list/list_position_controller.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/date_time_animation_controller.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_column_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_column_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_column_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_dialog_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/datepicker_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/picker/toss_animation_controller.cpp", - "$ace_root/frameworks/core/components_ng/pattern/relative_container/relative_container_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stack/stack_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/image_span_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_picker/textpicker_dialog_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_column_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_column_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_column_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_dialog_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_row_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/timepicker_row_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/time_picker/toss_animation_controller.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/divider_painter.cpp", - "$ace_root/frameworks/core/components_ng/render/drawing_prop_convertor.cpp", - "$ace_root/frameworks/core/components_ng/render/image_painter.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_source_info.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/grid_container/mock_grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/nav_bar/mock_nav_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_surface_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/syntax/mock_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/theme/mock_theme_constants.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/theme/mock_theme_utils.cpp", - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/pipeline/base/constants.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_subwindow.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "$ace_root/test/unittest/core/pipeline/mock_drag_drop_manager.cpp", - ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/frameworks/core/components/theme:build_theme_code", - "$ace_root/test/unittest:ace_unittest_log", - "$cjson_root:cjson_static", - "//third_party/googletest:gmock_main", + "overlay_manager_test_ng.cpp", ] - - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] } diff --git a/frameworks/core/components_ng/test/pattern/overlay/overlay_manager_test_ng.cpp b/frameworks/core/components_ng/test/pattern/overlay/overlay_manager_test_ng.cpp index cde786b0733..efcc3ed16f6 100644 --- a/frameworks/core/components_ng/test/pattern/overlay/overlay_manager_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/overlay/overlay_manager_test_ng.cpp @@ -58,7 +58,6 @@ #include "core/components_ng/pattern/stage/stage_pattern.h" #include "core/components_ng/pattern/toast/toast_layout_property.h" #include "core/components_ng/pattern/toast/toast_pattern.h" -#include "core/components_ng/test/mock/pattern/picker/mock_picker_theme_manager.h" #include "core/components_ng/test/mock/theme/mock_theme_manager.h" #include "core/components_v2/inspector/inspector_constants.h" #include "core/pipeline_ng/pipeline_context.h" @@ -403,7 +402,7 @@ HWTEST_F(OverlayManagerTestNg, BindSheet001, TestSize.Level1) auto sheetDragBarPaintProperty = sheetDragBarNode->GetPaintProperty(); EXPECT_FALSE(sheetDragBarPaintProperty == nullptr); SheetStyle sheetStyle1; - topSheetNode->GetGeometryNode()->SetFrameSize({10, 10}); + topSheetNode->GetGeometryNode()->SetFrameSize({ 10, 10 }); // sheetStyle1.sheetMode is null. sheetStyle1.sheetMode = std::nullopt; @@ -491,7 +490,7 @@ HWTEST_F(OverlayManagerTestNg, RemoveAllModalInOverlay001, TestSize.Level1) EXPECT_FALSE(overlayManager->modalStack_.empty()); auto sheetNode = overlayManager->modalStack_.top().Upgrade(); EXPECT_EQ(sheetNode->GetTag(), V2::SHEET_PAGE_TAG); - + /** * @tc.steps: step4. run RemoveAllModalInOverlay func. */ @@ -659,7 +658,7 @@ HWTEST_F(OverlayManagerTestNg, DestroySheet003, TestSize.Level1) EXPECT_NE(sheetNode->GetPattern()->targetId_, targetId); overlayManager->DestroySheet(sheetNode, targetId); EXPECT_FALSE(overlayManager->modalStack_.empty()); - + sheetNode->tag_ = V2::SHEET_PAGE_TAG; sheetNode->GetPattern()->targetId_ = targetId; overlayManager->DestroySheet(sheetNode, targetId); @@ -1013,8 +1012,8 @@ HWTEST_F(OverlayManagerTestNg, MenuTest002, TestSize.Level1) auto menuNode = FrameNode::CreateFrameNode(V2::MENU_WRAPPER_ETS_TAG, menuId, AceType::MakeRefPtr(targetId)); auto subMenuId = ElementRegister::GetInstance()->MakeUniqueId(); - auto subMenuNode = FrameNode::CreateFrameNode(V2::MENU_ETS_TAG, - subMenuId, AceType::MakeRefPtr(1, "Test", MenuType::MENU)); + auto subMenuNode = FrameNode::CreateFrameNode( + V2::MENU_ETS_TAG, subMenuId, AceType::MakeRefPtr(1, "Test", MenuType::MENU)); subMenuNode->MountToParent(menuNode); /** * @tc.steps: step2. call showMenu when menuNode is nullptr and menuMap is empty. @@ -1480,6 +1479,7 @@ HWTEST_F(OverlayManagerTestNg, DialogTest002, TestSize.Level1) EXPECT_TRUE(overlayManager->dialogMap_.empty()); EXPECT_FALSE(overlayManager->DialogInMapHoldingFocus()); } + /** * @tc.name: DialogTest003 * @tc.desc: Test OverlayManager::ShowDateDialog->ShowTimeDialog->RemoveOverlay. @@ -1490,7 +1490,7 @@ HWTEST_F(OverlayManagerTestNg, DialogTest003, TestSize.Level1) /** * @tc.steps: step1. create root node and prepare dialogProperties. */ - auto themeManager = AceType::MakeRefPtr(); + auto themeManager = AceType::MakeRefPtr(); MockPipelineBase::GetCurrent()->SetThemeManager(themeManager); auto rootNode = FrameNode::CreateFrameNode(V2::ROOT_ETS_TAG, 1, AceType::MakeRefPtr()); DialogProperties dialogProperties; diff --git a/frameworks/core/components_ng/test/pattern/panel/BUILD.gn b/frameworks/core/components_ng/test/pattern/panel/BUILD.gn index db63f404d71..ad8539ea8c2 100644 --- a/frameworks/core/components_ng/test/pattern/panel/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/panel/BUILD.gn @@ -20,7 +20,6 @@ ace_unittest("panel_test_ng") { sources = [ "$ace_root/frameworks/core/components/panel/render_sliding_panel.cpp", "$ace_root/frameworks/core/components/panel/sliding_events.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "close_icon_pattern_test_ng.cpp", "dragBar_pattern_test_ng.cpp", "panel_property_test_ng.cpp", diff --git a/frameworks/core/components_ng/test/pattern/picker/BUILD.gn b/frameworks/core/components_ng/test/pattern/picker/BUILD.gn index 974f8035e63..99c0937a218 100644 --- a/frameworks/core/components_ng/test/pattern/picker/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/picker/BUILD.gn @@ -84,6 +84,7 @@ ohos_unittest("date_picker_test_ng") { "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", @@ -207,7 +208,7 @@ ohos_unittest("date_picker_test_ng") { "$ace_root/test/mock/core/render/mock_paragraph.cpp", "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", "$root_out_dir/arkui/framework/core/components/theme/theme_constants_default.cpp", - "datepicker_test_ng.cpp", + "date_picker_test_ng.cpp", ] deps = [ diff --git a/frameworks/core/components_ng/test/pattern/picker/datepicker_test_ng.cpp b/frameworks/core/components_ng/test/pattern/picker/date_picker_test_ng.cpp similarity index 100% rename from frameworks/core/components_ng/test/pattern/picker/datepicker_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/picker/date_picker_test_ng.cpp diff --git a/frameworks/core/components_ng/test/pattern/progress/BUILD.gn b/frameworks/core/components_ng/test/pattern/progress/BUILD.gn index 830a4ef26aa..a0808edcb8f 100644 --- a/frameworks/core/components_ng/test/pattern/progress/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/progress/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("progress_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "progress_test_ng.cpp", - ] + sources = [ "progress_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/refresh/BUILD.gn b/frameworks/core/components_ng/test/pattern/refresh/BUILD.gn index 671960448f2..d595816ef67 100644 --- a/frameworks/core/components_ng/test/pattern/refresh/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/refresh/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("refresh_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "refresh_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/rich_editor/BUILD.gn b/frameworks/core/components_ng/test/pattern/rich_editor/BUILD.gn index 186165f8c5a..7b68413aaa0 100755 --- a/frameworks/core/components_ng/test/pattern/rich_editor/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/rich_editor/BUILD.gn @@ -28,7 +28,6 @@ ace_unittest("rich_editor_test_ng") { "$ace_root/frameworks/core/components_ng/pattern/rich_editor/rich_editor_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/rich_editor/rich_editor_pattern.cpp", "$ace_root/frameworks/core/event/key_event.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "rich_editor_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/scroll/BUILD.gn b/frameworks/core/components_ng/test/pattern/scroll/BUILD.gn index 245c9e9c395..50a82a6c313 100644 --- a/frameworks/core/components_ng/test/pattern/scroll/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/scroll/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("scroll_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "scroll_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/search/BUILD.gn b/frameworks/core/components_ng/test/pattern/search/BUILD.gn index 642046b7fe3..b4af75bef1b 100644 --- a/frameworks/core/components_ng/test/pattern/search/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/search/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("search_test_ng") { type = "new" sources = [ "$ace_root/frameworks/base/test/mock/mock_mouse_style.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "search_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/search/search_test_ng.cpp b/frameworks/core/components_ng/test/pattern/search/search_test_ng.cpp index 8dbc2a89ade..44f373df131 100644 --- a/frameworks/core/components_ng/test/pattern/search/search_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/search/search_test_ng.cpp @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "gtest/gtest.h" -#include "gmock/gmock-actions.h" #define protected public #define private public @@ -46,6 +46,9 @@ #include "core/components_ng/test/mock/theme/mock_theme_manager.h" #include "core/components_v2/inspector/inspector_constants.h" #include "core/pipeline_ng/test/mock/mock_pipeline_base.h" +#undef protected +#undef private + using namespace testing; using namespace testing::ext; @@ -91,15 +94,15 @@ void SearchTestNg::SetThemeInCreate() auto textFieldTheme = AceType::MakeRefPtr(); auto searchTheme = AceType::MakeRefPtr(); auto iconTheme = AceType::MakeRefPtr(); - EXPECT_CALL(*themeManager, GetTheme(_)) - .WillRepeatedly([=](ThemeType type) -> RefPtr { - if (type == SearchTheme::TypeId()) { - return searchTheme; - } else if (type == IconTheme::TypeId()) { - return iconTheme; - } - return textFieldTheme; - }); + EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly([=](ThemeType type) -> RefPtr { + if (type == SearchTheme::TypeId()) { + return searchTheme; + } + if (type == IconTheme::TypeId()) { + return iconTheme; + } + return textFieldTheme; + }); } void SearchTestNg::SetSearchTheme() @@ -800,7 +803,6 @@ HWTEST_F(SearchTestNg, PatternOnColorConfigurationUpdate011, TestSize.Level1) */ auto textFieldPattern = textFieldFrameNode->GetPattern(); ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->InitCaretPosition(""); auto textRect = textFieldPattern->GetTextRect(); textRect.SetTop(0.0); textFieldPattern->SetTextRect(textRect); @@ -861,7 +863,6 @@ HWTEST_F(SearchTestNg, PatternOnColorConfigurationUpdate012, TestSize.Level1) * @tc.step: step4. call HandleTextContentLines. * @tc.expected: cover branch IsOperation is true and GetLineHeight value is 0. */ - textFieldPattern->SetCaretOffsetX(0.0); textFieldPattern->UpdateEditingValue("aaa", 0); result = pattern->HandleTextContentLines(); EXPECT_EQ(result, 0); @@ -1592,7 +1593,7 @@ HWTEST_F(SearchTestNg, Pattern013, TestSize.Level1) pattern->clickListener_->GetGestureEventFunc()(gestureEvent); } - /** +/** * @tc.name: OnColorConfigurationUpdate001 * @tc.desc: test Oncolorconfigurationupdate * @tc.type: FUNC diff --git a/frameworks/core/components_ng/test/pattern/security_component/BUILD.gn b/frameworks/core/components_ng/test/pattern/security_component/BUILD.gn index 4489d005809..81d9276b6f1 100644 --- a/frameworks/core/components_ng/test/pattern/security_component/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/security_component/BUILD.gn @@ -11,40 +11,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") -import("//foundation/arkui/ace_engine/ace_config.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("security_component_pattern_test_ng") { +ohos_unittest("security_component_test_ng") { module_out_path = pattern_test_output_path sources = [ - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/components_ng/base/view_abstract.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_painter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_source_info.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/button/mock_button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/button/mock_button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock/mock_image_pattern.cpp", - - # self "$ace_root/frameworks/core/components_ng/pattern/security_component/location_button/location_button_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/security_component/paste_button/paste_button_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/security_component/save_button/save_button_model_ng.cpp", @@ -53,95 +25,24 @@ ohos_unittest("security_component_pattern_test_ng") { "$ace_root/frameworks/core/components_ng/pattern/security_component/security_component_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/security_component/security_component_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/security_component/security_component_pattern.cpp", - "security_component_model_test_ng.cpp", + "security_component_test_ng.cpp", ] - sources += [ - # base - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - - # components - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - - # components_ng - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/drawing_prop_convertor.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - - # components_v2 - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - - # pipeline - "$ace_root/frameworks/core/pipeline/base/constants.cpp", - - # mock - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/ace_trace_mock.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/grid_container/mock_grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_surface_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/syntax/mock_for_each_node.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - ] deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", "$ace_root/frameworks/core/components/theme:build_theme_code", + "$ace_root/test/unittest:ace_base", + "$ace_root/test/unittest:ace_components_base", + "$ace_root/test/unittest:ace_components_event", + "$ace_root/test/unittest:ace_components_gestures", + "$ace_root/test/unittest:ace_components_layout", + "$ace_root/test/unittest:ace_components_manager", + "$ace_root/test/unittest:ace_components_mock", + "$ace_root/test/unittest:ace_components_pattern", + "$ace_root/test/unittest:ace_components_property", + "$ace_root/test/unittest:ace_components_render", + "$ace_root/test/unittest:ace_components_syntax", + "$ace_root/test/unittest:ace_core_animation", + "$ace_root/test/unittest:ace_core_extra", "$ace_root/test/unittest:ace_unittest_log", "$cjson_root:cjson_static", "//third_party/googletest:gmock_main", diff --git a/frameworks/core/components_ng/test/pattern/security_component/security_component_model_test_ng.cpp b/frameworks/core/components_ng/test/pattern/security_component/security_component_test_ng.cpp similarity index 100% rename from frameworks/core/components_ng/test/pattern/security_component/security_component_model_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/security_component/security_component_test_ng.cpp diff --git a/frameworks/core/components_ng/test/pattern/select/BUILD.gn b/frameworks/core/components_ng/test/pattern/select/BUILD.gn index 1b04ca44b7b..70639cca643 100644 --- a/frameworks/core/components_ng/test/pattern/select/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/select/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("select_pattern_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_v2/inspector/utils.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "select_pattern_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/select_overlay/BUILD.gn b/frameworks/core/components_ng/test/pattern/select_overlay/BUILD.gn index 51d27476d4c..b6d95c9dcf8 100644 --- a/frameworks/core/components_ng/test/pattern/select_overlay/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/select_overlay/BUILD.gn @@ -13,197 +13,7 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("select_overlay_test_ng") { - module_out_path = pattern_test_output_path - - sources = [ - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/test/mock/mock_animatable_dimension.cpp", - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_subwindow_manager.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_animator.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_scheduler.cpp", - "$ace_root/frameworks/core/common/container_scope.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow_config.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/ace_trace_mock.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/mock_icon_theme.cpp", - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item_group/menu_item_group_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/multi_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/sub_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/stage_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/property/accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/drawing_prop_convertor.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/event/scrollable_event/mock_scrollable.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_painter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_source_info.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/grid_container/mock_grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_bar_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/moc_refresh_coordination.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/mock_scrollable_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_rosen_render_custom_paint/mock_rosen_render_custom_paint.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_surface_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/syntax/mock_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock/mock_image_pattern.cpp", - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/pipeline/base/constants.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/core/common/mock_ace_engine.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", - "select_overlay_test_ng.cpp", - ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/frameworks/core/components/theme:build_theme_code", - "$ace_root/test/unittest:ace_engine_unittest_flutter_deps", - "$ace_root/test/unittest:ace_unittest_log", - "$cjson_root:cjson_static", - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/googletest:gmock_main", - "//third_party/icu/icu4c:shared_icui18n", - "//third_party/icu/icu4c:shared_icuuc", - ] - - external_deps = [] - if (enable_graphic_text_gine) { - external_deps += [ "graphic_2d:rosen_text" ] - } - defines = [ "ENABLE_ROSEN_BACKEND" ] - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] +ace_unittest("select_overlay_test_ng") { + type = "new" + sources = [ "select_overlay_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/side_bar/BUILD.gn b/frameworks/core/components_ng/test/pattern/side_bar/BUILD.gn index 07be9f4a897..6ab43fb02b9 100644 --- a/frameworks/core/components_ng/test/pattern/side_bar/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/side_bar/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("side_bar_pattern_test_ng") { type = "new" sources = [ "$ace_root/frameworks/base/test/mock/mock_mouse_style.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "side_bar_layout_test_ng.cpp", "side_bar_pattern_test_ng.cpp", "side_bar_view_test_ng.cpp", diff --git a/frameworks/core/components_ng/test/pattern/slider/BUILD.gn b/frameworks/core/components_ng/test/pattern/slider/BUILD.gn index a1235f9fa51..51a82fa8d08 100644 --- a/frameworks/core/components_ng/test/pattern/slider/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/slider/BUILD.gn @@ -17,7 +17,6 @@ ace_unittest("slider_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_ng/test/mock/render/mock_path_painter.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "slider_test_ng.cpp", ] } diff --git a/frameworks/core/components_ng/test/pattern/stepper/BUILD.gn b/frameworks/core/components_ng/test/pattern/stepper/BUILD.gn index e4cdc9f8d07..8bf00a34e6a 100644 --- a/frameworks/core/components_ng/test/pattern/stepper/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/stepper/BUILD.gn @@ -16,7 +16,6 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("stepper_pattern_test_ng") { type = "new" sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "stepper_accessibility_property_test_ng.cpp", "stepper_item_pattern_test_ng.cpp", "stepper_pattern_test_ng.cpp", diff --git a/frameworks/core/components_ng/test/pattern/swiper/BUILD.gn b/frameworks/core/components_ng/test/pattern/swiper/BUILD.gn index de3ea1b1f2a..ae8bc987f03 100644 --- a/frameworks/core/components_ng/test/pattern/swiper/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/swiper/BUILD.gn @@ -17,8 +17,5 @@ ace_unittest("swiper_test_ng") { flutter_skia = true render = true type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "swiper_test_ng.cpp", - ] + sources = [ "swiper_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/tabs/BUILD.gn b/frameworks/core/components_ng/test/pattern/tabs/BUILD.gn index 4974637fbb6..eb98716ae92 100644 --- a/frameworks/core/components_ng/test/pattern/tabs/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/tabs/BUILD.gn @@ -11,185 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("tabs_test_ng") { - module_out_path = pattern_test_output_path - - sources = [ - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/animation/scheduler.cpp", - "$ace_root/frameworks/core/animation/scroll_motion.cpp", - "$ace_root/frameworks/core/animation/spring_curve.cpp", - "$ace_root/frameworks/core/animation/spring_model.cpp", - "$ace_root/frameworks/core/animation/spring_motion.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_animator.cpp", - "$ace_root/frameworks/core/common/container_scope.cpp", - "$ace_root/frameworks/core/components/theme/icon_theme.cpp", - "$ace_root/frameworks/core/components/theme/theme_constants.cpp", - "$ace_root/frameworks/core/components/theme/theme_utils.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/divider/divider_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/wrap_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/linear_layout/column_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/linear_layout/linear_layout_utils.cpp", - "$ace_root/frameworks/core/components_ng/pattern/linear_layout/row_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_spring_effect.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scrollable/nestable_scroll_container.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper/swiper_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper/swiper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper/swiper_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper/swiper_paint_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper/swiper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/digit_indicator/digit_indicator_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/indicator_common/swiper_arrow_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/property/accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/render/divider_painter.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/event/scrollable_event/mock_scrollable.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_painter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/swiper_indicator/mock_swiper_arrow_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/text/mock_text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock/mock_image_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_layout_adapter.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/image/image_source_info.cpp", - - # self - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_content_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tab_content_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tabs_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tabs_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tabs_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/tabs/tabs_pattern.cpp", - "tabs_test_ng.cpp", - ] - - sources += [ - # base - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - - # components - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - - # components_ng - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/long_press_event.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/drawing_prop_convertor.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - - # components_v2 - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - - # pipeline - "$ace_root/frameworks/core/pipeline/base/constants.cpp", - - # mock - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/ace_trace_mock.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/grid_container/mock_grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_surface_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/syntax/mock_for_each_node.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/frameworks/core/components/theme:build_theme_code", - "$ace_root/test/unittest:ace_unittest_log", - "$cjson_root:cjson_static", - "//third_party/googletest:gmock_main", - ] - - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] +ace_unittest("tabs_test_ng") { + type = "new" + sources = [ "tabs_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/tabs/tabs_test_ng.cpp b/frameworks/core/components_ng/test/pattern/tabs/tabs_test_ng.cpp index d6e3b07d216..abc52cb03b7 100644 --- a/frameworks/core/components_ng/test/pattern/tabs/tabs_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/tabs/tabs_test_ng.cpp @@ -10252,7 +10252,7 @@ HWTEST_F(TabsTestNg, TabBarPatternOnDirtyLayoutWrapperSwap002, TestSize.Level1) EXPECT_EQ(tabBarPattern->tabBarStyles_[0], TabBarStyle::SUBTABBATSTYLE); tabBarPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, config); EXPECT_EQ(tabBarPattern->indicator_, 0); - + /** * @tc.steps: step2. creat different conditions and invoke OnDirtyLayoutWrapperSwap. * @tc.expected: step2. expect The function is run ok. diff --git a/frameworks/core/components_ng/test/pattern/test_ng.cpp b/frameworks/core/components_ng/test/pattern/test_ng.cpp index 7b3b115a674..0480d9681aa 100644 --- a/frameworks/core/components_ng/test/pattern/test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/test_ng.cpp @@ -13,10 +13,13 @@ * limitations under the License. */ -#define protected public #define private public +#define protected public #include "core/components_ng/test/pattern/test_ng.h" +#include "core/components_ng/base/view_stack_processor.h" +#include "core/components_ng/test/mock/render/mock_render_context.h" + namespace OHOS::Ace::NG { void TestNG::SetWidth(const Dimension& width) { @@ -43,6 +46,7 @@ void TestNG::RunMeasureAndLayout(const RefPtr& frameNode, float width LayoutConstraint.selfIdealSize = { width, height }; } LayoutConstraint.maxSize = { DEVICE_WIDTH, DEVICE_HEIGHT }; + frameNode->UpdateLayoutPropertyFlag(); frameNode->Measure(LayoutConstraint); frameNode->Layout(); } diff --git a/frameworks/core/components_ng/test/pattern/test_ng.h b/frameworks/core/components_ng/test/pattern/test_ng.h index 13df19e350b..ca68fcedeba 100644 --- a/frameworks/core/components_ng/test/pattern/test_ng.h +++ b/frameworks/core/components_ng/test/pattern/test_ng.h @@ -18,19 +18,15 @@ #include "gtest/gtest.h" -#include "base/geometry/axis.h" #include "base/geometry/dimension.h" #include "base/memory/ace_type.h" #include "base/memory/referenced.h" -#include "base/utils/utils.h" #include "core/components_ng/base/frame_node.h" #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/test/mock/render/mock_render_context.h" namespace OHOS::Ace::NG { namespace { -using namespace testing; -using namespace testing::ext; constexpr int32_t PLATFORM_VERSION_TEN = 10; constexpr int32_t PLATFORM_VERSION_ELEVEN = 11; constexpr float DEVICE_WIDTH = 480.f; @@ -44,10 +40,9 @@ class TestNG { public: static void SetWidth(const Dimension& width); static void SetHeight(const Dimension& height); - void RunMeasureAndLayout(const RefPtr& frameNode, - float width = DEVICE_WIDTH, float height = DEVICE_HEIGHT); + void RunMeasureAndLayout( + const RefPtr& frameNode, float width = DEVICE_WIDTH, float height = DEVICE_HEIGHT); uint64_t GetActions(const RefPtr& accessibilityProperty); - void MockGetPaintRectWithTransform(const RefPtr& frameNode, RectF paintRect = RectF()); AssertionResult IsEqualOverScrollOffset(const OverScrollOffset& actual, const OverScrollOffset& expected) { @@ -126,12 +121,11 @@ public: { return GetChildFrameNode(frameNode, index)->GetEventHub(); } - + const RectF& GetChildRect(const RefPtr& frameNode, int32_t index) { return GetChildFrameNode(frameNode, index)->GetGeometryNode()->GetFrameRect(); } }; } // namespace OHOS::Ace::NG - #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H diff --git a/frameworks/core/components_ng/test/pattern/text/BUILD.gn b/frameworks/core/components_ng/test/pattern/text/BUILD.gn index 85abc1af542..dbc9194b64e 100644 --- a/frameworks/core/components_ng/test/pattern/text/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/text/BUILD.gn @@ -11,174 +11,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") -ohos_unittest("text_test_ng") { - module_out_path = pattern_test_output_path - - if (enable_graphic_text_gine) { - defines = [ "USE_GRAPHIC_TEXT_GINE" ] - } else { - include_dirs = - [ "//foundation/graphic/graphic_2d/rosen/modules/2d_graphics/include" ] - } - +ace_unittest("text_test_ng") { + type = "new" + render = true sources = [ - "$ace_root/adapter/preview/osal/ressched_report.cpp", - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/ressched/ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_drag_window.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_clipboard.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow_config.cpp", - "$ace_root/frameworks/core/components/common/properties/text_style.cpp", - "$ace_root/frameworks/core/components/font/constants_converter.cpp", - "$ace_root/frameworks/core/components/theme/theme_utils.cpp", - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_abstract.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/long_press_event.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/image_provider/image_object.cpp", - "$ace_root/frameworks/core/components_ng/image_provider/image_provider.cpp", - "$ace_root/frameworks/core/components_ng/image_provider/image_state_manager.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/grid_container/grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/image_span_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/span_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/span_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/property/accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/adapter/svg_canvas_image.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_cache.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_painter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/menu/mock_menu_wrapper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/root/mock_root_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/select_overlay/mock_select_overlay_node.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_drawing_convertor.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock_icon_theme.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_layout_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp", - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/image/image_provider.cpp", - "$ace_root/frameworks/core/image/image_source_info.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "$ace_root/test/mock/core/render/mock_font_collection.cpp", - "$ace_root/test/mock/core/render/mock_paragraph.cpp", "span_test_ng.cpp", "text_test_ng.cpp", ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/test/unittest:ace_engine_unittest_flutter_deps", - "$ace_root/test/unittest:ace_unittest_log", - "$ace_root/test/unittest:ace_unittest_trace", - "$cjson_root:cjson", - "//foundation/graphic/graphic_2d/rosen/modules/render_service_base:librender_service_base", - "//third_party/googletest:gmock_main", - ] - - external_deps = [] - if (enable_graphic_text_gine) { - external_deps += [ "graphic_2d:rosen_text" ] - } - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] } diff --git a/frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp b/frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp deleted file mode 100644 index f9704f35041..00000000000 --- a/frameworks/core/components_ng/test/pattern/text/mock/mock_text_theme.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define private public -#define protected public -#include "core/components/common/properties/color.h" -#include "core/components/text/text_theme.h" -#include "core/components/theme/theme_manager_impl.h" - -namespace OHOS::Ace { -ThemeManagerImpl::ThemeManagerImpl() = default; - -RefPtr ThemeManagerImpl::GetTheme(ThemeType type) -{ - RefPtr theme = AceType::Claim(new TextTheme()); - theme->textStyle_.SetTextColor(Color::BLACK); - theme->textStyle_.SetFontSize(Dimension(50)); - // Styles below do not need to get from ThemeConstants, directly set at here. - theme->textStyle_.SetFontStyle(FontStyle::NORMAL); - theme->textStyle_.SetFontWeight(FontWeight::NORMAL); - theme->textStyle_.SetTextDecoration(TextDecoration::NONE); - return theme; -} -} // namespace OHOS::Ace diff --git a/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp b/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp index f48534e70a8..63b7cc50797 100644 --- a/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/text/text_test_ng.cpp @@ -3890,9 +3890,6 @@ HWTEST_F(TextTestNg, PerformActionTest001, TestSize.Level1) * @tc.steps: step3. When text CopyOptions is None, call the callback function in textAccessibilityProperty. * @tc.expected: Related function is called. */ - RectF rect(0.0f, 0.0f, 0.0f, 0.0f); - EXPECT_CALL(*AceType::DynamicCast(frameNode->renderContext_), GetPaintRectWithTransform()) - .WillRepeatedly(Return(rect)); EXPECT_TRUE(textAccessibilityProperty->ActActionSetSelection(1, TEXT_SIZE_INT)); EXPECT_TRUE(textAccessibilityProperty->ActActionClearSelection()); EXPECT_TRUE(textAccessibilityProperty->ActActionCopy()); diff --git a/frameworks/core/components_ng/test/pattern/text_clock/BUILD.gn b/frameworks/core/components_ng/test/pattern/text_clock/BUILD.gn index 9efee422599..6f29af9aa70 100644 --- a/frameworks/core/components_ng/test/pattern/text_clock/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/text_clock/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("text_clock_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "text_clock_test_ng.cpp", - ] + sources = [ "text_clock_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/text_field/BUILD.gn b/frameworks/core/components_ng/test/pattern/text_field/BUILD.gn new file mode 100644 index 00000000000..eb986bd5f05 --- /dev/null +++ b/frameworks/core/components_ng/test/pattern/text_field/BUILD.gn @@ -0,0 +1,19 @@ +# Copyright (c) 2022-2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") + +ace_unittest("text_field_test_ng") { + type = "new" + sources = [ "text_field_test_ng.cpp" ] +} diff --git a/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp b/frameworks/core/components_ng/test/pattern/text_field/text_field_test_ng.cpp similarity index 87% rename from frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/text_field/text_field_test_ng.cpp index 6deb119f5ef..c42e34cfb34 100644 --- a/frameworks/core/components_ng/test/pattern/textfield/textfield_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/text_field/text_field_test_ng.cpp @@ -440,121 +440,6 @@ HWTEST_F(TextFieldPatternTestNg, TextareaMoveCaret001, TestSize.Level1) EXPECT_EQ(pattern->GetEditingValue().caretPosition, CARET_POSITION_2); } -/** - * @tc.name: FilterWithRegex001 - * @tc.desc: test FilterWithRegex - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, FilterWithRegex001, TestSize.Level1) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - std::string result; - auto funcReturn = textFieldPattern->FilterWithRegex("test", "filter_valuetest", result, true); - EXPECT_TRUE(funcReturn); - EXPECT_EQ("test", result); -} - -/** - * @tc.name: FilterWithRegex002 - * @tc.desc: test FilterWithRegex - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, FilterWithRegex002, TestSize.Level2) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - std::string result; - auto funcReturn = textFieldPattern->FilterWithRegex("filter_value", "", result, true); - EXPECT_FALSE(funcReturn); - funcReturn = textFieldPattern->FilterWithRegex("filter_value", "", result); - EXPECT_FALSE(funcReturn); - EXPECT_TRUE(result.empty()); - funcReturn = textFieldPattern->FilterWithRegex("", "", result); - EXPECT_FALSE(funcReturn); - EXPECT_TRUE(result.empty()); -} - -/** - * @tc.name: EditingValueFilter001 - * @tc.desc: test EditingValueFilter - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, EditingValueFilter001, TestSize.Level1) -{ - auto layoutProperty = GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateTextInputType(TextInputType::NUMBER); - std::string result; - std::string valueToUpdate = "filter_value1test"; - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->EditingValueFilter(valueToUpdate, result); - EXPECT_EQ(valueToUpdate, "filter_value1test"); - layoutProperty->UpdateInputFilter("test"); - result = ""; - valueToUpdate = "filter_value1test"; - textFieldPattern->EditingValueFilter(valueToUpdate, result); - EXPECT_EQ(valueToUpdate, "test"); -} - -/** - * @tc.name: EditingValueFilter002 - * @tc.desc: test EditingValueFilter - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, EditingValueFilter002, TestSize.Level1) -{ - auto layoutProperty = GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateTextInputType(TextInputType::PHONE); - std::string result; - std::string valueToUpdate = "filter_value\\dtest"; - layoutProperty->UpdateInputFilter("test"); - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->EditingValueFilter(valueToUpdate, result); - EXPECT_EQ(valueToUpdate, "test"); -} - -/** - * @tc.name: EditingValueFilter003 - * @tc.desc: test EditingValueFilter - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, EditingValueFilter003, TestSize.Level1) -{ - auto layoutProperty = GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateTextInputType(TextInputType::EMAIL_ADDRESS); - std::string result; - std::string valueToUpdate = "filter_valuew+test"; - layoutProperty->UpdateInputFilter("test"); - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->EditingValueFilter(valueToUpdate, result); - EXPECT_EQ(valueToUpdate, "test"); -} - -/** - * @tc.name: EditingValueFilter004 - * @tc.desc: test EditingValueFilter - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, EditingValueFilter004, TestSize.Level1) -{ - auto layoutProperty = GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateTextInputType(TextInputType::URL); - std::string result; - std::string valueToUpdate = "filter_value//test"; - layoutProperty->UpdateInputFilter("test"); - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->EditingValueFilter(valueToUpdate, result); - EXPECT_EQ(valueToUpdate, "test"); -} - /** * @tc.name: GetTextOrPlaceHolderFontSize001 * @tc.desc: test GetTextOrPlaceHolderFontSize @@ -568,140 +453,6 @@ HWTEST_F(TextFieldPatternTestNg, GetTextOrPlaceHolderFontSize001, TestSize.Level EXPECT_EQ(size, 0.0f); } -/** - * @tc.name: UpdateCaretRect - * @tc.desc: test UpdateCaretRect - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretRect, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = frameNode->GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - frameNode->GetOrCreateFocusHub()->currentFocus_ = true; - - /** - * @tc.steps: step2. set clipboard avoid nullptr and call UpdateCaretRect. - * @tc.expected: Check it is not nullptr. - */ - auto pipeline = MockPipelineBase::GetCurrent(); - auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor()); - textFieldPattern->clipboard_ = clipboard; - - CaretUpdateType exptectFalseTypes[] = { CaretUpdateType::INPUT, CaretUpdateType::PRESSED, - CaretUpdateType::LONG_PRESSED, CaretUpdateType::EVENT, CaretUpdateType::DEL, CaretUpdateType::ICON_PRESSED, - CaretUpdateType::RIGHT_CLICK, CaretUpdateType::HANDLE_MOVE }; - for (auto caretType : exptectFalseTypes) { - textFieldPattern->caretUpdateType_ = caretType; - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - } - - textFieldPattern->caretUpdateType_ = CaretUpdateType::PRESSED; - textFieldPattern->isMousePressed_ = true; - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - - textFieldPattern->caretUpdateType_ = CaretUpdateType::ICON_PRESSED; - textFieldPattern->selectionMode_ = SelectionMode::SELECT; - textFieldPattern->textSelector_.baseOffset = 0; - textFieldPattern->textSelector_.destinationOffset = 5; - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - textFieldPattern->UpdateEditingValue("", 0); - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - - textFieldPattern->caretUpdateType_ = CaretUpdateType::NONE; - textFieldPattern->UpdateEditingValue(TEXT_VALUE, 0); - EXPECT_TRUE(textFieldPattern->UpdateCaretRect()); - - /** - * @tc.steps: step3. when textEditing empty, return false - * @tc.expected: Check it is not nullptr. - */ - textFieldPattern->UpdateEditingValue("", 0); - textFieldPattern->caretUpdateType_ = CaretUpdateType::NONE; - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - - textFieldPattern->caretUpdateType_ = CaretUpdateType::EVENT; - layoutProperty->UpdateShowPasswordIcon(false); - textFieldPattern->needToRefreshSelectOverlay_ = false; - textFieldPattern->cursorVisible_ = true; - textFieldPattern->isMousePressed_ = true; - textFieldPattern->UpdateEditingValue(TEXT_VALUE, 0); - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - - textFieldPattern->caretUpdateType_ = CaretUpdateType::PRESSED; - textFieldPattern->isMousePressed_ = false; - textFieldPattern->isFocusedBeforeClick_ = true; - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - - /** - * @tc.steps: step3. set in search node and call UpdateCaretRect. - * @tc.expected: Check it is not nullptr. - */ - auto* stack = ViewStackProcessor::GetInstance(); - int32_t nodeId = stack->ClaimNodeId(); - auto searchNode = AceType::MakeRefPtr(V2::SEARCH_ETS_TAG, nodeId, AceType::MakeRefPtr(), false); - frameNode->MountToParent(searchNode); - textFieldPattern->caretUpdateType_ = CaretUpdateType::HANDLE_MOVE; - EXPECT_TRUE(textFieldPattern->UpdateCaretRect()); -} - -/** - * @tc.name: AdjustTextRectOffset - * @tc.desc: test AdjustTextRectOffset. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, AdjustTextRectOffset, TestSize.Level2) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - - /** - * @tc.steps: step2. set isTextArea to true and call AdjustTextRectOffsetX,AdjustTextAreaOffsetY. - * @tc.expected: Check the return value. - */ - layoutProperty->UpdateMaxLines(2); - EXPECT_EQ(pattern->AdjustTextRectOffsetX(), 0.0f); - pattern->caretRect_.SetTop(10); - pattern->contentRect_.SetTop(8); - pattern->contentRect_.SetHeight(4); - EXPECT_EQ(pattern->AdjustTextAreaOffsetY(), 2.0f); - pattern->caretRect_.SetTop(5); - EXPECT_EQ(pattern->AdjustTextAreaOffsetY(), 7.0f); - pattern->caretRect_.SetTop(13); - EXPECT_EQ(pattern->AdjustTextAreaOffsetY(), -1.0f); - - /** - * @tc.steps: step3. set isTextArea to false and call AdjustTextRectOffsetX,AdjustTextAreaOffsetY. - * @tc.expected: Check the return value. - */ - layoutProperty->UpdateMaxLines(1); - EXPECT_EQ(pattern->AdjustTextAreaOffsetY(), 0.0f); - EXPECT_EQ(pattern->AdjustTextRectOffsetX(), 0.0f); - pattern->caretRect_.SetLeft(10); - pattern->contentRect_.SetLeft(8); - pattern->contentRect_.SetWidth(4); - EXPECT_EQ(pattern->AdjustTextRectOffsetX(), 0.0f); - pattern->caretRect_.SetLeft(7); - EXPECT_EQ(pattern->AdjustTextRectOffsetX(), 1.0f); - pattern->caretRect_.SetLeft(15); - EXPECT_EQ(pattern->AdjustTextRectOffsetX(), -3.0f); -} - /** * @tc.name: IsTextArea001 * @tc.desc: test IsTextArea @@ -720,95 +471,6 @@ HWTEST_F(TextFieldPatternTestNg, IsTextArea001, TestSize.Level1) EXPECT_TRUE(textFieldPattern->IsTextArea()); } -/** - * @tc.name: UpdateDestinationToCaretByEvent001 - * @tc.desc: test UpdateDestinationToCaretByEvent - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateDestinationToCaretByEvent001, TestSize.Level1) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - textFieldPattern->isMousePressed_ = true; - int32_t len = static_cast(TEXT_VALUE.size()); - textFieldPattern->UpdateEditingValue(TEXT_VALUE, len); - textFieldPattern->selectionMode_ = SelectionMode::NONE; - textFieldPattern->textSelector_.baseOffset = len; - textFieldPattern->UpdateDestinationToCaretByEvent(); - EXPECT_EQ(textFieldPattern->GetSelectMode(), SelectionMode::NONE); - textFieldPattern->textSelector_.baseOffset = 0; - textFieldPattern->UpdateDestinationToCaretByEvent(); - EXPECT_EQ(textFieldPattern->GetSelectMode(), SelectionMode::SELECT); -} - -/** - * @tc.name: UpdateCaretPositionByLastTouchOffset001 - * @tc.desc: test UpdateCaretPositionByLastTouchOffset - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretPositionByLastTouchOffset001, TestSize.Level1) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - SizeF contentSize(730.0, 160.0); - SizeF textSize(720.0, 150.0); - textFieldPattern->contentRect_.Reset(); - textFieldPattern->textRect_.Reset(); - textFieldPattern->caretRect_.Reset(); - textFieldPattern->contentRect_.SetSize(contentSize); - textFieldPattern->textRect_.SetSize(textSize); - textFieldPattern->InitEditingValueText(TEXT_VALUE); - textFieldPattern->lastTouchOffset_ = Offset(725.0, 0.0); - textFieldPattern->UpdateCaretPositionByLastTouchOffset(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, 0); - EXPECT_EQ(textFieldPattern->GetCaretOffsetX(), 0); -} - -/** - * @tc.name: UpdateCaretPositionByLastTouchOffset002 - * @tc.desc: test UpdateCaretPositionByLastTouchOffset - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretPositionByLastTouchOffset002, TestSize.Level1) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - SizeF contentSize(730.0, 160.0); - SizeF textSize(720.0, 150.0); - OffsetF textOffset(10.0, 0.0); - textFieldPattern->contentRect_.Reset(); - textFieldPattern->textRect_.Reset(); - textFieldPattern->caretRect_.Reset(); - textFieldPattern->contentRect_.SetSize(contentSize); - textFieldPattern->textRect_.SetSize(textSize); - textFieldPattern->textRect_.SetOffset(textOffset); - textFieldPattern->InitEditingValueText(TEXT_VALUE); - textFieldPattern->UpdateCaretPositionByLastTouchOffset(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, 0); -} - -/** - * @tc.name: UpdateCaretPositionByLastTouchOffset003 - * @tc.desc: test UpdateCaretPositionByLastTouchOffset - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretPositionByLastTouchOffset003, TestSize.Level2) -{ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - SizeF contentSize(710.0, 160.0); - SizeF textSize(720.0, 150.0); - textFieldPattern->contentRect_.Reset(); - textFieldPattern->textRect_.Reset(); - textFieldPattern->caretRect_.Reset(); - textFieldPattern->contentRect_.SetSize(contentSize); - textFieldPattern->textRect_.SetSize(textSize); - textFieldPattern->InitEditingValueText(TEXT_VALUE); - textFieldPattern->UpdateCaretPositionByLastTouchOffset(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, 0); - EXPECT_EQ(textFieldPattern->GetCaretOffsetX(), 0.0); -} - /** * @tc.name: CursorWidth001 * @tc.desc: Verify that the CursorWidth interface calls normally and exits without exception. @@ -862,7 +524,7 @@ HWTEST_F(TextFieldPatternTestNg, CaretPosition001, TestSize.Level1) layoutProperty->UpdateCaretPosition(CARET_POSITION); auto textFieldPattern = AceType::DynamicCast(frameNode->GetPattern()); textFieldPattern->OnModifyDone(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, CARET_POSITION); + EXPECT_EQ(textFieldPattern->GetTextSelectController()->GetCaretIndex(), CARET_POSITION); } /** @@ -879,26 +541,7 @@ HWTEST_F(TextFieldPatternTestNg, CaretPosition002, TestSize.Level1) auto layoutProperty = frameNode->GetLayoutProperty(); ASSERT_NE(layoutProperty, nullptr); layoutProperty->UpdateCaretPosition(CARET_POSITION); - textFieldPattern->UpdateCaretRectByPosition(CARET_POSITION); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, CARET_POSITION); -} - -/** - * @tc.name: CaretPosition003 - * @tc.desc: Verify that the CursorPosition interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CaretPosition003, TestSize.Level1) -{ - auto frameNode = GetFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = AceType::DynamicCast(frameNode->GetPattern()); - ASSERT_NE(textFieldPattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateCaretPosition(CARET_POSITION); - textFieldPattern->UpdateCaretPositionByPressOffset(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, CARET_POSITION); + EXPECT_EQ(textFieldPattern->GetTextSelectController()->GetCaretIndex(), CARET_POSITION); } /** @@ -923,26 +566,7 @@ HWTEST_F(TextFieldPatternTestNg, CaretPosition004, TestSize.Level1) ASSERT_NE(layoutProperty, nullptr); layoutProperty->UpdateCaretPosition(CARET_POSITION); textFieldPattern->InitEditingValueText(TEXT_VALUE); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, TEXT_VALUE.length()); -} - -/** - * @tc.name: CaretPosition005 - * @tc.desc: Verify that the CursorPosition interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CaretPosition005, TestSize.Level1) -{ - auto frameNode = GetFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = AceType::DynamicCast(frameNode->GetPattern()); - ASSERT_NE(textFieldPattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - layoutProperty->UpdateCaretPosition(CARET_POSITION); - textFieldPattern->textEditingValue_.text = "text"; - textFieldPattern->UpdateCaretPositionByPressOffset(); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, CARET_POSITION); + EXPECT_EQ(textFieldPattern->GetTextSelectController()->GetCaretIndex(), TEXT_VALUE.length()); } /** @@ -1057,7 +681,6 @@ HWTEST_F(TextFieldPatternTestNg, CheckScrollable004, TestSize.Level1) EXPECT_FALSE(textFieldPattern->scrollable_); layoutProperty->UpdateShowCounter(true); - textFieldPattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldPattern->CheckScrollable(); EXPECT_FALSE(textFieldPattern->scrollable_); } @@ -1074,8 +697,7 @@ HWTEST_F(TextFieldPatternTestNg, UpdateCaretRectByPosition001, TestSize.Level1) auto pattern = frameNode->GetPattern(); ASSERT_NE(pattern, nullptr); const int32_t position = 0; - pattern->UpdateCaretRectByPosition(position); - EXPECT_EQ(pattern->GetEditingValue().caretPosition, position); + EXPECT_EQ(pattern->GetTextSelectController()->GetCaretIndex(), position); } /** @@ -1343,31 +965,6 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldPatternUpdateScrollBarOffset002, TestS ASSERT_FALSE(!pattern->GetScrollBar() && !pattern->GetScrollBarProxy()); } -/** - * @tc.name: TextFieldPatternSearchNodeTest001 - * @tc.desc: Verify the parent search node branch. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, TextFieldPatternSearchNodeTest001, TestSize.Level1) -{ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto* stack = ViewStackProcessor::GetInstance(); - int32_t nodeId = stack->ClaimNodeId(); - auto searchNode = AceType::MakeRefPtr(V2::SEARCH_ETS_TAG, nodeId, AceType::MakeRefPtr(), false); - frameNode->MountToParent(searchNode); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - pattern->HasFocus(); - auto info = GestureEvent(); - pattern->UpdateCaretInfoToController(); - pattern->HandleClickEvent(info); - pattern->HandleLongPress(info); - auto mouseInfo = MouseInfo(); - pattern->HandleMouseEvent(mouseInfo); - EXPECT_EQ(pattern->IsSearchParentNode(), true); -} - /** * @tc.name: OffsetInContentRegion * @tc.desc: Verify the parent search node branch. @@ -1434,9 +1031,7 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldPatternOnTextAreaScroll001, TestSize.L pattern->isSingleHandle_ = false; pattern->OnTextAreaScroll(TEXT_AREA_SCROLL_OFFSET); pattern->isSingleHandle_ = true; - float oldCaretRectY = pattern->caretRect_.GetY(); pattern->OnTextAreaScroll(TEXT_AREA_SCROLL_OFFSET); - EXPECT_EQ(pattern->caretRect_.GetY(), oldCaretRectY); EXPECT_EQ(pattern->textRect_.GetOffset(), OffsetF(pattern->textRect_.GetX(), pattern->currentOffset_)); // Scroll down, secondHandleOffset Y > contentRect Y @@ -2796,7 +2391,6 @@ HWTEST_F(TextFieldPatternTestNg, AdjustTextSelectionRectOffsetX, TestSize.Level1 textFieldPattern->textBoxes_.begin()->SetWidth(10.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 60.0f); - EXPECT_EQ(textFieldPattern->unitWidth_, 0.0f); textFieldPattern->textBoxes_.begin()->SetWidth(120.0f); textFieldPattern->AdjustTextSelectionRectOffsetX(); EXPECT_EQ(textFieldPattern->textRect_.GetX(), 60.0f); @@ -2870,10 +2464,7 @@ HWTEST_F(TextFieldPatternTestNg, SetTextSelection001, TestSize.Level1) textFieldController->SetPattern(textFieldPattern); textFieldController->SetCaretPosition( [&caretPositionCallback](const int32_t caretPosition) { caretPositionCallback = caretPosition; }); - textFieldPattern->SetTextSelection(TEXT_SELECTION_START, TEXT_SELECTION_END); - textFieldPattern->SetTextSelection(TEXT_SELECTION_ERR, TEXT_SELECTION_END); - textFieldPattern->SetTextSelection(TEXT_SELECTION_END, TEXT_SELECTION_END); - EXPECT_EQ(textFieldPattern->GetTextEditingValue().caretPosition, CARET_POSITION_2); + EXPECT_EQ(textFieldPattern->GetTextSelectController()->GetCaretIndex(), CARET_POSITION_2); EXPECT_EQ(textFieldPattern->GetEditingValue().caretPosition, CARET_POSITION_2); } @@ -2931,30 +2522,6 @@ HWTEST_F(TextFieldPatternTestNg, SetUnderlineColor, TestSize.Level1) EXPECT_EQ(textFieldOverlayModifier.underlineColor_->Get(), value); } -/** - * @tc.name: GetUnitWidth - * @tc.desc: Verify that the GetUnitWidth interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, GetUnitWidth, TestSize.Level1) -{ - /** - * @tc.steps: step1. create textFieldPattern. - */ - auto textFieldPattern = GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - - /** - * @tc.steps: step2. call GetUnitWidth function. - * @tc.expected: The member variable value of textFieldPattern is the same as expected. - */ - EXPECT_EQ(textFieldPattern->GetUnitWidth(), 0.0f); - - float unitWidth = 1.0; - textFieldPattern->unitWidth_ = unitWidth; - EXPECT_EQ(textFieldPattern->GetUnitWidth(), unitWidth); -} - /** * @tc.name: SetShowUnderline001 * @tc.desc: Verify that the SetShowUnderline interface calls normally and exits without exception. @@ -3169,8 +2736,6 @@ HWTEST_F(TextFieldPatternTestNg, onDraw005, TestSize.Level1) layoutProperty->UpdateShowUnderline(true); bool value = true; textFieldContentModifier.showErrorState_ = AceType::MakeRefPtr(value); - textFieldContentModifier.showCounter_ = AceType::MakeRefPtr(value); - pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); pattern->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldContentModifier.onDraw(context); } @@ -3242,34 +2807,6 @@ HWTEST_F(TextFieldPatternTestNg, ProcessDefaultPadding, TestSize.Level1) EXPECT_EQ(paddings.top, NG::CalcLength(themePadding.Top().ConvertToPx())); } -/** - * @tc.name: SetShowCounter - * @tc.desc: Verify that the SetShowCounter interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, SetShowCounter, TestSize.Level1) -{ - /** - * @tc.steps: step1. create frameNode. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - TextFieldContentModifier textFieldContentModifier(pattern); - bool value = true; - - /** - * @tc.steps: step2. call SetShowCounter function. - * @tc.expected: The member variable value of textFieldContentModifier is the value set above. - */ - textFieldContentModifier.showCounter_ = nullptr; - textFieldContentModifier.SetShowCounter(value); - textFieldContentModifier.showCounter_ = AceType::MakeRefPtr(value); - textFieldContentModifier.SetShowCounter(value); - EXPECT_EQ(textFieldContentModifier.showCounter_->Get(), value); -} - /** * @tc.name: SetShowErrorState * @tc.desc: Verify that the SetShowErrorState interface calls normally and exits without exception. @@ -3298,77 +2835,6 @@ HWTEST_F(TextFieldPatternTestNg, SetShowErrorState, TestSize.Level1) EXPECT_EQ(textFieldContentModifier.showErrorState_->Get(), value); } -/** - * @tc.name: CreateCounterParagraph001 - * @tc.desc: Verify that the CreateCounterParagraph interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CreateCounterParagraph001, TestSize.Level1) -{ - /** - * @tc.steps: step1. create textFieldLayoutAlgorithm. - */ - TextFieldLayoutAlgorithm textFieldLayoutAlgorithm; - - /** - * @tc.steps: step2. call CreateCounterParagraph function. - * @tc.expected: The member variable value of textFieldLayoutAlgorithm is the value set above. - */ - constexpr int32_t textLength = 5; - constexpr int32_t maxLength = 10; - const RefPtr theme = AceType::MakeRefPtr(); - EXPECT_EQ(textFieldLayoutAlgorithm.counterParagraph_, nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); - textFieldLayoutAlgorithm.CreateCounterParagraph(textLength, maxLength, theme); - EXPECT_NE(textFieldLayoutAlgorithm.counterParagraph_, nullptr); -} - -/** - * @tc.name: CreateCounterParagraph002 - * @tc.desc: Verify that the CreateCounterParagraph interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CreateCounterParagraph002, TestSize.Level1) -{ - /** - * @tc.steps: step1. create textFieldLayoutAlgorithm. - */ - TextFieldLayoutAlgorithm textFieldLayoutAlgorithm; - - /** - * @tc.steps: step2. call CreateCounterParagraph function. - * @tc.expected: The member variable value of textFieldLayoutAlgorithm is the value set above. - */ - constexpr int32_t textLength = 10; - constexpr int32_t maxLength = 10; - const RefPtr theme = AceType::MakeRefPtr(); - EXPECT_EQ(textFieldLayoutAlgorithm.counterParagraph_, nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); - textFieldLayoutAlgorithm.CreateCounterParagraph(textLength, maxLength, theme); - EXPECT_NE(textFieldLayoutAlgorithm.counterParagraph_, nullptr); -} - -/** - * @tc.name: GetCounterParagraph - * @tc.desc: Verify that the GetCounterParagraph interface calls normally and exits without exception. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, GetCounterParagraph, TestSize.Level1) -{ - /** - * @tc.steps: step1. create textFieldLayoutAlgorithm. - */ - TextFieldLayoutAlgorithm textFieldLayoutAlgorithm; - - /** - * @tc.steps: step2. call CreateCounterParagraph function. - * @tc.expected: The member variable value of textFieldLayoutAlgorithm is the value set above. - */ - EXPECT_EQ(textFieldLayoutAlgorithm.GetCounterParagraph(), nullptr); - textFieldLayoutAlgorithm.counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); - EXPECT_NE(textFieldLayoutAlgorithm.GetCounterParagraph(), nullptr); -} - /** * @tc.name: HandleCounterBorder * @tc.desc: Verify that the HandleCounterBorder interface calls normally and exits without exception. @@ -3567,8 +3033,6 @@ HWTEST_F(TextFieldPatternTestNg, PaintCursor002, TestSize.Level1) * @tc.expected: Check the properties set successfully. */ textFieldOverlayModifier.cursorVisible_ = AceType::MakeRefPtr(true); - textFieldOverlayModifier.showCounter_ = AceType::MakeRefPtr(true); - pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldOverlayModifier.PaintCursor(context); } @@ -3609,8 +3073,6 @@ HWTEST_F(TextFieldPatternTestNg, PaintSelection004, TestSize.Level1) * @tc.steps: step2. Set properties. Call function PaintSelection. * @tc.expected: Check the properties set successfully. */ - textFieldOverlayModifier.showCounter_ = AceType::MakeRefPtr(true); - pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldOverlayModifier.inputStyle_ = InputStyle::DEFAULT; textFieldOverlayModifier.PaintSelection(context); } @@ -4027,7 +3489,6 @@ HWTEST_F(TextFieldPatternTestNg, ShowOverlay001, TestSize.Level1) std::optional firstHandle = RectF(0, 0, 0, 0); std::optional secondHandle = RectF(0, 0, 0, 0); - pattern->CheckHandles(firstHandle, secondHandle); // handles should be reset after CheckHandles EXPECT_EQ(firstHandle, std::nullopt); EXPECT_EQ(secondHandle, std::nullopt); @@ -4199,7 +3660,6 @@ HWTEST_F(TextFieldPatternTestNg, OnDirtyLayoutWrapperSwap, TestSize.Level2) EXPECT_TRUE(textFieldPattern->OnDirtyLayoutWrapperSwap(layoutWrapper, dirtySwapConfig)); layoutAlgorithm->paragraph_ = MockParagraph::GetOrCreateMockParagraph(); - layoutAlgorithm->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutAlgorithm->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutAlgorithm->errorParagraph_ = MockParagraph::GetOrCreateMockParagraph(); textFieldPattern->needToRefreshSelectOverlay_ = true; @@ -4499,7 +3959,6 @@ HWTEST_F(TextFieldPatternTestNg, TFLayoutAlgorithmMeasureContent, TestSize.Level layoutWrapper.Update(AceType::WeakClaim(AceType::RawPtr(frameNode)), cloneGeometryNode, cloneLayoutProperty); layoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_EQ(layoutWrapper.GetGeometryNode()->GetFrameSize().Width(), 0); - pattern->counterParagraph_ = MockParagraph::GetOrCreateMockParagraph(); layoutAlgorithm->MeasureContent(contentConstraint, &layoutWrapper); EXPECT_EQ(layoutWrapper.GetGeometryNode()->GetFrameSize().Width(), 0); cloneLayoutProperty->UpdateShowErrorText(true); @@ -4576,8 +4035,6 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldLayoutAlgorithmLayout, TestSize.Level2 pattern->caretUpdateType_ = CaretUpdateType::INPUT; pattern->mouseStatus_ = MouseStatus::PRESSED; pattern->isMousePressed_ = false; - layoutAlgorithm->imageRect_.SetWidth(5); - layoutAlgorithm->imageRect_.SetHeight(5); cloneLayoutProperty->UpdateShowUnderline(true); cloneLayoutProperty->UpdateShowErrorText(true); layoutProperty->UpdateTextInputType(TextInputType::VISIBLE_PASSWORD); @@ -4634,41 +4091,6 @@ HWTEST_F(TextFieldPatternTestNg, GetFontFamily, TestSize.Level2) EXPECT_STREQ(getFontFamily.c_str(), "Sans,serif"); } -/** - * @tc.name: UpdateCaretPositionByMouseMovement - * @tc.desc: test UpdateCaretPositionByMouseMovement. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretPositionByMouseMovement, TestSize.Level2) -{ - /** - * @tc.steps: step1. Create frameNode.Get pattern. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - - /** - * @tc.steps: step2. call function UpdateCaretPositionByMouseMovement. - * @tc.expected: Check the return value. - */ - EXPECT_FALSE(pattern->UpdateCaretPositionByMouseMovement()); - pattern->UpdateEditingValue(TEXT_VALUE, 5); - pattern->UpdateCaretPositionByMouseMovement(); - EXPECT_FALSE(pattern->UpdateCaretPositionByMouseMovement()); - - pattern->lastTouchOffset_.SetX(8); - pattern->contentRect_.SetLeft(4); - pattern->contentRect_.SetWidth(2); - EXPECT_TRUE(pattern->UpdateCaretPositionByMouseMovement()); - pattern->lastTouchOffset_.SetX(2); - EXPECT_TRUE(pattern->UpdateCaretPositionByMouseMovement()); - - pattern->UpdateEditingValue("", 0); - EXPECT_FALSE(pattern->UpdateCaretPositionByMouseMovement()); -} - /** * @tc.name: UpdateSelectionOffset * @tc.desc: test UpdateSelectionOffset. @@ -4702,8 +4124,6 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectionOffset, TestSize.Level2) pattern->textRect_.SetLeft(4); pattern->textRect_.SetWidth(4); pattern->UpdateSelectionOffset(); - EXPECT_EQ(pattern->GetTextSelector().selectionBaseOffset.GetX(), 4); - EXPECT_EQ(pattern->GetTextSelector().selectionDestinationOffset.GetX(), 8); std::vector textBoxes; RectF firstTextBox; @@ -4716,8 +4136,6 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectionOffset, TestSize.Level2) pattern->textRect_.SetTop(5); pattern->textRect_.SetHeight(5); pattern->selectOverlayProxy_ = AceType::MakeRefPtr(143); - EXPECT_EQ(pattern->GetTextSelector().selectionBaseOffset.GetX(), 4); - EXPECT_EQ(pattern->GetTextSelector().selectionDestinationOffset.GetX(), 8); layoutProperty->UpdateMaxLines(1); pattern->contentRect_.SetLeft(1); @@ -4728,77 +4146,12 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectionOffset, TestSize.Level2) EXPECT_FALSE(pattern->textSelector_.StartEqualToDest()); EXPECT_TRUE(pattern->selectionMode_ != SelectionMode::NONE); pattern->UpdateSelectionOffset(); - EXPECT_EQ(pattern->GetTextSelector().selectionBaseOffset.GetX(), 5); - EXPECT_EQ(pattern->GetTextSelector().selectionDestinationOffset.GetX(), 10); EXPECT_EQ(pattern->textSelector_.firstHandleOffset_.GetX(), 5.0f); EXPECT_EQ(pattern->textSelector_.firstHandleOffset_.GetY(), 8.0f); EXPECT_EQ(pattern->textSelector_.secondHandleOffset_.GetX(), 5.0f); EXPECT_EQ(pattern->textSelector_.secondHandleOffset_.GetY(), 8.0f); } -/** - * @tc.name: UpdateCaretPositionByTextEdit - * @tc.desc: test UpdateCaretPositionByTextEdit. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretPositionByTextEdit, TestSize.Level2) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - - /** - * @tc.steps: step2. let editing text be empty. - * @tc.expected: Check CaretRect property. - */ - layoutProperty->UpdateMaxLines(2); - layoutProperty->UpdateTextAlign(TextAlign::START); - pattern->textRect_.SetLeft(8); - pattern->textRect_.SetTop(5); - pattern->contentRect_.SetLeft(0); - pattern->contentRect_.SetWidth(6); - pattern->UpdateEditingValue("", 0); - std::pair textAligns[] = { - std::make_pair(TextAlign::START, 8.0f), - std::make_pair(TextAlign::CENTER, 3.0f), - std::make_pair(TextAlign::END, 4.5f), - std::make_pair(TextAlign::RIGHT, 8.0f), - }; - for (auto align : textAligns) { - layoutProperty->UpdateTextAlign(align.first); - pattern->UpdateCaretPositionByTextEdit(); - EXPECT_EQ(pattern->GetCaretRect().GetX(), align.second); - } - layoutProperty->UpdateTextAlign(TextAlign::START); - - /** - * @tc.steps: step3. let editing text caret position be zero. - * @tc.expected: Check CaretRect property. - */ - pattern->UpdateEditingValue(TEXT_VALUE, 0); - pattern->textEditingValue_.caretPosition = 0; - pattern->UpdateCaretPositionByTextEdit(); - EXPECT_EQ(pattern->GetCaretRect().GetX(), 8); - EXPECT_EQ(pattern->GetCaretRect().GetY(), 5); - - /** - * @tc.steps: step4. editing text not empty and caret position > 0. - * @tc.expected: Check CaretRect property. - */ - pattern->textEditingValue_.caretPosition = 1; - pattern->contentRect_.SetLeft(4); - pattern->UpdateCaretPositionByTextEdit(); - EXPECT_EQ(pattern->GetCaretRect().GetX(), 4); - EXPECT_EQ(pattern->GetCaretRect().GetY(), 8); -} - /** * @tc.name: GetCopyOptionString * @tc.desc: test GetCopyOptionString. @@ -4844,15 +4197,11 @@ HWTEST_F(TextFieldPatternTestNg, UpdateOtherHandleOnMove001, TestSize.Level1) auto pattern = GetPattern(); ASSERT_NE(pattern, nullptr); pattern->selectOverlayProxy_ = AceType::MakeRefPtr(-1); - pattern->isFirstHandle_ = true; auto oldSecondHandleOffset = pattern->textSelector_.secondHandleOffset_; - pattern->UpdateOtherHandleOnMove(1.0f, 1.0f); ASSERT_EQ(pattern->textSelector_.secondHandleOffset_.GetX(), oldSecondHandleOffset.GetX() + 1.0f); ASSERT_EQ(pattern->textSelector_.secondHandleOffset_.GetY(), oldSecondHandleOffset.GetY() + 1.0f); - pattern->isFirstHandle_ = false; auto oldFirstHandleOffset = pattern->textSelector_.firstHandleOffset_; - pattern->UpdateOtherHandleOnMove(-1.0f, -1.0f); ASSERT_EQ(pattern->textSelector_.firstHandleOffset_.GetX(), oldFirstHandleOffset.GetX() - 1.0f); ASSERT_EQ(pattern->textSelector_.firstHandleOffset_.GetY(), oldFirstHandleOffset.GetY() - 1.0f); } @@ -5244,11 +4593,9 @@ HWTEST_F(TextFieldPatternTestNg, CaretMoveToLastNewLineChar, TestSize.Level2) * @tc.expected: Check the editing value's crePosition. */ pattern->UpdateEditingValue("New\nLine\nChar", 0); - pattern->CaretMoveToLastNewLineChar(); EXPECT_EQ(pattern->textEditingValue_.caretPosition, 0); pattern->UpdateEditingValue("New\nLine\nChar", 10); - pattern->CaretMoveToLastNewLineChar(); - EXPECT_EQ(pattern->textEditingValue_.caretPosition, 8); + EXPECT_EQ(pattern->GetTextSelectController()->GetCaretIndex(), 8); } /** @@ -5314,8 +4661,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionRight, TestSize.Level2) pattern->UpdateEditingValue("HandleSelectionRight", 10); pattern->HandleSelectionRight(); EXPECT_EQ(pattern->GetSelectMode(), SelectionMode::SELECT); - EXPECT_EQ(pattern->GetTextSelector().GetStart(), 10); - EXPECT_EQ(pattern->GetTextSelector().GetEnd(), 1); /** * @tc.steps: step2. in select mode and call HandleSelectionRight. @@ -5327,7 +4672,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionRight, TestSize.Level2) pattern->UpdateEditingValue("HandleSelectionRight", 20); pattern->HandleSelectionRight(); EXPECT_EQ(pattern->GetSelectMode(), SelectionMode::SELECT); - EXPECT_EQ(pattern->GetTextSelector().GetEnd(), 11); pattern->selectionMode_ = SelectionMode::SELECT; pattern->textSelector_.baseOffset = 11; @@ -5335,7 +4679,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionRight, TestSize.Level2) pattern->UpdateEditingValue("HandleSelectionRight", 20); pattern->HandleSelectionRight(); EXPECT_EQ(pattern->GetSelectMode(), SelectionMode::NONE); - EXPECT_EQ(pattern->GetTextSelector().GetEnd(), 11); } /** @@ -5421,8 +4764,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionDown, TestSize.Level2) pattern->selectionMode_ = SelectionMode::SELECT; pattern->HandleSelectionDown(); pattern->selectionMode_ = SelectionMode::NONE; - pattern->caretRect_.SetTop(0); - pattern->caretRect_.SetLeft(0); pattern->textRect_.SetTop(0); pattern->HandleSelectionDown(); EXPECT_EQ(pattern->GetSelectMode(), SelectionMode::NONE); @@ -5468,8 +4809,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleSelectionUp, TestSize.Level2) pattern->selectionMode_ = SelectionMode::SELECT; pattern->HandleSelectionUp(); pattern->selectionMode_ = SelectionMode::NONE; - pattern->caretRect_.SetTop(0); - pattern->caretRect_.SetLeft(0); pattern->textRect_.SetTop(0); pattern->HandleSelectionUp(); EXPECT_EQ(pattern->GetSelectMode(), SelectionMode::NONE); @@ -5671,32 +5010,6 @@ HWTEST_F(TextFieldPatternTestNg, OnAreaChangedInner, TestSize.Level2) EXPECT_EQ(pattern->selectionMode_, SelectionMode::NONE); } -/** - * @tc.name: CreateSingleHandle - * @tc.desc: test CreateSingleHandle. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CreateSingleHandle, TestSize.Level2) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - /** - * @tc.steps: step2. call CreateSingleHandle. - * @tc.expected: Check the value of the updated property. - */ - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - - pattern->OnModifyDone(); - pattern->textEditingValue_.Reset(); - EXPECT_TRUE(pattern->textEditingValue_.Empty()); - pattern->CreateSingleHandle(); -} - /** * @tc.name: UpdateEditingValue * @tc.desc: test UpdateEditingValue. @@ -6067,7 +5380,6 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldPatternOnTextInputScroll001, TestSize. pattern->OnTextInputScroll(0.0f); pattern->isSingleHandle_ = true; pattern->OnTextInputScroll(0.0f); - EXPECT_EQ(pattern->caretRect_.GetX(), -90.0f); EXPECT_EQ(pattern->textRect_.GetOffset(), OffsetF(pattern->currentOffset_, pattern->textRect_.GetY())); // first handle and second handle are in contentRect's region. @@ -6113,29 +5425,14 @@ HWTEST_F(TextFieldPatternTestNg, FitInSafeArea, TestSize.Level1) AceType::DynamicCast(pipeline)->SetRootSize(1000, 1000); pipeline->GetSafeAreaManager()->UpdateKeyboardSafeArea(500.0f); pattern->caretUpdateType_ = CaretUpdateType::INPUT; - // test caret inside safeArea pattern->contentRect_ = RectF { 0.0f, 0.0f, 1000.0f, 1000.0f }; const RectF CARET_RECT_SAFE { 0.0f, 0.0f, 100.0f, 100.0f }; - pattern->caretRect_ = CARET_RECT_SAFE; - auto dy = pattern->AdjustTextAreaOffsetY(); - EXPECT_EQ(dy, 0.0f); - EXPECT_EQ(pattern->caretRect_, CARET_RECT_SAFE); - // test caret outside safeArea const RectF CARE_RECT_DANGEROUS { 600.0f, 600.0f, 100.0f, 100.0f }; - pattern->caretRect_ = CARE_RECT_DANGEROUS; - dy = pattern->AdjustTextAreaOffsetY(); // caretBottom is 200 below safeAreaBottom - EXPECT_EQ(dy, -200.0f); - EXPECT_EQ(pattern->caretRect_, CARE_RECT_DANGEROUS - OffsetF(0.0f, 200.0f)); - // test caret when keyboard is down pipeline->GetSafeAreaManager()->UpdateKeyboardSafeArea(0.0f); - pattern->caretRect_ = CARE_RECT_DANGEROUS; - dy = pattern->AdjustTextAreaOffsetY(); - EXPECT_EQ(dy, 195.0f); - EXPECT_EQ(pattern->caretRect_.GetX(), CARE_RECT_DANGEROUS.GetX()); int32_t charPosition[3] = { -1, 0, 2 }; auto content = pattern->CreateDisplayText(TEXT_CONTENT, charPosition[1], true); for (int i = 0; i < 3; i++) { @@ -6191,41 +5488,10 @@ HWTEST_F(TextFieldPatternTestNg, UpdateSelectorByPosition001, TestSize.Level1) */ pattern->textSelector_.baseOffset = 0; pattern->textSelector_.destinationOffset = 5; - pattern->UpdateSelectorByPosition(10); EXPECT_EQ(pattern->textSelector_.GetStart(), 10); EXPECT_EQ(pattern->textSelector_.GetEnd(), 11); } -/** - * @tc.name: OnScrollEndCallback001 - * @tc.desc: test textfield OnScrollEndCallback function. - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, OnScrollEndCallback001, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create the TextFieldPattern. - * @tc.expected: step1. Check the TextFieldPattern success. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto pattern = frameNode->GetPattern(); - ASSERT_NE(pattern, nullptr); - pattern->selectOverlayProxy_ = AceType::MakeRefPtr(SELECT_OVERLAY_ID); - - /** - * @tc.steps: step2. Call the OnScrollEndCallback. - * @tc.expected: the OnScrollEndCallback function called success without expection. - */ - bool originalIsMenuShow[2] = { true, false }; - for (int i = 0; i < 2; i++) { - pattern->originalIsMenuShow_ = originalIsMenuShow[i]; - EXPECT_EQ(pattern->originalIsMenuShow_, originalIsMenuShow[i]); - pattern->OnScrollEndCallback(); - EXPECT_NE(pattern->GetSelectOverlay(), nullptr); - } -} - /** * @tc.name: OnHandleMove001 * @tc.desc: test textfield OnHandleMove001 function. @@ -6417,54 +5683,6 @@ HWTEST_F(TextFieldPatternTestNg, TextFieldPatternApplyInlineState002, TestSize.L EXPECT_EQ(renderContext->GetBackgroundColor(), textFieldTheme->GetInlineBgColor()); } -/** - * @tc.name: BeforeCreateLayoutWrapper001 - * @tc.desc: test BeforeCreateLayoutWrapper - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, BeforeCreateLayoutWrapper001, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = frameNode->GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - frameNode->GetOrCreateFocusHub()->currentFocus_ = true; - - /** - * @tc.steps: step2. set clipboard avoid nullptr and call BeforeCreateLayoutWrapper. - * @tc.expected: Check it is not nullptr. - */ - auto pipeline = MockPipelineBase::GetCurrent(); - auto clipboard = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor()); - textFieldPattern->clipboard_ = clipboard; - - CaretUpdateType exptectFalseTypes[] = { CaretUpdateType::INPUT, CaretUpdateType::PRESSED, - CaretUpdateType::LONG_PRESSED, CaretUpdateType::EVENT, CaretUpdateType::DEL, CaretUpdateType::ICON_PRESSED, - CaretUpdateType::RIGHT_CLICK, CaretUpdateType::HANDLE_MOVE }; - for (auto caretType : exptectFalseTypes) { - textFieldPattern->caretUpdateType_ = caretType; - textFieldPattern->BeforeCreateLayoutWrapper(); - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); - } - - EXPECT_TRUE(textFieldPattern->CaretPositionCloseToTouchPosition()); - EXPECT_FALSE(textFieldPattern->SelectOverlayIsOn()); - EXPECT_TRUE(textFieldPattern->caretUpdateType_ != CaretUpdateType::LONG_PRESSED); - EXPECT_FALSE(textFieldPattern->isMousePressed_); - textFieldPattern->UpdateCaretByPressOrLongPress(); - textFieldPattern->UpdateCaretByRightClick(); - - textFieldPattern->caretUpdateType_ = CaretUpdateType::EVENT; - textFieldPattern->isMousePressed_ = true; - textFieldPattern->BeforeCreateLayoutWrapper(); - textFieldPattern->caretUpdateType_ = CaretUpdateType::PRESSED; - EXPECT_FALSE(textFieldPattern->UpdateCaretPositionByMouseMovement()); -} - /** * @tc.name: BeforeCreateLayoutWrapper002 * @tc.desc: test BeforeCreateLayoutWrapper @@ -6492,7 +5710,6 @@ HWTEST_F(TextFieldPatternTestNg, BeforeCreateLayoutWrapper002, TestSize.Level1) textFieldPattern->caretUpdateType_ = CaretUpdateType::DOUBLE_CLICK; textFieldPattern->BeforeCreateLayoutWrapper(); - EXPECT_FALSE(textFieldPattern->UpdateCaretRect()); EXPECT_FALSE(textFieldPattern->isDoubleClick_); textFieldPattern->caretUpdateType_ = CaretUpdateType::EVENT; @@ -6500,104 +5717,9 @@ HWTEST_F(TextFieldPatternTestNg, BeforeCreateLayoutWrapper002, TestSize.Level1) textFieldPattern->isDoubleClick_ = true; textFieldPattern->BeforeCreateLayoutWrapper(); textFieldPattern->caretUpdateType_ = CaretUpdateType::PRESSED; - EXPECT_FALSE(textFieldPattern->UpdateCaretPositionByMouseMovement()); EXPECT_FALSE(textFieldPattern->isDoubleClick_); } -/** - * @tc.name: UpdateCaretOffsetByEvent - * @tc.desc: test UpdateCaretOffsetByEvent - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, UpdateCaretOffsetByEvent, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = frameNode->GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - frameNode->GetOrCreateFocusHub()->currentFocus_ = true; - - /** - * @tc.steps: step2. set clipboard avoid nullptr and call UpdateCaretOffsetByEvent. - * @tc.expected: Check it is not nullptr. - */ - textFieldPattern->UpdateCaretOffsetByEvent(); - EXPECT_FALSE(textFieldPattern->textEditingValue_.text.empty()); - - textFieldPattern->textEditingValue_.Reset(); - textFieldPattern->textEditingValue_.text = TEXT_VALUE; - textFieldPattern->UpdateCaretOffsetByEvent(); - EXPECT_TRUE(textFieldPattern->isMousePressed_); - textFieldPattern->textEditingValue_.caretPosition = 10; - - textFieldPattern->isMousePressed_ = true; - textFieldPattern->UpdateCaretOffsetByEvent(); - EXPECT_FALSE(textFieldPattern->IsSelected()); - - frameNode->GetOrCreateFocusHub()->currentFocus_ = true; - textFieldPattern->textEditingValue_.text = TEXT_VALUE; - textFieldPattern->isMousePressed_ = false; - textFieldPattern->UpdateCaretOffsetByEvent(); - - textFieldPattern->textEditingValue_.text = ""; - textFieldPattern->UpdateCaretOffsetByEvent(); -} - -/** - * @tc.name: CalcCaretMetricsByPosition - * @tc.desc: test CalcCaretMetricsByPosition - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, CalcCaretMetricsByPosition, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - ASSERT_NE(frameNode, nullptr); - auto textFieldPattern = frameNode->GetPattern(); - ASSERT_NE(textFieldPattern, nullptr); - auto layoutProperty = frameNode->GetLayoutProperty(); - ASSERT_NE(layoutProperty, nullptr); - frameNode->GetOrCreateFocusHub()->currentFocus_ = true; - - /** - * @tc.steps: step2. set clipboard avoid nullptr and call CalcCaretMetricsByPosition. - * @tc.expected: Check it is not nullptr. - */ - textFieldPattern->textEditingValue_.caretPosition = 10; - textFieldPattern->textEditingValue_.text = TEXT_VALUE; - auto position = textFieldPattern->textEditingValue_.caretPosition; - CaretMetricsF baseMetrics; - CaretMetricsF destinationMetrics; - textFieldPattern->CalcCaretMetricsByPosition(position, baseMetrics); - textFieldPattern->CalcCaretMetricsByPosition(position, destinationMetrics, TextAffinity::UPSTREAM); - - /** - * @tc.steps: step3. set contentSize and textSize. contentWidth less than textWidth. - * @tc.expected: Check it is not nullptr. - */ - SizeF textSize(730.0, 160.0); - SizeF contentSize(720.0, 150.0); - textFieldPattern->contentRect_.Reset(); - textFieldPattern->textRect_.Reset(); - textFieldPattern->caretRect_.Reset(); - textFieldPattern->contentRect_.SetSize(contentSize); - textFieldPattern->textRect_.SetSize(textSize); - layoutProperty->UpdateMaxLines(1); - - EXPECT_FALSE(textFieldPattern->AdjustTextRectOffsetX()); - layoutProperty->UpdateMaxLines(2); - EXPECT_TRUE(textFieldPattern->IsTextArea()); -} - /** * @tc.name: GetDragUpperLeftCoordinates * @tc.desc: test GetDragUpperLeftCoordinates @@ -7354,99 +6476,6 @@ HWTEST_F(TextFieldPatternTestNg, CursorMove003, TestSize.Level1) EXPECT_EQ(pattern_->textEditingValue_.caretPosition, 3); } -/** - * @tc.name: TextFilter - * @tc.desc: test method of line position - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, TextFilter, TestSize.Level1) -{ - /** - * @tc.steps: step1. RunSetUp to Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - RunSetUp(); - /** - * @tc.steps: step2. call FilterWithEmail and FilterWithAscii. - * @tc.expected: Check result. - */ - std::string result = "wyz@@xx.com"; - EXPECT_TRUE(pattern_->FilterWithEmail(result)); - result = "wyz@xx.com"; - EXPECT_FALSE(pattern_->FilterWithEmail(result)); - - std::string valueToUpdate = "wyz测试"; - result = ""; - EXPECT_TRUE(pattern_->FilterWithAscii(valueToUpdate, result)); - EXPECT_STREQ(result.c_str(), "wyz"); -} - -/** - * @tc.name: ProcessPasswordIcon - * @tc.desc: test method of ProcessPasswordIcon - * @tc.type: FUNC - */ -HWTEST_F(TextFieldPatternTestNg, ProcessPasswordIcon, TestSize.Level1) -{ - /** - * @tc.steps: step1. RunSetUp to Create TextFieldPattern. - * @tc.expected: Check it is not nullptr. - */ - RunSetUp(); - /** - * @tc.steps: step2. call ProcessPasswordIcon. - * @tc.expected: Check result. - */ - layoutProperty_->UpdateTextInputType(TextInputType::VISIBLE_PASSWORD); - layoutProperty_->UpdateShowPasswordIcon(false); - pattern_->ProcessPasswordIcon(); - - layoutProperty_->UpdateShowPasswordIcon(true); - ImageSourceInfo imageSourceInfo; - layoutProperty_->UpdateHidePasswordSourceInfo(imageSourceInfo); - pattern_->textObscured_ = true; - pattern_->hideUserDefinedIcon_ = true; - - auto themeManager = AceType::MakeRefPtr(); - MockPipelineBase::GetCurrent()->SetThemeManager(themeManager); - EXPECT_CALL(*themeManager, GetTheme(_)).WillRepeatedly([](ThemeType type) -> RefPtr { - if (type == IconTheme::TypeId()) { - return AceType::MakeRefPtr(); - } - return AceType::MakeRefPtr(); - }); - - pattern_->ProcessPasswordIcon(); - ASSERT_NE(pattern_->hidePasswordImageLoadingCtx_, nullptr); - auto loadSuccessTask = pattern_->CreateLoadSuccessCallback(pattern_->textObscured_); - loadSuccessTask(imageSourceInfo); - EXPECT_NE(pattern_->hidePasswordCanvasImage_, nullptr); - auto loadFailTask = pattern_->CreateLoadFailCallback(pattern_->textObscured_); - loadFailTask(imageSourceInfo, "tdd error"); - auto dataReadyTask = pattern_->CreateDataReadyCallback(pattern_->textObscured_); - dataReadyTask(imageSourceInfo); - - pattern_->hideUserDefinedIcon_ = false; - imageSourceInfo.SetSrc("/pages/media/test.jpg"); - pattern_->ProcessPasswordIcon(); - loadFailTask(imageSourceInfo, "tdd error"); - - pattern_->textObscured_ = false; - pattern_->showUserDefinedIcon_ = true; - layoutProperty_->UpdateShowPasswordSourceInfo(imageSourceInfo); - pattern_->ProcessPasswordIcon(); - ASSERT_NE(pattern_->showPasswordImageLoadingCtx_, nullptr); - loadSuccessTask = pattern_->CreateLoadSuccessCallback(pattern_->textObscured_); - loadSuccessTask(imageSourceInfo); - loadFailTask = pattern_->CreateLoadFailCallback(pattern_->textObscured_); - loadFailTask(imageSourceInfo, "tdd error"); - - pattern_->showUserDefinedIcon_ = false; - pattern_->ProcessPasswordIcon(); - loadFailTask(imageSourceInfo, "tdd error"); - EXPECT_NE(pattern_->showPasswordCanvasImage_, nullptr); -} - /** * @tc.name: OnCursorTwinkling * @tc.desc: test method of OnCursorTwinkling @@ -7538,9 +6567,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleClickEvent, TestSize.Level1) * @tc.steps: step2. call HandleClickEvent. * @tc.expected: Check result. */ - auto renderContext = host_->GetRenderContext(); - auto mockRenderContext = AceType::DynamicCast(renderContext); - EXPECT_CALL(*mockRenderContext, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF())); auto focusHub = host_->GetOrCreateFocusHub(); focusHub->eventHub_.Upgrade()->SetEnabled(true); @@ -7566,7 +6592,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleClickEvent, TestSize.Level1) EXPECT_FALSE(pattern_->isMousePressed_); info.SetLocalLocation(Offset(90, 90)); - pattern_->imageRect_.SetWidth(20); pattern_->frameRect_.SetWidth(100); layoutProperty_->UpdateTextInputType(TextInputType::VISIBLE_PASSWORD); layoutProperty_->UpdateShowPasswordIcon(true); @@ -7599,9 +6624,6 @@ HWTEST_F(TextFieldPatternTestNg, HandleDoubleClickEvent, TestSize.Level1) * @tc.steps: step2. call HandleClickEvent function quickly to trigger doubleClick. * @tc.expected: Check result. */ - auto renderContext = host_->GetRenderContext(); - auto mockRenderContext = AceType::DynamicCast(renderContext); - EXPECT_CALL(*mockRenderContext, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF())); auto focusHub = host_->GetOrCreateFocusHub(); focusHub->eventHub_.Upgrade()->SetEnabled(true); diff --git a/frameworks/core/components_ng/test/pattern/text_picker/BUILD.gn b/frameworks/core/components_ng/test/pattern/text_picker/BUILD.gn index 431112e8f85..a223f66df6e 100644 --- a/frameworks/core/components_ng/test/pattern/text_picker/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/text_picker/BUILD.gn @@ -84,6 +84,7 @@ ohos_unittest("text_picker_test_ng") { "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", @@ -176,7 +177,7 @@ ohos_unittest("text_picker_test_ng") { "$ace_root/test/mock/core/render/mock_paragraph.cpp", "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", "$root_out_dir/arkui/framework/core/components/theme/theme_constants_default.cpp", - "textpicker_test_ng.cpp", + "text_picker_test_ng.cpp", ] deps = [ diff --git a/frameworks/core/components_ng/test/pattern/text_picker/textpicker_test_ng.cpp b/frameworks/core/components_ng/test/pattern/text_picker/text_picker_test_ng.cpp similarity index 100% rename from frameworks/core/components_ng/test/pattern/text_picker/textpicker_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/text_picker/text_picker_test_ng.cpp diff --git a/frameworks/core/components_ng/test/pattern/texttimer/BUILD.gn b/frameworks/core/components_ng/test/pattern/text_timer/BUILD.gn similarity index 86% rename from frameworks/core/components_ng/test/pattern/texttimer/BUILD.gn rename to frameworks/core/components_ng/test/pattern/text_timer/BUILD.gn index 72b2ac7c722..a64506c8e7d 100644 --- a/frameworks/core/components_ng/test/pattern/texttimer/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/text_timer/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("text_timer_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "text_timer_test_ng.cpp", - ] + sources = [ "text_timer_test_ng.cpp" ] } diff --git a/frameworks/core/components_ng/test/pattern/texttimer/text_timer_test_ng.cpp b/frameworks/core/components_ng/test/pattern/text_timer/text_timer_test_ng.cpp similarity index 100% rename from frameworks/core/components_ng/test/pattern/texttimer/text_timer_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/text_timer/text_timer_test_ng.cpp diff --git a/frameworks/core/components_ng/test/pattern/textfield/BUILD.gn b/frameworks/core/components_ng/test/pattern/textfield/BUILD.gn deleted file mode 100644 index 2de3a4c10e8..00000000000 --- a/frameworks/core/components_ng/test/pattern/textfield/BUILD.gn +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright (c) 2022-2023 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build/test.gni") -import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") - -ohos_unittest("textfield_test_ng") { - module_out_path = pattern_test_output_path - - sources = [ - "$ace_root/frameworks/base/geometry/animatable_dimension.cpp", - "$ace_root/frameworks/base/geometry/dimension.cpp", - "$ace_root/frameworks/base/geometry/least_square_impl.cpp", - "$ace_root/frameworks/base/geometry/matrix3.cpp", - "$ace_root/frameworks/base/geometry/matrix4.cpp", - "$ace_root/frameworks/base/json/json_util.cpp", - "$ace_root/frameworks/base/test/mock/mock_drag_window.cpp", - "$ace_root/frameworks/base/test/mock/mock_ressched_report.cpp", - "$ace_root/frameworks/base/test/mock/mock_socperf_client_impl.cpp", - "$ace_root/frameworks/base/test/mock/mock_subwindow_manager.cpp", - "$ace_root/frameworks/base/test/mock/mock_system_properties.cpp", - "$ace_root/frameworks/base/utils/base_id.cpp", - "$ace_root/frameworks/base/utils/string_expression.cpp", - "$ace_root/frameworks/base/utils/string_utils.cpp", - "$ace_root/frameworks/base/utils/time_util.cpp", - "$ace_root/frameworks/core/animation/anticipate_curve.cpp", - "$ace_root/frameworks/core/animation/cubic_curve.cpp", - "$ace_root/frameworks/core/animation/curves.cpp", - "$ace_root/frameworks/core/animation/scheduler.cpp", - "$ace_root/frameworks/core/animation/test/mock/mock_animator.cpp", - "$ace_root/frameworks/core/common/container_scope.cpp", - "$ace_root/frameworks/core/common/ime/text_editing_value.cpp", - "$ace_root/frameworks/core/common/ime/text_input_connection.cpp", - "$ace_root/frameworks/core/common/ime/text_input_proxy.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", - "$ace_root/frameworks/core/common/test/mock/mock_clipboard.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_column_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_container_info.cpp", - "$ace_root/frameworks/core/components/common/layout/grid_system_manager.cpp", - "$ace_root/frameworks/core/components/common/layout/screen_system_manager.cpp", - "$ace_root/frameworks/core/components/common/properties/alignment.cpp", - "$ace_root/frameworks/core/components/common/properties/color.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow.cpp", - "$ace_root/frameworks/core/components/common/properties/shadow_config.cpp", - "$ace_root/frameworks/core/components/test/unittest/mock/ace_trace_mock.cpp", - "$ace_root/frameworks/core/components_ng/base/frame_node.cpp", - "$ace_root/frameworks/core/components_ng/base/geometry_node.cpp", - "$ace_root/frameworks/core/components_ng/base/modifier.cpp", - "$ace_root/frameworks/core/components_ng/base/ui_node.cpp", - "$ace_root/frameworks/core/components_ng/base/view_abstract.cpp", - "$ace_root/frameworks/core/components_ng/base/view_stack_processor.cpp", - "$ace_root/frameworks/core/components_ng/event/click_event.cpp", - "$ace_root/frameworks/core/components_ng/event/drag_event.cpp", - "$ace_root/frameworks/core/components_ng/event/event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/focus_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/gesture_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event.cpp", - "$ace_root/frameworks/core/components_ng/event/input_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/event/pan_event.cpp", - "$ace_root/frameworks/core/components_ng/event/state_style_manager.cpp", - "$ace_root/frameworks/core/components_ng/event/touch_event.cpp", - "$ace_root/frameworks/core/components_ng/gestures/gesture_referee.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/click_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/gesture_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/long_press_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/multi_fingers_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/pan_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/recognizer_group.cpp", - "$ace_root/frameworks/core/components_ng/gestures/recognizers/sequenced_recognizer.cpp", - "$ace_root/frameworks/core/components_ng/layout/box_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_property.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", - "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", - "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", - "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/button/toggle_button_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/custom/custom_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/flex/flex_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/image/image_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_item/menu_item_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/menu_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/multi_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/preview/menu_preview_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/sub_menu_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/option/option_view.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/inner/scroll_bar.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll/scroll_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.cpp", - "$ace_root/frameworks/core/components_ng/pattern/scroll_bar/scroll_bar_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/search/search_event_hub.cpp", - "$ace_root/frameworks/core/components_ng/pattern/search/search_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/select_overlay/select_overlay_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/page_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/stage/stage_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/span_node.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_pattern.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_manager.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.cpp", - "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp", - "$ace_root/frameworks/core/components_ng/property/accessibility_property.cpp", - "$ace_root/frameworks/core/components_ng/property/border_property.cpp", - "$ace_root/frameworks/core/components_ng/property/calc_length.cpp", - "$ace_root/frameworks/core/components_ng/property/grid_property.cpp", - "$ace_root/frameworks/core/components_ng/property/measure_utils.cpp", - "$ace_root/frameworks/core/components_ng/property/property.cpp", - "$ace_root/frameworks/core/components_ng/property/safe_area_insets.cpp", - "$ace_root/frameworks/core/components_ng/render/drawing_prop_convertor.cpp", - "$ace_root/frameworks/core/components_ng/render/image_painter.cpp", - "$ace_root/frameworks/core/components_ng/render/paint_wrapper.cpp", - "$ace_root/frameworks/core/components_ng/syntax/lazy_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_long_press_event.cpp", - "$ace_root/frameworks/core/components_ng/test/event/mock/mock_scrollable_event.cpp", - "$ace_root/frameworks/core/components_ng/test/event/scrollable_event/mock_scrollable.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/animation/mock_geometry_transition.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/base/mock_localization.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_loading_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_source_info.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/grid_container/mock_grid_container_layout_property.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/root/mock_root_layout_algorithm.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_bar_overlay_modifier.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/moc_refresh_coordination.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/pattern/scrollable/mock_scrollable_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_animation_utils.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_modifier_adapter.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_context_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/render/mock_render_surface_creator.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/rosen/testing_typography_style.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/syntax/mock_for_each_node.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock/mock_image_pattern.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/image/mock_icon_theme.cpp", - "$ace_root/frameworks/core/components_ng/test/pattern/text/mock/mock_text_layout_adapter.cpp", - "$ace_root/frameworks/core/components_v2/inspector/inspector_constants.cpp", - "$ace_root/frameworks/core/gestures/velocity_tracker.cpp", - "$ace_root/frameworks/core/pipeline/base/constants.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_element_register.cpp", - "$ace_root/frameworks/core/pipeline_ng/test/mock/mock_pipeline_base.cpp", - "$ace_root/test/mock/base/mock_frame_trace_adapter.cpp", - "$ace_root/test/mock/core/common/mock_ace_engine.cpp", - "$ace_root/test/mock/core/common/mock_container.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "$ace_root/test/mock/core/render/mock_font_collection.cpp", - "$ace_root/test/mock/core/render/mock_paragraph.cpp", - "$ace_root/test/unittest/core/pipeline/mock_drag_drop_manager.cpp", - "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", - "textfield_test_ng.cpp", - ] - - deps = [ - "$ace_root/frameworks/base:ace_memory_monitor_ohos", - "$ace_root/frameworks/core/components/theme:build_theme_code", - "$ace_root/test/unittest:ace_engine_unittest_flutter_deps", - "$ace_root/test/unittest:ace_unittest_log", - "$cjson_root:cjson_static", - "//third_party/bounds_checking_function:libsec_shared", - "//third_party/googletest:gmock_main", - "//third_party/icu/icu4c:shared_icui18n", - "//third_party/icu/icu4c:shared_icuuc", - ] - - external_deps = [] - if (enable_graphic_text_gine) { - external_deps += [ "graphic_2d:rosen_text" ] - } - configs = [ "$ace_root/test/unittest:ace_unittest_config" ] -} diff --git a/frameworks/core/components_ng/test/pattern/time_picker/BUILD.gn b/frameworks/core/components_ng/test/pattern/time_picker/BUILD.gn index 8db918f1c0a..4e4ff778b63 100644 --- a/frameworks/core/components_ng/test/pattern/time_picker/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/time_picker/BUILD.gn @@ -85,6 +85,7 @@ ohos_unittest("time_picker_test_ng") { "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/pattern/button/button_layout_algorithm.cpp", @@ -176,7 +177,7 @@ ohos_unittest("time_picker_test_ng") { "$ace_root/test/mock/core/render/mock_paragraph.cpp", "$ace_root/test/unittest/core/pipeline/mock_overlay_manager.cpp", "$root_out_dir/arkui/framework/core/components/theme/theme_constants_default.cpp", - "timepicker_test_ng.cpp", + "time_picker_test_ng.cpp", ] deps = [ diff --git a/frameworks/core/components_ng/test/pattern/time_picker/timepicker_test_ng.cpp b/frameworks/core/components_ng/test/pattern/time_picker/time_picker_test_ng.cpp similarity index 100% rename from frameworks/core/components_ng/test/pattern/time_picker/timepicker_test_ng.cpp rename to frameworks/core/components_ng/test/pattern/time_picker/time_picker_test_ng.cpp diff --git a/frameworks/core/components_ng/test/pattern/waterflow/BUILD.gn b/frameworks/core/components_ng/test/pattern/waterflow/BUILD.gn index eec67adad13..8dc5528bc2c 100644 --- a/frameworks/core/components_ng/test/pattern/waterflow/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/waterflow/BUILD.gn @@ -18,7 +18,6 @@ ace_unittest("water_flow_test_ng") { type = "new" sources = [ "$ace_root/frameworks/core/components_ng/test/pattern/test_ng.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "water_flow_test_ng.cpp", ] } diff --git a/test/mock/core/pattern/window_scene/mock_window_pattern.cpp b/test/mock/core/pattern/window_scene/mock_window_pattern.cpp deleted file mode 100644 index 35b0aedcc9b..00000000000 --- a/test/mock/core/pattern/window_scene/mock_window_pattern.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "core/components_ng/pattern/window_scene/scene/window_pattern.h" - -namespace OHOS::Ace::NG { -void WindowPattern::RegisterLifecycleListener() {} - -void WindowPattern::UnregisterLifecycleListener() {} - -void WindowPattern::CreateStartingNode() {} - -void WindowPattern::CreateSnapshotNode(std::optional> snapshot) {} - -void WindowPattern::OnAttachToFrameNode() {} - -void WindowPattern::DispatchPointerEvent(const std::shared_ptr& pointerEvent) {} - -void WindowPattern::DispatchKeyEvent(const std::shared_ptr& keyEvent) {} - -void WindowPattern::DispatchKeyEventForConsumed(const std::shared_ptr& keyEvent, bool& isConsumed) {} - -void WindowPattern::DisPatchFocusActiveEvent(bool isFocusActive) {} - -void WindowPattern::OnModifyDone() {} - -void WindowPattern::TransferFocusState(bool focusState) {} -} // namespace OHOS::Ace::NG diff --git a/test/mock/core/render/mock_paragraph.h b/test/mock/core/render/mock_paragraph.h index 920e097f348..4c6d4f6e166 100644 --- a/test/mock/core/render/mock_paragraph.h +++ b/test/mock/core/render/mock_paragraph.h @@ -56,8 +56,8 @@ public: MOCK_METHOD3(GetWordBoundary, bool(int32_t offset, int32_t& start, int32_t& end)); MOCK_METHOD3( CalcCaretMetricsByPosition, bool(int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity)); - MOCK_METHOD3( - CalcCaretMetricsByPosition, bool(int32_t extent, CaretMetricsF& caretCaretMetric, OffsetF lastTouchOffsetF)); + MOCK_METHOD3(CalcCaretMetricsByPosition, + bool(int32_t extent, CaretMetricsF& caretCaretMetric, const OffsetF& lastTouchOffsetF)); static RefPtr GetOrCreateMockParagraph(); static void TearDown(); diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 2efad523871..6dde7dc1575 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -214,6 +214,7 @@ ohos_source_set("ace_components_manager") { "$ace_root/frameworks/core/components_ng/manager/drag_drop/drag_drop_proxy.cpp", "$ace_root/frameworks/core/components_ng/manager/full_screen/full_screen_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/manager/shared_overlay/shared_overlay_manager.cpp", @@ -407,6 +408,7 @@ source_set("ace_components_mock") { "$ace_root/test/mock/base/mock_jank_frame_report.cpp", "$ace_root/test/mock/core/common/mock_ace_engine.cpp", "$ace_root/test/mock/core/common/mock_container.cpp", + "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "$ace_root/test/mock/core/render/mock_font_collection.cpp", "$ace_root/test/mock/core/render/mock_paragraph.cpp", "$ace_root/test/mock/interfaces/mock_ace_forward_compatibility.cpp", @@ -720,6 +722,7 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/search/search_node.cpp", "$ace_root/frameworks/core/components_ng/pattern/search/search_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/search/search_pattern.cpp", + "$ace_root/frameworks/core/components_ng/pattern/search/search_text_field.cpp", "$ace_root/frameworks/core/components_ng/pattern/select/select_accessibility_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/select/select_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/select/select_model_ng.cpp", @@ -794,6 +797,7 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/text/text_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/text/text_pattern.cpp", "$ace_root/frameworks/core/components_ng/pattern/text/text_styles.cpp", + "$ace_root/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_clock/text_clock_accessibility_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_clock/text_clock_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_clock/text_clock_layout_property.cpp", @@ -802,6 +806,7 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/text_drag/text_drag_overlay_modifier.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_drag/text_drag_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_drag/text_drag_pattern.cpp", + "$ace_root/frameworks/core/components_ng/pattern/text_field/content_controller.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_accessibility_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_content_modifier.cpp", @@ -813,6 +818,9 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_paint_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp", + "$ace_root/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp", + "$ace_root/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp", + "$ace_root/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/texttimer/text_timer_accessibility_property.cpp", "$ace_root/frameworks/core/components_ng/pattern/texttimer/text_timer_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/texttimer/text_timer_layout_property.cpp", diff --git a/test/unittest/ace_unittest.gni b/test/unittest/ace_unittest.gni index 5b696c8fd11..477dbda312f 100644 --- a/test/unittest/ace_unittest.gni +++ b/test/unittest/ace_unittest.gni @@ -72,6 +72,7 @@ template("ace_unittest") { ace_unittest_deps += invoker.extra_deps } + # ---------------------------- temporary support if (render) { ace_unittest_deps += [ "$graphic_2d_path/rosen/modules/render_service_base:librender_service_base", @@ -102,6 +103,8 @@ template("ace_unittest") { flutter_external_deps = [ "eventhandler:libeventhandler" ] } + # ---------------------------- + if (type == "components") { ohos_unittest(ace_unittest_name) { module_out_path = "ace_engine/${module_output}" diff --git a/test/unittest/core/base/frame_node/frame_node_test_ng.cpp b/test/unittest/core/base/frame_node/frame_node_test_ng.cpp index de87d65f3aa..5cc835684d2 100644 --- a/test/unittest/core/base/frame_node/frame_node_test_ng.cpp +++ b/test/unittest/core/base/frame_node/frame_node_test_ng.cpp @@ -316,7 +316,7 @@ HWTEST_F(FrameNodeTestNg, FrameNodeTouchTest, TestSize.Level1) auto globalPoint = PointF(10, 10); auto touchTestResult = std::list>(); - EXPECT_CALL(*mockRenderContext, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF(0, 0, 100, 100))); + mockRenderContext->rect_ = RectF(0, 0, 100, 100); EXPECT_CALL(*mockRenderContext, GetPointWithTransform(_)).WillRepeatedly(DoAll(SetArgReferee<0>(localPoint))); /** @@ -326,7 +326,7 @@ HWTEST_F(FrameNodeTestNg, FrameNodeTouchTest, TestSize.Level1) childNode->SetExclusiveEventForChild(true); auto mockRenderContextforChild = AceType::MakeRefPtr(); childNode->renderContext_ = mockRenderContextforChild; - EXPECT_CALL(*mockRenderContextforChild, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF(0, 0, 100, 100))); + mockRenderContext->rect_ = RectF(0, 0, 100, 100); EXPECT_CALL(*mockRenderContextforChild, GetPointWithTransform(_)) .WillRepeatedly(DoAll(SetArgReferee<0>(localPoint))); childNode->GetOrCreateGestureEventHub(); @@ -347,7 +347,7 @@ HWTEST_F(FrameNodeTestNg, FrameNodeTouchTest, TestSize.Level1) auto grandChildNode = FrameNode::CreateFrameNode("main", 3, AceType::MakeRefPtr(), true); grandChildNode->SetExclusiveEventForChild(true); grandChildNode->renderContext_ = mockRenderContextforChild; - EXPECT_CALL(*mockRenderContextforChild, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF(0, 0, 100, 100))); + mockRenderContext->rect_ = RectF(0, 0, 100, 100); EXPECT_CALL(*mockRenderContextforChild, GetPointWithTransform(_)) .WillRepeatedly(DoAll(SetArgReferee<0>(localPoint))); grandChildNode->GetOrCreateGestureEventHub(); @@ -1616,7 +1616,7 @@ HWTEST_F(FrameNodeTestNg, FrameNodeTouchTest042, TestSize.Level1) auto mockRenderContextforChild = AceType::MakeRefPtr(); childNode->renderContext_ = mockRenderContextforChild; auto localPoint = PointF(10, 10); - EXPECT_CALL(*mockRenderContextforChild, GetPaintRectWithTransform()).WillRepeatedly(Return(RectF(0, 0, 100, 100))); + mockRenderContextforChild->rect_ = RectF(0, 0, 100, 100); EXPECT_CALL(*mockRenderContextforChild, GetPointWithTransform(_)) .WillRepeatedly(DoAll(SetArgReferee<0>(localPoint))); auto childEventHub = childNode->GetOrCreateGestureEventHub(); diff --git a/test/unittest/core/base/view_abstract/BUILD.gn b/test/unittest/core/base/view_abstract/BUILD.gn index 0c81154e5be..fb343ff5d1e 100755 --- a/test/unittest/core/base/view_abstract/BUILD.gn +++ b/test/unittest/core/base/view_abstract/BUILD.gn @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//build/test.gni") import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ohos_unittest("view_abstract_test_ng") { @@ -92,6 +91,9 @@ ohos_unittest("view_abstract_test_ng") { "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_paint_method.cpp", "$ace_root/frameworks/core/components_ng/pattern/bubble/bubble_pattern.cpp", @@ -206,8 +208,6 @@ ohos_unittest("view_abstract_test_ng") { "$ace_root/frameworks/core/components_ng/test/mock/image_provider/mock_image_painter.cpp", "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_manager.cpp", "$ace_root/frameworks/core/components_ng/test/mock/manager/drag_drop/mock_drag_drop_proxy.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_manager.cpp", - "$ace_root/frameworks/core/components_ng/test/mock/manager/select_overlay/mock_select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/test/mock/pattern/nav_bar/mock_nav_bar_pattern.cpp", "$ace_root/frameworks/core/components_ng/test/mock/pattern/popup/mock_popup_base_pattern.cpp", "$ace_root/frameworks/core/components_ng/test/mock/pattern/scroll/mock_scroll_bar_overlay_modifier.cpp", diff --git a/test/unittest/core/pattern/badge/BUILD.gn b/test/unittest/core/pattern/badge/BUILD.gn index 10584ac1dc1..6c1666819b0 100644 --- a/test/unittest/core/pattern/badge/BUILD.gn +++ b/test/unittest/core/pattern/badge/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("badge_test_ng") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "badge_test_ng.cpp", - ] + sources = [ "badge_test_ng.cpp" ] } diff --git a/test/unittest/core/pattern/text_field/BUILD.gn b/test/unittest/core/pattern/text_field/BUILD.gn index 78d95212d27..f973542c0a2 100644 --- a/test/unittest/core/pattern/text_field/BUILD.gn +++ b/test/unittest/core/pattern/text_field/BUILD.gn @@ -15,8 +15,5 @@ import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") ace_unittest("TextFieldTest") { type = "new" - sources = [ - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", - "text_field_test.cpp", - ] + sources = [ "text_field_test.cpp" ] } diff --git a/test/unittest/core/pattern/text_field/text_field_test.cpp b/test/unittest/core/pattern/text_field/text_field_test.cpp index c02257239b7..3fbd2ec1724 100644 --- a/test/unittest/core/pattern/text_field/text_field_test.cpp +++ b/test/unittest/core/pattern/text_field/text_field_test.cpp @@ -13,21 +13,25 @@ * limitations under the License. */ +#include #include #include #include -#include "gmock/gmock.h" #include "gtest/gtest.h" +#include "base/memory/ace_type.h" +#include "base/memory/referenced.h" +#include "base/utils/string_utils.h" + #define private public #define protected public #include "test/mock/base/mock_task_executor.h" #include "test/mock/core/common/mock_container.h" +#include "test/mock/core/render/mock_paragraph.h" #include "base/geometry/dimension.h" -#include "base/utils/utils.h" #include "core/common/ime/text_input_type.h" #include "core/components/common/layout/constants.h" #include "core/components/common/properties/color.h" @@ -35,13 +39,13 @@ #include "core/components/scroll/scroll_bar_theme.h" #include "core/components/text_field/textfield_theme.h" #include "core/components/theme/theme_manager.h" -#include "core/components_ng/pattern/root/root_pattern.h" #include "core/components_ng/pattern/text_field/text_field_manager.h" #include "core/components_ng/pattern/text_field/text_field_model_ng.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" +#include "core/components_ng/test/mock/render/mock_render_context.h" #include "core/components_ng/test/mock/theme/mock_theme_manager.h" +#include "core/components_ng/test/pattern/test_ng.h" #include "core/event/key_event.h" -#include "core/pipeline/base/element_register.h" #include "core/pipeline_ng/test/mock/mock_pipeline_base.h" #undef private @@ -51,7 +55,7 @@ using namespace testing; using namespace testing::ext; namespace OHOS::Ace::NG { - +namespace { template struct TestItem { CheckItem item; @@ -63,105 +67,113 @@ struct TestItem { TestItem() = default; }; +constexpr double ICON_SIZE = 24; +constexpr double ICON_HOT_ZONE_SIZE = 40; +constexpr double FONT_SIZE = 16; +constexpr int32_t DEFAULT_NODE_ID = 1; +const std::string DEFAULT_TEXT = "abcdefghijklmnopqrstuvwxyz"; +const std::string DEFAULT_PLACE_HOLDER = "please input text here"; using TextFiledModelUpdater = std::function; +} // namespace class TextFieldTestBase : public testing::Test { -public: +protected: static void SetUpTestSuite(); static void TearDownTestSuite(); - void SetUp() override; void TearDown() override; -protected: - RefPtr CreateTextFieldNode(int32_t id, std::string text, std::string placeHolder, bool isTextArea, - TextFiledModelUpdater&& modelUpdater = nullptr); - void CreateOrUpdate(int32_t id, std::string text, std::string placeHolder, bool isTextArea, - TextFiledModelUpdater&& modelUpdater = nullptr); + void CreateTextFieldNode(const std::string& text, const std::string& placeHolder, bool isTextArea, + std::function&& modelUpdater); + void RunMeasureAndLayout(); + void GetFocus(); + + RefPtr paragraph_; RefPtr frameNode_; RefPtr pattern_; - RefPtr mockThemeManager_ = AceType::MakeRefPtr(); - int32_t id_ = -1; - std::string text_ = "abcedefghijklmnopqrstuvwxyz"; - std::string placeHolder_ = "abcedefghijklmnopqrstuvwxyz"; }; void TextFieldTestBase::SetUpTestSuite() { MockContainer::SetUp(); MockPipelineBase::SetUp(); - MockPipelineBase::GetCurrent()->SetRootSize(500, 500); - MockPipelineBase::GetCurrent()->rootNode_ = - FrameNode::CreateFrameNodeWithTree(V2::ROOT_ETS_TAG, 0, AceType::MakeRefPtr()); - MockPipelineBase::GetCurrent()->SetTextFieldManager(AceType::MakeRefPtr()); - MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr(); -} - -void TextFieldTestBase::TearDownTestSuite() -{ - MockContainer::TearDown(); - MockPipelineBase::TearDown(); -} - -void TextFieldTestBase::SetUp() -{ - MockPipelineBase::GetCurrent()->SetThemeManager(mockThemeManager_); + MockPipelineBase::GetCurrent()->SetRootSize(DEVICE_WIDTH, DEVICE_HEIGHT); + auto themeManager = AceType::MakeRefPtr(); + MockPipelineBase::GetCurrent()->SetThemeManager(themeManager); auto textFieldTheme = AceType::MakeRefPtr(); - textFieldTheme->iconSize_ = Dimension(24, DimensionUnit::VP); - textFieldTheme->iconHotZoneSize_ = Dimension(40, DimensionUnit::VP); - textFieldTheme->fontSize_ = Dimension(16, DimensionUnit::FP); + textFieldTheme->iconSize_ = Dimension(ICON_SIZE, DimensionUnit::VP); + textFieldTheme->iconHotZoneSize_ = Dimension(ICON_HOT_ZONE_SIZE, DimensionUnit::VP); + textFieldTheme->fontSize_ = Dimension(FONT_SIZE, DimensionUnit::FP); textFieldTheme->fontWeight_ = FontWeight::W400; textFieldTheme->textColor_ = Color::FromString("#ff182431"); - - EXPECT_CALL(*mockThemeManager_, GetTheme(_)) - .WillRepeatedly([this, textFieldTheme = textFieldTheme](ThemeType type) -> RefPtr { + EXPECT_CALL(*themeManager, GetTheme(_)) + .WillRepeatedly([textFieldTheme = textFieldTheme](ThemeType type) -> RefPtr { if (type == ScrollBarTheme::TypeId()) { return AceType::MakeRefPtr(); } return textFieldTheme; }); - CreateOrUpdate(1, text_, placeHolder_, false); + MockPipelineBase::GetCurrent()->SetTextFieldManager(AceType::MakeRefPtr()); + MockContainer::Current()->taskExecutor_ = AceType::MakeRefPtr(); +} + +void TextFieldTestBase::RunMeasureAndLayout() +{ + frameNode_->SetRootMeasureNode(true); + frameNode_->UpdateLayoutPropertyFlag(); + frameNode_->SetSkipSyncGeometryNode(false); + frameNode_->Measure(frameNode_->GetLayoutConstraint()); + frameNode_->Layout(); + frameNode_->SetRootMeasureNode(false); +} + +void TextFieldTestBase::TearDownTestSuite() +{ + MockContainer::TearDown(); + MockPipelineBase::TearDown(); + MockParagraph::TearDown(); } void TextFieldTestBase::TearDown() { - ElementRegister::GetInstance()->Clear(); - auto* stack = ViewStackProcessor::GetInstance(); - while (!stack->elementsStack_.empty()) { - stack->elementsStack_.pop(); - } + pattern_ = nullptr; + frameNode_ = nullptr; } -RefPtr TextFieldTestBase::CreateTextFieldNode( - int32_t id, std::string text, std::string placeHolder, bool isTextArea, TextFiledModelUpdater&& modelUpdater) +void TextFieldTestBase::CreateTextFieldNode(const std::string& text, const std::string& placeHolder, bool isTextArea, + std::function&& modelUpdater) { auto* stack = ViewStackProcessor::GetInstance(); - stack->StartGetAccessRecordingFor(id); + stack->StartGetAccessRecordingFor(DEFAULT_NODE_ID); TextFieldModelNG textFieldModelNG; textFieldModelNG.CreateNode(placeHolder, text, isTextArea); if (modelUpdater) { modelUpdater(textFieldModelNG); } stack->StopGetAccessRecording(); - auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); - CHECK_NULL_RETURN(frameNode, nullptr); - stack->elementsStack_.pop(); - ElementRegister::GetInstance()->AddUINode(frameNode); - return frameNode; + frameNode_ = AceType::DynamicCast(stack->Finish()); + pattern_ = frameNode_->GetPattern(); + paragraph_ = MockParagraph::GetOrCreateMockParagraph(); + EXPECT_CALL(*paragraph_, PushStyle(_)).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, AddText(_)).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, PopStyle()).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, Build()).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, Layout(_)).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, GetHeight()).Times(AnyNumber()); + EXPECT_CALL(*paragraph_, GetLongestLine()).Times(AnyNumber()); + RunMeasureAndLayout(); } -void TextFieldTestBase::CreateOrUpdate( - int32_t id, std::string text, std::string placeHolder, bool /*isTextArea*/, TextFiledModelUpdater&& modelUpdater) +void TextFieldTestBase::GetFocus() { - frameNode_ = CreateTextFieldNode(1, text, placeHolder, false, std::move(modelUpdater)); - ASSERT_NE(frameNode_, nullptr); - pattern_ = frameNode_->GetPattern(); - ASSERT_NE(pattern_, nullptr); - pattern_->OnModifyDone(); - id_ = frameNode_->GetId(); + auto focushHub = pattern_->GetFocusHub(); + focushHub->currentFocus_ = true; + pattern_->HandleFocusEvent(); + RunMeasureAndLayout(); } -namespace CaretTest { class TextFieldCaretTest : public TextFieldTestBase {}; +class TextFieldControllerTest : public TextFieldTestBase {}; +class TextFieldKeyHandlerTest : public TextFieldTestBase {}; /** * @tc.name: CaretPosition001 @@ -171,28 +183,25 @@ class TextFieldCaretTest : public TextFieldTestBase {}; HWTEST_F(TextFieldCaretTest, CaretPosition001, TestSize.Level1) { /** - * @tc.steps: Check caret position when the text is unchanged. - * @tc.expected: Previous caret position is same as the current. + * @tc.steps: Create Text filed node with default text and placeholder */ - ASSERT_NE(pattern_, nullptr); - auto prevCaretPosition = pattern_->GetTextEditingValue().GetWideText().length() / 2; - pattern_->SetCaretPosition(prevCaretPosition); + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); - CreateOrUpdate(id_, text_, placeHolder_, false); - auto currentCaretPosition = pattern_->GetTextEditingValue().caretPosition; - EXPECT_EQ(prevCaretPosition, currentCaretPosition) << "caret position should not change when text unchanged"; + /** + * @tc.expected: Current caret position is end of text + */ + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), DEFAULT_TEXT.size()); /** - * @tc.steps: Check caret position when the text is changed. - * @tc.expected: Previous caret position is not same as the current. + * @tc.steps: Changed new text and remeasure and layout */ - auto newText = text_ + "_new"; - CreateOrUpdate(id_, newText, placeHolder_, false); - currentCaretPosition = pattern_->GetTextEditingValue().caretPosition; - EXPECT_NE(prevCaretPosition, currentCaretPosition) << "caret position should update when text changed"; - auto actualCaretPosition = StringUtils::ToWstring(newText).length(); - EXPECT_EQ(actualCaretPosition, currentCaretPosition) - << "caret position should be at the end of the text when text changed"; + pattern_->InsertValue("new"); + RunMeasureAndLayout(); + + /** + * @tc.expected: Current caret position is end of text + */ + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), DEFAULT_TEXT.size() + 3); } /** @@ -203,230 +212,270 @@ HWTEST_F(TextFieldCaretTest, CaretPosition001, TestSize.Level1) HWTEST_F(TextFieldCaretTest, CaretPosition002, TestSize.Level1) { /** - * @tc.steps: Check caret position after call SetType. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Create Text filed node with default text and placeholder and set input type */ - auto textLength = pattern_->GetTextEditingValue().GetWideText().length(); - auto caretPosition = pattern_->GetTextEditingValue().caretPosition; - EXPECT_EQ(textLength, caretPosition) << "default input type"; - std::string text = "openharmony@huawei.com+*0123456789"; std::vector> testItems; - testItems.emplace_back(TextInputType::TEXT, 34, "TextInputType::TEXT"); + testItems.emplace_back(TextInputType::TEXT, text.size(), "TextInputType::TEXT"); testItems.emplace_back(TextInputType::NUMBER, 10, "TextInputType::NUMBER"); testItems.emplace_back(TextInputType::PHONE, 12, "TextInputType::PHONE"); - testItems.emplace_back(TextInputType::EMAIL_ADDRESS, 32, "TextInputType::EMAIL_ADDRESS"); - testItems.emplace_back(TextInputType::VISIBLE_PASSWORD, 34, "TextInputType::VISIBLE_PASSWORD"); - for (auto testItem : testItems) { - CreateOrUpdate( - id_, text, placeHolder_, false, [type = testItem.item](TextFieldModelNG& model) { model.SetType(type); }); - auto errorMessage = "inputType is " + testItem.error + ", text is " + pattern_->GetEditingValue().text; - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, testItem.expected) << errorMessage; + testItems.emplace_back(TextInputType::EMAIL_ADDRESS, text.size() - 2, "TextInputType::EMAIL_ADDRESS"); + testItems.emplace_back(TextInputType::VISIBLE_PASSWORD, text.size() - 2, "TextInputType::VISIBLE_PASSWORD"); + + /** + * @tc.expected: Check if the text filter rules for the input box are compliant + */ + for (const auto& testItem : testItems) { + CreateTextFieldNode( + text, DEFAULT_PLACE_HOLDER, false, [testItem](TextFieldModelNG& model) { model.SetType(testItem.item); }); + auto errorMessage = "InputType is " + testItem.error + ", text is " + pattern_->GetTextValue(); + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), testItem.expected) << errorMessage; } } /** * @tc.name: CaretPosition003 - * @tc.desc: Test caret position on SetCaretPosition. + * @tc.desc: Test caret position on SetCaretPosition and SetMaxLength * @tc.type: FUNC */ HWTEST_F(TextFieldCaretTest, CaretPosition003, TestSize.Level1) { /** - * @tc.steps: Check caret position after call SetCaretPosition. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Create Text filed node with default text and placeholder + * @tc.expected: Cursor movement position matches the actual position */ - auto length = static_cast(pattern_->GetTextEditingValue().GetWideText().length()); - std::vector> testItems; - for (auto position = 0; position <= length; position++) { - testItems.emplace_back(position, position); - } - for (auto testItem : testItems) { - pattern_->SetCaretPosition(testItem.item); - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, testItem.expected); - } + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); + auto controller = pattern_->GetTextFieldController(); + controller->CaretPosition(static_cast(DEFAULT_TEXT.size() - 2)); + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), static_cast(DEFAULT_TEXT.size() - 2)); + + /** + * @tc.steps: Create Text filed node with default text and placeholder + * @tc.expected: Cursor movement position matches the actual position + */ + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, + [](TextFieldModelNG& model) { model.SetMaxLength(DEFAULT_TEXT.size() - 2); }); + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), DEFAULT_TEXT.size() - 2); } /** * @tc.name: CaretPosition004 - * @tc.desc: Test caret position on SetMaxLength. + * @tc.desc: Test caret position on SetInputFilter. * @tc.type: FUNC */ HWTEST_F(TextFieldCaretTest, CaretPosition004, TestSize.Level1) { /** - * @tc.steps: Check caret position after call SetMaxLength. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Initialize text and filter patterns + */ + std::string text = "abcdefghABCDEFG0123456789"; + std::vector> testItems; + testItems.emplace_back("", StringUtils::ToWstring(text).length()); + testItems.emplace_back("[0-9]", 10); + testItems.emplace_back("[A-Z]", 7); + testItems.emplace_back("[a-z]", 8); + + /** + * @tc.expected: Check if the text filter patterns for the input box are compliant */ - auto length = static_cast(pattern_->GetTextEditingValue().GetWideText().length()); - pattern_->SetCaretPosition(length / 2); - - std::vector> testItems; - testItems.emplace_back(length, length / 2, "caret position is less than max length"); - testItems.emplace_back(length / 2 - 1, length / 2 - 1, "caret position is greater than max length"); - for (auto testItem : testItems) { - CreateOrUpdate(id_, text_, placeHolder_, false, - [maxLength = testItem.item](TextFieldModelNG& model) { model.SetMaxLength(maxLength); }); - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, testItem.expected) << testItem.error; + for (const auto& testItem : testItems) { + CreateTextFieldNode(text, DEFAULT_PLACE_HOLDER, false, + [testItem](TextFieldModelNG& model) { model.SetInputFilter(testItem.item, nullptr); }); + auto errorMessage = "InputType is " + testItem.error + ", text is " + pattern_->GetTextValue(); + EXPECT_EQ(pattern_->GetTextSelectController()->GetCaretIndex(), testItem.expected) << errorMessage; } } /** * @tc.name: CaretPosition005 - * @tc.desc: Test caret position on SetInputFilter. + * @tc.desc: Test input string at the cursor position * @tc.type: FUNC */ HWTEST_F(TextFieldCaretTest, CaretPosition005, TestSize.Level1) { /** - * @tc.steps: Check caret position after call SetInputFilter. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Initialize text input and get select controller, update caret position and insert value */ - std::string text = "abcdefghABCDEFG0123456789"; - std::vector> testItems; + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); + auto controller = pattern_->GetTextSelectController(); + controller->UpdateCaretIndex(2); + pattern_->InsertValue("new"); + RunMeasureAndLayout(); - testItems.emplace_back("", StringUtils::ToWstring(text).length()); - testItems.emplace_back("[0-9]", 10); - testItems.emplace_back("[A-Z]", 7); - testItems.emplace_back("[a-z]", 8); - for (auto testItem : testItems) { - CreateOrUpdate(id_, text, placeHolder_, false, - [filter = testItem.item](TextFieldModelNG& model) { model.SetInputFilter(filter, nullptr); }); - auto errorMessage = "input filter is " + testItem.item + ", text is " + pattern_->GetEditingValue().text; - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, testItem.expected) << errorMessage; - } + /** + * @tc.expected: Check if the text and cursor position are correct + */ + EXPECT_EQ(pattern_->contentController_->GetTextValue(), "abnewcdefghijklmnopqrstuvwxyz"); + EXPECT_EQ(controller->GetCaretIndex(), 5); } /** * @tc.name: CaretPosition006 - * @tc.desc: Test caret position when focus changed. + * @tc.desc: Test stop edting input mode * @tc.type: FUNC */ HWTEST_F(TextFieldCaretTest, CaretPosition006, TestSize.Level1) { /** - * @tc.steps: Check caret position after call HandleFocusEvent or HandleBlurEvent. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Initialize text input node */ - pattern_->HandleFocusEvent(); - EXPECT_TRUE(pattern_->cursorVisible_) << "show cursor on focus"; - pattern_->HandleBlurEvent(); - EXPECT_FALSE(pattern_->cursorVisible_) << "hide cursor on blur"; + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); + + /** + * @tc.expected: The cursor is neither blinking nor visible when unfocused + */ + EXPECT_EQ(pattern_->caretStatus_, CaretStatus::NONE); + EXPECT_FALSE(pattern_->GetCursorVisible()); + + /** + * @tc.steps: Manually trigger focus and perform measure and layout again + * @tc.expected: Check if the cursor is twinking + */ + GetFocus(); + EXPECT_EQ(pattern_->caretStatus_, CaretStatus::SHOW); + EXPECT_TRUE(pattern_->GetCursorVisible()); + + /** + * @tc.steps: Get text filed controller and stop editing + */ + auto controller = pattern_->GetTextFieldController(); + controller->StopEditing(); + RunMeasureAndLayout(); + + /** + * @tc.expected: Check if the cursor stop twinking + */ + EXPECT_EQ(pattern_->caretStatus_, CaretStatus::HIDE); + EXPECT_FALSE(pattern_->GetCursorVisible()); } /** * @tc.name: CaretPosition007 - * @tc.desc: Test caret position with the clipboard. + * @tc.desc: Test the text selection mode of the text controller * @tc.type: FUNC */ HWTEST_F(TextFieldCaretTest, CaretPosition007, TestSize.Level1) { /** - * @tc.steps: Check caret position after call HandleOnCut,HandleOnPaste,HandleOnSelectAll. - * @tc.expected: caret position is same as the expected. + * @tc.steps: Initialize text input node and get focus + */ + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); + GetFocus(); + + EXPECT_CALL(*paragraph_, GetRectsForRange(_, _, _)).Times(1); + auto controller = pattern_->GetTextFieldController(); + controller->SetTextSelection(3, 5); + RunMeasureAndLayout(); + + /** + * @tc.expected: Check if the cursor stop twinking and + * get select first and second handle info index + */ + auto selectController = pattern_->GetTextSelectController(); + EXPECT_EQ(selectController->GetStartIndex(), 3); + EXPECT_EQ(selectController->GetEndIndex(), 5); +} + +/** + * @tc.name: ContentController001 + * @tc.desc: Test ContentController in different input type + * @tc.type: FUNC + */ +HWTEST_F(TextFieldControllerTest, ContentController001, TestSize.Level1) +{ + /** + * @tc.steps: Initialize insert text and expected values + */ + std::vector insertValues = { + "openharmony123_ *+%$", + "openharmony123456*+&@huawei.com", + "openharmony#15612932075*.com", + "open_harmony@@huawei.com*+$helloworld", + "open_harmony123 password*+#", + }; + std::vector> testItems; + testItems.emplace_back(TextInputType::TEXT, "openharmony123_ *+%$", "TextInputType::TEXT"); + testItems.emplace_back(TextInputType::NUMBER, "123456", "TextInputType::NUMBER"); + testItems.emplace_back(TextInputType::PHONE, "#15612932075*", "TextInputType::PHONE"); + testItems.emplace_back( + TextInputType::EMAIL_ADDRESS, "open_harmony@huawei.comhelloworld", "TextInputType::EMAIL_ADDRESS"); + testItems.emplace_back( + TextInputType::VISIBLE_PASSWORD, "openharmony123 password*+#", "TextInputType::VISIBLE_PASSWORD"); + + /** + * @tc.expected: Check if text filtering meets expectations */ - CreateOrUpdate( - id_, text_, placeHolder_, false, [](TextFieldModelNG& model) { model.SetCopyOption(CopyOptions::InApp); }); - auto len = pattern_->GetEditingValue().GetWideText().length(); - auto selectStart = len / 2; - auto selectEnd = len; - pattern_->UpdateSelection(selectStart, selectEnd); - pattern_->SetInSelectMode(SelectionMode::SELECT); - pattern_->HandleOnCut(); - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, selectStart) - << "caret position should equals with first handle position"; - - len = pattern_->GetEditingValue().GetWideText().length(); - pattern_->SetInSelectMode(SelectionMode::SELECT); - pattern_->UpdateSelection(0, len / 2); - pattern_->HandleOnCopy(); - EXPECT_TRUE(pattern_->cursorVisible_) << "show cursor when call HandleOnCopy"; - pattern_->SetCaretPosition(len); - pattern_->HandleOnPaste(); - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, len + len / 2) - << ("caret position equals with [last position] + [copy data length]"); - - len = pattern_->GetEditingValue().GetWideText().length(); - pattern_->HandleOnSelectAll(false); - EXPECT_EQ(pattern_->GetEditingValue().caretPosition, len) << ("caret position equals with text length"); + int index = 0; + for (const auto& testItem : testItems) { + CreateTextFieldNode( + "", DEFAULT_PLACE_HOLDER, false, [testItem](TextFieldModelNG& model) { model.SetType(testItem.item); }); + auto controller = pattern_->contentController_; + controller->InsertValue(0, insertValues[index]); + index++; + auto errorMessage = "InputType is " + testItem.error + ", text is " + pattern_->GetTextValue(); + EXPECT_EQ(controller->GetTextValue().compare(testItem.expected), 0) << errorMessage; + } } /** - * @tc.name: CaretPosition008 - * @tc.desc: Test caret position with the keyboard event. + * @tc.name: ContentController002 + * @tc.desc: Test ContentController in different input filter * @tc.type: FUNC */ -HWTEST_F(TextFieldCaretTest, CaretPosition008, TestSize.Level1) +HWTEST_F(TextFieldControllerTest, ContentController002, TestSize.Level1) { /** - * @tc.steps: text is abcedefghijkl*mnopqrstuvwxyz, * is caret position. - * 1. abcedefghijkl*nopqrstuvwxyz -- delete forward - * 2. abcedefghijk*nopqrstuvwxyz -- delete backward - * 3. abcedefghijk@*nopqrstuvwxyz -- insert 8 - * 4. abcedefghijk@*stuvwxyz -- select right 5(nopqr) and cut - * 5. abcedefghijk@nopqr*stuvwxyz -- paste 5(nopqr) - * 6. abcedefghijk@*stuvwxyz -- undo step 5 - * 7. abcedefghijk@nopqr*stuvwxyz -- redo step 6 - * 8. abcedefghijk@nopqrstuvwxyz* -- select all - * @tc.expected: caret position is same as the expected. + * @tc.steps: Initialize text and filter patterns + */ + std::string text = "CabcdefgABhCDEFG0123a456A789"; + std::vector> testItems; + testItems.emplace_back("", "CabcdefgABhCDEFG0123a456A789", "None"); + testItems.emplace_back("[0-9]", "0123456789", "Input filter [0-9]"); + testItems.emplace_back("[A-Z]", "CABCDEFGA", "Input filter [A-Z]"); + testItems.emplace_back("[a-z]", "abcdefgha", "Input filter [a-z]"); + + /** + * @tc.expected: Check if the text filter patterns for the input box are compliant */ - auto length = static_cast(pattern_->GetTextEditingValue().GetWideText().length()); - pattern_->SetCaretPosition(length / 2); - pattern_->imeAttached_ = true; - KeyEvent event; - event.code = KeyCode::KEY_FORWARD_DEL; - event.action = KeyAction::DOWN; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2) << "delete forward"; - - event.code = KeyCode::KEY_DEL; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2 - 1) << "delete backward"; - - event.code = KeyCode::KEY_2; - event.pressedCodes = { KeyCode::KEY_SHIFT_LEFT, KeyCode::KEY_2 }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2) << "insert one"; - - event.code = KeyCode::KEY_DPAD_RIGHT; - event.pressedCodes = { KeyCode::KEY_SHIFT_LEFT, KeyCode::KEY_DPAD_RIGHT }; - pattern_->UpdateSelection(length / 2); - auto selectCount = 5; - for (auto i = 0; i < selectCount; i++) { - pattern_->OnKeyEvent(event); + for (const auto& testItem : testItems) { + CreateTextFieldNode("", DEFAULT_PLACE_HOLDER, false, + [testItem](TextFieldModelNG& model) { model.SetInputFilter(testItem.item, nullptr); }); + auto controller = pattern_->contentController_; + controller->InsertValue(0, text); + auto errorMessage = testItem.error + ", text is " + pattern_->GetTextValue(); + EXPECT_EQ(controller->GetTextValue().compare(testItem.expected), 0) << errorMessage; } - event.code = KeyCode::KEY_X; - event.pressedCodes = { KeyCode::KEY_CTRL_LEFT, KeyCode::KEY_X }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2) - << ("cut " + std::to_string(selectCount) + " characters"); - - event.code = KeyCode::KEY_V; - event.pressedCodes = { KeyCode::KEY_CTRL_LEFT, KeyCode::KEY_V }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2 + selectCount) - << ("paste " + std::to_string(selectCount) + " characters"); - - event.code = KeyCode::KEY_Z; - event.pressedCodes = { KeyCode::KEY_CTRL_LEFT, KeyCode::KEY_Z }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2) - << ("undo, the caret position is at last position"); - - event.code = KeyCode::KEY_Y; - event.pressedCodes = { KeyCode::KEY_CTRL_LEFT, KeyCode::KEY_Y }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length / 2 + selectCount) - << ("redo, the caret position equals with step 5"); - - length = static_cast(pattern_->GetTextEditingValue().GetWideText().length()); - event.code = KeyCode::KEY_A; - event.pressedCodes = { KeyCode::KEY_CTRL_LEFT, KeyCode::KEY_A }; - pattern_->OnKeyEvent(event); - EXPECT_EQ(pattern_->GetTextEditingValue().caretPosition, length) - << ("select all, caret position is at the end of text"); - - pattern_->imeAttached_ = false; } -} // namespace CaretTest -}; // namespace OHOS::Ace::NG + +/** + * @tc.name: ContentController003 + * @tc.desc: Test ContentController in different input filter + * @tc.type: FUNC + */ +HWTEST_F(TextFieldControllerTest, ContentController003, TestSize.Level1) +{ + /** + * @tc.steps: Initialize text and filter patterns + */ + CreateTextFieldNode(DEFAULT_TEXT, DEFAULT_PLACE_HOLDER, false, nullptr); + auto controller = pattern_->contentController_; + + /** + * @tc.expected: Check if text is selected based on corresponding left and right coordinates + */ + auto selectedValue = controller->GetSelectedValue(1, 4); + EXPECT_EQ(selectedValue.compare("bcd"), 0) << "Text is " + selectedValue; + + /** + * @tc.expected: Check if text is selected based on preceding coordinates + */ + auto beforeSelectedValue = controller->GetValueBeforeIndex(3); + EXPECT_EQ(beforeSelectedValue.compare("abc"), 0) << "Text is " + beforeSelectedValue; + + /** + * @tc.expected: Check if text is selected based on trailing coordinates + */ + auto afterSelectedValue = controller->GetValueAfterIndex(3); + EXPECT_EQ(afterSelectedValue.compare("defghijklmnopqrstuvwxyz"), 0) << "Text is " + afterSelectedValue; +} +} // namespace OHOS::Ace::NG diff --git a/test/unittest/core/pattern/video/BUILD.gn b/test/unittest/core/pattern/video/BUILD.gn index b6402e43d66..69c4cbf3ea8 100644 --- a/test/unittest/core/pattern/video/BUILD.gn +++ b/test/unittest/core/pattern/video/BUILD.gn @@ -18,7 +18,6 @@ ace_unittest("video_test_ng") { sources = [ "$ace_root/frameworks/core/components_ng/test/mock/render/mock_media_player_creator.cpp", "$ace_root/frameworks/core/components_ng/test/mock/render/mock_path_painter.cpp", - "$ace_root/test/mock/core/common/mock_font_manager_ng.cpp", "video_test_ng.cpp", ] } diff --git a/test/unittest/core/pipeline/BUILD.gn b/test/unittest/core/pipeline/BUILD.gn index b7b92bb048c..9cd608fc69e 100644 --- a/test/unittest/core/pipeline/BUILD.gn +++ b/test/unittest/core/pipeline/BUILD.gn @@ -130,6 +130,7 @@ ohos_unittest("pipeline_context_test_ng") { "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_builder.cpp", "$ace_root/frameworks/core/components_ng/layout/layout_wrapper_node.cpp", "$ace_root/frameworks/core/components_ng/manager/safe_area/safe_area_manager.cpp", + "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp", "$ace_root/frameworks/core/components_ng/manager/select_overlay/select_overlay_proxy.cpp", "$ace_root/frameworks/core/components_ng/pattern/app_bar/app_bar_view.cpp", -- Gitee From 22efcee7d3d9584e71b6514ea6f6ab0e9324742d Mon Sep 17 00:00:00 2001 From: lijuan Date: Wed, 18 Oct 2023 12:59:46 +0000 Subject: [PATCH 05/31] =?UTF-8?q?textfield=E4=BC=98=E5=8C=96:layoutalgorit?= =?UTF-8?q?hm=E4=BC=98=E5=8C=96=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=85=89?= =?UTF-8?q?=E6=A0=87=E5=AE=BD=E5=BA=A6=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: Icf55bc04e570c3d1a5c64481bfdaf791a3de1df9 --- .gitee/CODEOWNERS | 18 +- .../text_area/text_area_layout_algorithm.cpp | 155 ++++++------------ .../text_area/text_area_layout_algorithm.h | 2 + .../text_field_layout_algorithm.cpp | 115 ++++++++----- .../text_field/text_field_layout_algorithm.h | 23 ++- .../text_field_overlay_modifier.cpp | 3 +- .../pattern/text_field/text_field_pattern.cpp | 46 ++---- .../pattern/text_field/text_field_pattern.h | 11 +- .../text_field/text_input_response_area.cpp | 13 +- .../text_field/text_select_controller.cpp | 43 ++++- .../text_field/text_select_controller.h | 1 + .../text_input_layout_algorithm.cpp | 75 ++++----- 12 files changed, 252 insertions(+), 253 deletions(-) diff --git a/.gitee/CODEOWNERS b/.gitee/CODEOWNERS index 60cf27c0494..37ec4adbf63 100644 --- a/.gitee/CODEOWNERS +++ b/.gitee/CODEOWNERS @@ -113,11 +113,11 @@ frameworks/core/components_ng/pattern/swiper/ @xuzhidan frameworks/core/components_ng/pattern/swiper_indicator/ @xuzhidan frameworks/core/components_ng/pattern/tabs/ @xuzhidan frameworks/core/components_ng/pattern/text/ @lijuan124 -frameworks/core/components_ng/pattern/text_clock/ @lijuan124 +frameworks/core/components_ng/pattern/text_clock/ @aryawang frameworks/core/components_ng/pattern/text_drag/ @zhaojian2021 -frameworks/core/components_ng/pattern/text_field/ @xiexiyun +frameworks/core/components_ng/pattern/text_field/ @jyj-0306 @lijuan124 frameworks/core/components_ng/pattern/text_picker/ @cheng-feiwang -frameworks/core/components_ng/pattern/texttimer/ @lijuan124 +frameworks/core/components_ng/pattern/texttimer/ @aryawang frameworks/core/components_ng/pattern/time_picker/ @cheng-feiwang frameworks/core/components_ng/pattern/toast/ @cheng-feiwang frameworks/core/components_ng/pattern/toggle/ @luoying_ace_admin @@ -219,11 +219,11 @@ frameworks/core/components/svg/ @zhoutianer frameworks/core/components/swiper/ @xuzhidan frameworks/core/components/tab_bar/ @xuzhidan frameworks/core/components/text/ @lijuan124 -frameworks/core/components/text_clock/ @lijuan124 -frameworks/core/components/text_field/ @xiexiyun +frameworks/core/components/text_clock/ @aryawang +frameworks/core/components/text_field/ @jyj-0306 @lijuan124 frameworks/core/components/text_overlay/ @yangfan229 frameworks/core/components/text_span/ @lijuan124 -frameworks/core/components/texttimer/ @lijuan124 +frameworks/core/components/texttimer/ @aryawang frameworks/core/components/theme/ @yan-shuifeng frameworks/core/components/tip/ @ frameworks/core/components/toast/ @ @@ -390,11 +390,11 @@ frameworks/core/components_ng/test/pattern/swiper/ @xuzhidan frameworks/core/components_ng/test/pattern/swiper_indicator/ @xuzhidan frameworks/core/components_ng/test/pattern/tabs/ @xuzhidan frameworks/core/components_ng/test/pattern/text/ @lijuan124 -frameworks/core/components_ng/test/pattern/text_clock/ @lijuan124 +frameworks/core/components_ng/test/pattern/text_clock/ @aryawang frameworks/core/components_ng/test/pattern/text_drag/ @zhaojian2021 -frameworks/core/components_ng/test/pattern/text_field/ @xiexiyun +frameworks/core/components_ng/test/pattern/text_field/ @jyj-0306 @lijuan124 frameworks/core/components_ng/test/pattern/text_picker/ @cheng-feiwang -frameworks/core/components_ng/test/pattern/texttimer/ @lijuan124 +frameworks/core/components_ng/test/pattern/texttimer/ @aryawang frameworks/core/components_ng/test/pattern/time_picker/ @cheng-feiwang frameworks/core/components_ng/test/pattern/toast/ @ frameworks/core/components_ng/test/pattern/toggle/ @luoying_ace_admin diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp index 64cc0ad1c8d..399402a3410 100644 --- a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp @@ -40,58 +40,60 @@ std::optional TextAreaLayoutAlgorithm::MeasureContent( // Construct text style. TextStyle textStyle; - std::string textContent; - bool showPlaceHolder = false; - ConstructTextStyles(frameNode, textStyle, textContent, showPlaceHolder); + ConstructTextStyles(frameNode, textStyle, textContent_, showPlaceHolder_); auto isInlineStyle = pattern->IsNormalInlineState(); // Create paragraph. - if (pattern->IsDragging() && !showPlaceHolder) { - CreateParagraph(textStyle, pattern->GetDragContents(), textContent, false); + if (pattern->IsDragging() && !showPlaceHolder_) { + CreateParagraph(textStyle, pattern->GetDragContents(), textContent_, false); } else { - CreateParagraph(textStyle, textContent, false, pattern->GetNakedCharPosition()); + CreateParagraph(textStyle, textContent_, false, pattern->GetNakedCharPosition()); } - // constraint size. - auto contentIdealSize = CalculateConstraintSize(contentConstraint, layoutWrapper); + // Used for empty text. + preferredHeight_ = pattern->PreferredLineHeight(); + + // Paragraph layout.} + if (isInlineStyle) { + return InlineMeasureContent(contentConstraint, layoutWrapper); + } else if (showPlaceHolder_) { + return PlaceHolderMeasureContent(contentConstraint, layoutWrapper); + } else { + return TextAreaMeasureContent(contentConstraint, layoutWrapper); + } +} - // CounterNode measureContent. +float TextAreaLayoutAlgorithm::CounterNodeMeasure(float contentWidth, LayoutWrapper* layoutWrapper) +{ + auto frameNode = layoutWrapper->GetHostNode(); + CHECK_NULL_RETURN(frameNode, 0.0f); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_RETURN(pattern, 0.0f); + auto textFieldLayoutProperty = pattern->GetLayoutProperty(); + CHECK_NULL_RETURN(textFieldLayoutProperty, 0.0f); + auto isInlineStyle = pattern->IsNormalInlineState(); if (textFieldLayoutProperty->GetShowCounterValue(false) && textFieldLayoutProperty->HasMaxLength() && !isInlineStyle) { auto counterNodeLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(0); if (counterNodeLayoutWrapper) { - auto textLength = static_cast(showPlaceHolder ? 0 : StringUtils::ToWstring(textContent).length()); + auto textLength = + static_cast(showPlaceHolder_ ? 0 : StringUtils::ToWstring(textContent_).length()); auto maxLength = static_cast(textFieldLayoutProperty->GetMaxLength().value()); LayoutConstraintF textContentConstraint; - textContentConstraint.UpdateIllegalSelfIdealSizeWithCheck( - OptionalSizeF(contentIdealSize.Width(), std::nullopt)); + textContentConstraint.UpdateIllegalSelfIdealSizeWithCheck(OptionalSizeF(contentWidth, std::nullopt)); CounterNodeMeasureContent(textLength, maxLength, textContentConstraint, counterNodeLayoutWrapper); - auto height = counterNodeLayoutWrapper->GetGeometryNode()->GetFrameSize().Height(); - contentIdealSize.SetHeight(std::max(contentIdealSize.Height() - height, 0.0f)); + return counterNodeLayoutWrapper->GetGeometryNode()->GetFrameSize().Height(); } } - - // Used for empty text. - preferredHeight_ = pattern->PreferredLineHeight(); - - // Paragraph layout.} - if (isInlineStyle) { - return InlineMeasureContent(contentConstraint, layoutWrapper, contentIdealSize); - } else if (showPlaceHolder) { - return PlaceHolderMeasureContent(contentIdealSize); - } else { - return TextAreaMeasureContent(contentIdealSize); - } + return 0.0f; } void TextAreaLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) { const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint(); - OptionalSizeF frameSize = - CreateIdealSize(layoutConstraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT_MAIN_AXIS); + OptionalSizeF frameSize; const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); - const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); auto frameNode = layoutWrapper->GetHostNode(); CHECK_NULL_VOID(frameNode); auto pattern = frameNode->GetPattern(); @@ -103,7 +105,6 @@ void TextAreaLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) contentWidth = contentSize.Width(); contentHeight = contentSize.Height(); } - // Add children height; auto counterNodeLayoutWrapper = layoutWrapper->GetOrCreateChildByIndex(0); if (counterNodeLayoutWrapper) { @@ -112,62 +113,28 @@ void TextAreaLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) } if (pattern->IsNormalInlineState() && pattern->IsFocus()) { - frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum() + PARAGRAPH_SAVE_BOUNDARY); - frameSize.SetHeight(contentHeight + pattern->GetVerticalPaddingSum() + PARAGRAPH_SAVE_BOUNDARY); + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum() + PARAGRAPH_SAVE_BOUNDARY); + frameSize.SetHeight(contentHeight + pattern->GetVerticalPaddingAndBorderSum() + PARAGRAPH_SAVE_BOUNDARY); } else { + // The width after MeasureContent is already optimal, but the height needs to be constrained in Measure. + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum()); auto textFieldLayoutProperty = pattern->GetLayoutProperty(); CHECK_NULL_VOID(textFieldLayoutProperty); - if (!frameSize.Width().has_value()) { - // If width is not set, select the maximum value of minWidth and maxWidth to layoutConstraint - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Width().has_value()) { - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Width(), contentWidth + pattern->GetHorizontalPaddingSum())); - } else if (!calcLayoutConstraint) { - // If calcLayoutConstraint has not set, use the LayoutConstraint initial value - frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingSum()); - } else { - // If maxWidth is not set and calcLayoutConstraint is set, set minWidth to layoutConstraint - frameSize.SetWidth(layoutConstraint->minSize.Width()); - } - } - if (!frameSize.Height().has_value()) { - // Like width - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Height().has_value()) { - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { - // calcLayoutConstraint initialized once when setting width, set minHeight=0, - // so add "minHeight=0" to the constraint. - frameSize.SetHeight( - std::min(layoutConstraint->maxSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } else { - frameSize.SetHeight( - std::max(layoutConstraint->minSize.Height(), contentHeight + pattern->GetVerticalPaddingSum())); - } - } - - if (textFieldLayoutProperty->GetWidthAutoValue(false)) { - frameSize.SetWidth(std::min(contentWidth, textRect_.Width()) + pattern->GetHorizontalPaddingSum()); + auto contentConstraint = layoutWrapper->GetLayoutProperty()->CreateContentConstraint(); + if (contentConstraint.selfIdealSize.Height().has_value()) { + frameSize.SetHeight(contentConstraint.maxSize.Height() + pattern->GetVerticalPaddingAndBorderSum()); + } else { + frameSize.SetHeight(contentHeight + pattern->GetVerticalPaddingAndBorderSum()); } - - // Here's what happens when the height or width is set at list one + // Height is constrained by the CalcLayoutConstraint. if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); } else { auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - frameSize.SetWidth(finalSize.Width()); frameSize.SetHeight(finalSize.Height()); } - if (layoutConstraint->maxSize.Height() < layoutConstraint->minSize.Height()) { - frameSize.SetHeight(layoutConstraint->minSize.Height()); - } - if (layoutConstraint->maxSize.Width() < layoutConstraint->minSize.Width()) { - frameSize.SetWidth(layoutConstraint->minSize.Width()); - } } layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); } @@ -199,53 +166,37 @@ void TextAreaLayoutAlgorithm::CounterNodeMeasureContent(uint32_t textLength, uin void TextAreaLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) { // update child position. - auto size = layoutWrapper->GetGeometryNode()->GetFrameSize(); auto frameNode = layoutWrapper->GetHostNode(); CHECK_NULL_VOID(frameNode); auto pattern = frameNode->GetPattern(); CHECK_NULL_VOID(pattern); + auto size = layoutWrapper->GetGeometryNode()->GetFrameSize() - + SizeF(pattern->GetHorizontalPaddingAndBorderSum(), pattern->GetVerticalPaddingAndBorderSum()); const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); CHECK_NULL_VOID(content); - auto contentSize = content->GetRect().GetSize(); auto layoutProperty = DynamicCast(layoutWrapper->GetLayoutProperty()); CHECK_NULL_VOID(layoutProperty); auto context = layoutWrapper->GetHostNode()->GetContext(); CHECK_NULL_VOID(context); parentGlobalOffset_ = layoutWrapper->GetHostNode()->GetPaintRectOffset() - context->GetRootRect().GetOffset(); - auto align = Alignment::CENTER; - bool hasAlign = false; + auto align = Alignment::TOP_CENTER; + + auto offsetBase = OffsetF( + pattern->GetPaddingLeft() + pattern->GetBorderLeft(), pattern->GetPaddingTop() + pattern->GetBorderTop()); if (layoutWrapper->GetLayoutProperty()->GetPositionProperty()) { align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align); - hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value(); } - // Update content position. - OffsetF contentOffset = Alignment::GetAlignPosition(size, contentSize, align); - auto isInlineStyle = pattern->IsNormalInlineState(); - if (hasAlign) { - if (isInlineStyle) { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX(), contentOffset.GetY())); - } else { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), - contentOffset.GetY() + pattern->GetBorderTop())); - } - + // Update text position. + if (LessOrEqual(textRect_.Height(), content->GetRect().Height())) { OffsetF textRectOffSet = Alignment::GetAlignPosition(size, textRect_.GetSize(), align); - if (LessOrEqual(textRect_.Height(), content->GetRect().Height())) { - textRect_.SetOffset(OffsetF(pattern->GetTextRect().GetOffset().GetX(), textRectOffSet.GetY())); - } else { - textRect_.SetOffset(pattern->GetTextRect().GetOffset()); - } + textRect_.SetOffset(OffsetF(0.0f, textRectOffSet.GetY()) + offsetBase); + content->SetOffset(OffsetF(0.0f, textRectOffSet.GetY()) + offsetBase); } else { - if (isInlineStyle) { - content->SetOffset(pattern->GetUtilPadding().Offset()); - } else { - content->SetOffset(OffsetF(pattern->GetUtilPadding().Offset().GetX() + pattern->GetBorderLeft(), - pattern->GetUtilPadding().Offset().GetY() + pattern->GetBorderTop())); - } textRect_.SetOffset(pattern->GetTextRect().GetOffset()); + content->SetOffset(offsetBase); } - // CounterNode Layout. + auto isInlineStyle = pattern->IsNormalInlineState(); if (layoutProperty->GetShowCounterValue(false) && layoutProperty->HasMaxLength() && !isInlineStyle) { CounterLayout(layoutWrapper); } diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h index 24994d96f45..aa7164ee9d3 100644 --- a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.h @@ -30,6 +30,8 @@ public: const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) override; void Layout(LayoutWrapper* layoutWrapper) override; + float CounterNodeMeasure(float contentWidth, LayoutWrapper* layoutWrapper) override; + private: void CounterNodeMeasureContent(uint32_t textLength, uint32_t maxLength, const LayoutConstraintF& contentConstraint, RefPtr& layoutWrapper); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp index 601ba2aa8db..48d18c77290 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp @@ -75,28 +75,8 @@ void TextFieldLayoutAlgorithm::ConstructTextStyles( } } -SizeF TextFieldLayoutAlgorithm::CalculateConstraintSize( - const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) -{ - // constraint size. - auto idealWidth = contentConstraint.selfIdealSize.Width().value_or(contentConstraint.maxSize.Width()); - auto idealHeight = contentConstraint.selfIdealSize.Height().value_or(contentConstraint.maxSize.Height()); - auto idealSize = SizeF { idealWidth, idealHeight }; - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { - idealSize.UpdateSizeWhenSmaller(contentConstraint.maxSize); - } else { - auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(static_cast>(idealSize), - layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), - layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - idealSize.UpdateSizeWhenSmaller(finalSize.ConvertToSizeT()); - } - idealWidth = idealSize.Width(); - idealHeight = idealSize.Height(); - return SizeF { idealWidth, idealHeight }; -} - std::optional TextFieldLayoutAlgorithm::InlineMeasureContent( - const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, const SizeF& idealSize) + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) { auto frameNode = layoutWrapper->GetHostNode(); CHECK_NULL_RETURN(frameNode, std::nullopt); @@ -109,56 +89,105 @@ std::optional TextFieldLayoutAlgorithm::InlineMeasureContent( auto pattern = frameNode->GetPattern(); CHECK_NULL_RETURN(pattern, std::nullopt); + float contentWidth = 0.0f; if (pattern->IsFocus()) { auto safeBoundary = textFieldTheme->GetInlineBorderWidth().ConvertToPx() * 2; - paragraph_->Layout(idealSize.Width() - safeBoundary - PARAGRAPH_SAVE_BOUNDARY); + paragraph_->Layout( + contentConstraint.maxSize.Width() - static_cast(safeBoundary) - PARAGRAPH_SAVE_BOUNDARY); paragraph_->Layout(std::ceil(paragraph_->GetLongestLine())); + contentWidth = ConstraintWithMinWidth( + contentConstraint, layoutWrapper, static_cast(safeBoundary) + PARAGRAPH_SAVE_BOUNDARY); } else { - paragraph_->Layout(idealSize.Width()); + paragraph_->Layout(contentConstraint.maxSize.Width()); + contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper); } - textRect_.SetSize(SizeF(paragraph_->GetLongestLine(), paragraph_->GetHeight())); - pattern->SetSingleLineHeight(paragraph_->GetHeight() / paragraph_->GetLineCount()); - auto inlineIdealHieght = idealSize.Height(); - if (pattern->IsFocus()) { + textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); + + auto inlineIdealHieght = contentConstraint.maxSize.Height(); + if (pattern->IsFocus() && paragraph_->GetLineCount() != 0) { + pattern->SetSingleLineHeight(paragraph_->GetHeight() / paragraph_->GetLineCount()); // The maximum height of the inline mode defaults to a maximum of three rows. inlineIdealHieght = pattern->GetSingleLineHeight() * textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE); } - return SizeF( - paragraph_->GetMaxWidth(), std::min(inlineIdealHieght, std::max(preferredHeight_, paragraph_->GetHeight()))); + return SizeF(contentWidth, std::min(inlineIdealHieght, std::max(preferredHeight_, paragraph_->GetHeight()))); } -SizeF TextFieldLayoutAlgorithm::PlaceHolderMeasureContent(const SizeF& idealSize, float imageWidth) +float TextFieldLayoutAlgorithm::ConstraintWithMinWidth( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float removeValue) { - paragraph_->Layout(idealSize.Width() - imageWidth); - textRect_.SetSize(SizeF(paragraph_->GetLongestLine(), paragraph_->GetHeight())); + const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); + if (calcLayoutConstraint && calcLayoutConstraint->minSize.has_value() && + calcLayoutConstraint->minSize->Width().has_value()) { + auto width = std::max(contentConstraint.minSize.Width() - removeValue, paragraph_->GetLongestLine()); + if (width != paragraph_->GetLongestLine()) { + paragraph_->Layout(width); + } else { + return paragraph_->GetLongestLine(); + } + } + return paragraph_->GetMaxWidth(); +} - auto contentWidth = idealSize.Width() - imageWidth; +SizeF TextFieldLayoutAlgorithm::PlaceHolderMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float imageWidth) +{ + paragraph_->Layout(contentConstraint.maxSize.Width() - imageWidth); + + // Adapts to auto width. if (autoWidth_) { - contentWidth = std::min(contentWidth, paragraph_->GetLongestLine()); + paragraph_->Layout(std::max(0.0f, std::ceil(paragraph_->GetLongestLine()))); } - return SizeF(contentWidth, std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); + + auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, imageWidth); + auto counterNodeHeight = CounterNodeMeasure(contentWidth, layoutWrapper); + + auto contentHeight = std::min( + contentConstraint.maxSize.Height() - counterNodeHeight, std::max(preferredHeight_, paragraph_->GetHeight())); + + textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); + + return SizeF(contentWidth, contentHeight); } -SizeF TextFieldLayoutAlgorithm::TextAreaMeasureContent(const SizeF& idealSize) +SizeF TextFieldLayoutAlgorithm::TextAreaMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper) { - paragraph_->Layout(idealSize.Width()); - textRect_.SetSize(SizeF(idealSize.Width(), paragraph_->GetHeight())); - return SizeF(idealSize.Width(), std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); + paragraph_->Layout(contentConstraint.maxSize.Width()); + + auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper); + auto counterNodeHeight = CounterNodeMeasure(contentWidth, layoutWrapper); + + auto contentHeight = std::min( + contentConstraint.maxSize.Height() - counterNodeHeight, std::max(preferredHeight_, paragraph_->GetHeight())); + + textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); + return SizeF(contentWidth, contentHeight); } -SizeF TextFieldLayoutAlgorithm::TextInputMeasureConetnt(const SizeF& idealSize, float imageWidth) +SizeF TextFieldLayoutAlgorithm::TextInputMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float imageWidth) { paragraph_->Layout(std::numeric_limits::infinity()); paragraph_->Layout(std::ceil(paragraph_->GetLongestLine())); - textRect_.SetSize(SizeF(static_cast(paragraph_->GetLongestLine()), paragraph_->GetHeight())); - auto contentWidth = idealSize.Width() - imageWidth; + + auto contentWidth = contentConstraint.maxSize.Width() - imageWidth; if (autoWidth_) { contentWidth = std::min(contentWidth, paragraph_->GetLongestLine()); } - return SizeF(contentWidth, std::min(idealSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight()))); + const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); + if (calcLayoutConstraint && calcLayoutConstraint->minSize.has_value() && + calcLayoutConstraint->minSize->Width().has_value()) { + contentWidth = std::min(contentConstraint.maxSize.Width() - imageWidth, + std::max(paragraph_->GetLongestLine(), contentConstraint.minSize.Width() - imageWidth)); + } + auto contenHeight = + std::min(contentConstraint.maxSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight())); + + textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); + return SizeF(contentWidth, contenHeight); } void TextFieldLayoutAlgorithm::ErrorTextMeasureContent(const std::string& content, const RefPtr& theme) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h index ca1c26c284f..e7d41b2ea1a 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h @@ -69,6 +69,11 @@ public: const RefPtr& layoutProperty, const RefPtr& theme, TextStyle& textStyle, bool isDisabled); + virtual float CounterNodeMeasure(float contentWidth, LayoutWrapper* layoutWrapper) + { + return 0.0f; + } + protected: static void FontRegisterCallback(const RefPtr& frameNode, const std::vector& fontFamilies); void CreateParagraph(const TextStyle& textStyle, std::string content, bool needObscureText, @@ -93,18 +98,22 @@ protected: int32_t ConvertTouchOffsetToCaretPosition(const Offset& localOffset); void UpdateUnitLayout(LayoutWrapper* layoutWrapper); ParagraphStyle GetParagraphStyle(const TextStyle& textStyle, const std::string& content) const; - - SizeF CalculateConstraintSize(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); - std::optional InlineMeasureContent( - const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, const SizeF& idealSize); - SizeF PlaceHolderMeasureContent(const SizeF& idealSize, float imageWidth = 0.0f); - SizeF TextInputMeasureConetnt(const SizeF& idealSize, float imageWidth); - SizeF TextAreaMeasureContent(const SizeF& idealSize); + float ConstraintWithMinWidth( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float removeValue = 0.0f); + SizeF GetConstraintSize(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); + std::optional InlineMeasureContent(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); + SizeF PlaceHolderMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float imageWidth = 0.0f); + SizeF TextInputMeasureContent( + const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float imageWidth); + SizeF TextAreaMeasureContent(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); RefPtr paragraph_; RefPtr errorParagraph_; RectF textRect_; OffsetF parentGlobalOffset_; + std::string textContent_; + bool showPlaceHolder_ = false; float preferredHeight_ = 0.0f; float unitWidth_ = 0.0f; diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp index 336175c5575..d9f7bff64a0 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp @@ -170,7 +170,8 @@ void TextFieldOverlayModifier::PaintCursor(DrawingContext& context) const clipRectHeight = paintOffset.GetY() + contentSize_->Get().Height(); RSRect clipInnerRect(paintOffset.GetX(), paintOffset.GetY(), // add extra clip space for cases such as auto width - paintOffset.GetX() + contentSize_->Get().Width() + cursorWidth_->Get() * 2.0f, + paintOffset.GetX() + contentSize_->Get().Width() + + (LessOrEqual(contentSize_->Get().Width(), 0.0) ? cursorWidth_->Get() : 0.0f), clipRectHeight); auto layoutProperty = textFieldPattern->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 59dbfbbe8bb..9a869bfe06b 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -333,8 +333,6 @@ void TextFieldPattern::UpdateCaretRect() } selectController_->UpdateCaretOffset(); - auto caretRect = selectController_->GetCaretRect(); - selectController_->MoveHandleToContentRect(caretRect); } void TextFieldPattern::AdjustTextInReasonableArea() @@ -346,7 +344,7 @@ void TextFieldPattern::AdjustTextInReasonableArea() textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); } } else { - if (textRect_.GetY() < contentRect_.GetY()) { + if (textRect_.GetY() != contentRect_.GetY()) { auto dy = contentRect_.GetY() - textRect_.GetY(); textRect_.SetOffset(OffsetF(textRect_.GetX(), textRect_.GetY() + dy)); } @@ -487,10 +485,12 @@ void TextFieldPattern::OnTextAreaScroll(float offset) UpdateDoubleHandlePosition(); } else { UpdateSecondHandlePosition(); - selectController_->UpdateCaretOffset(); + auto carectOffset = selectController_->GetCaretRect().GetOffset() + OffsetF(0.0f, offset); + selectController_->UpdateCaretOffset(carectOffset); } } else { - selectController_->UpdateCaretOffset(); + auto carectOffset = selectController_->GetCaretRect().GetOffset() + OffsetF(0.0f, offset); + selectController_->UpdateCaretOffset(carectOffset); } UpdateScrollBarOffset(); } @@ -514,9 +514,12 @@ void TextFieldPattern::OnTextInputScroll(float offset) UpdateDoubleHandlePosition(); } else { UpdateSecondHandlePosition(); + auto carectOffset = selectController_->GetCaretRect().GetOffset() + OffsetF(offset, 0.0f); + selectController_->UpdateCaretOffset(carectOffset); } } else { - selectController_->UpdateCaretOffset(); + auto carectOffset = selectController_->GetCaretRect().GetOffset() + OffsetF(offset, 0.0f); + selectController_->UpdateCaretOffset(carectOffset); } auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); @@ -598,11 +601,10 @@ void TextFieldPattern::HandleFocusEvent() CHECK_NULL_VOID(paintProperty); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - if (IsNormalInlineState() && (!contentController_->IsEmpty() || !layoutProperty->GetPlaceholderValue("").empty())) { + if (IsNormalInlineState()) { ApplyInlineStates(true); inlineSelectAllFlag_ = true; inlineFocusState_ = true; - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } else { StartTwinkling(); } @@ -836,7 +838,7 @@ void TextFieldPattern::HandleOnUndoAction() auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::HandleOnRedoAction() @@ -857,7 +859,7 @@ void TextFieldPattern::HandleOnRedoAction() auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) @@ -1213,7 +1215,8 @@ std::function&, const std::strin auto contentController = pattern->contentController_; auto selectController = pattern->selectController_; std::string beforeStr = contentController->GetValueBeforeIndex(selectController->GetStartIndex()); - std::string selectedStr = contentController->GetSelectedValue(selectController->GetStartIndex(), selectController->GetEndIndex()); + std::string selectedStr = + contentController->GetSelectedValue(selectController->GetStartIndex(), selectController->GetEndIndex()); std::string afterStr = contentController->GetValueAfterIndex(selectController->GetEndIndex()); pattern->dragContents_ = { beforeStr, selectedStr, afterStr }; itemInfo.extraInfo = selectedStr; @@ -1644,8 +1647,8 @@ void TextFieldPattern::OnModifyDone() lastTextRectY_ = textRect_.GetY(); } ProcessInnerPadding(); - textRect_.SetLeft(textRect_.GetX() + offsetDifference_.GetX()); - textRect_.SetTop(textRect_.GetY() + offsetDifference_.GetY()); + textRect_.SetLeft(GetPaddingLeft() + GetBorderLeft()); + textRect_.SetTop(GetPaddingTop() + GetBorderTop()); CalculateDefaultCursor(); if (renderContext->HasBackgroundColor()) { paintProperty->UpdateBackgroundColor(renderContext->GetBackgroundColorValue()); @@ -1832,27 +1835,11 @@ void TextFieldPattern::ProcessInnerPadding() auto left = !paddingProperty ? CalcLength(themePadding.Left()).GetDimension().ConvertToPx() : paddingProperty->left.value_or(CalcLength(themePadding.Left())).GetDimension().ConvertToPx(); - offsetDifference_.SetX( - left + (float)currentBorderWidth.leftDimen->ConvertToPx() - GetPaddingLeft() - GetBorderLeft()); - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN) || IsNormalInlineState()) { - offsetDifference_.SetX(left - GetPaddingLeft()); - } utilPadding_.left = left; auto top = !paddingProperty ? CalcLength(themePadding.Top()).GetDimension().ConvertToPx() : paddingProperty->top.value_or(CalcLength(themePadding.Top())).GetDimension().ConvertToPx(); - offsetDifference_.SetY(top + (float)currentBorderWidth.topDimen->ConvertToPx() - GetPaddingTop() - GetBorderTop()); - if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN) || IsNormalInlineState()) { - offsetDifference_.SetY(top - GetPaddingTop()); - } utilPadding_.top = top; - utilPadding_.bottom = - !paddingProperty - ? CalcLength(themePadding.Bottom()).GetDimension().ConvertToPx() - : paddingProperty->bottom.value_or(CalcLength(themePadding.Bottom())).GetDimension().ConvertToPx(); - utilPadding_.right = - !paddingProperty - ? CalcLength(themePadding.Right()).GetDimension().ConvertToPx() : paddingProperty->right.value_or(CalcLength(themePadding.Right())).GetDimension().ConvertToPx(); lastBorderWidth_ = currentBorderWidth; } @@ -4867,7 +4854,6 @@ void TextFieldPattern::UpdateSelectController() { selectController_->UpdateContentRect(contentRect_); selectController_->UpdateParagraph(paragraph_); - selectController_->UpdateCaretOffset(); } bool TextFieldPattern::IsSingleHandle() const diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 82d3ccc3de7..87334416c23 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -389,14 +389,16 @@ public: return utilPadding_; } - float GetHorizontalPaddingSum() const + float GetHorizontalPaddingAndBorderSum() const { - return utilPadding_.left.value_or(0.0f) + utilPadding_.right.value_or(0.0f); + return utilPadding_.left.value_or(0.0f) + utilPadding_.right.value_or(0.0f) + GetBorderLeft() + + GetBorderRight(); } - float GetVerticalPaddingSum() const + float GetVerticalPaddingAndBorderSum() const { - return utilPadding_.top.value_or(0.0f) + utilPadding_.bottom.value_or(0.0f); + return utilPadding_.top.value_or(0.0f) + utilPadding_.bottom.value_or(0.0f) + GetBorderTop() + + GetBorderBottom(); } float GetBorderLeft() const @@ -1124,7 +1126,6 @@ private: OffsetF lastTouchOffset_; PaddingPropertyF utilPadding_; OffsetF rightClickOffset_; - OffsetF offsetDifference_; BorderWidthProperty lastBorderWidth_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp index 3be0ea9dc99..a53fc7efb3c 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ +#include "core/components_ng/pattern/text_field/text_input_response_area.h" + #include "base/geometry/dimension.h" #include "base/geometry/ng/offset_t.h" #include "base/geometry/ng/size_t.h" @@ -23,7 +25,6 @@ #include "core/components_ng/pattern/image/image_pattern.h" #include "core/components_ng/pattern/stack/stack_pattern.h" #include "core/components_ng/pattern/text_field/text_field_layout_property.h" -#include "core/components_ng/pattern/text_field/text_input_response_area.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" #include "core/components_ng/property/measure_property.h" #include "core/components_v2/inspector/inspector_constants.h" @@ -123,12 +124,11 @@ RefPtr PasswordResponseArea::CreateNode() auto imageLayoutProperty = imageNode->GetLayoutProperty(); imageLayoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value()); imageLayoutProperty->UpdateImageFit(ImageFit::FILL); - imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), - CalcLength(iconSize))); + imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize))); imageNode->MarkModifyDone(); imageNode->MountToParent(stackNode); passwordNode_ = imageNode; - + return stackNode; } @@ -249,7 +249,8 @@ void UnitResponseArea::InitResponseArea(const WeakPtr& hostPattern) if (!IsShowUnit()) { return; } - auto unitNode = unitNode_.Upgrade();; + auto unitNode = unitNode_.Upgrade(); + ; CHECK_NULL_VOID(unitNode); unitNode->MountToParent(host); } @@ -284,7 +285,7 @@ bool UnitResponseArea::IsShowUnit() auto layoutProperty = textFieldPattern->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, false); return layoutProperty->GetShowUnderlineValue(false) && - layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::UNSPECIFIED; + layoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::UNSPECIFIED; } void UnitResponseArea::DestoryArea() diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 419da9fa3e3..902857cb299 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -55,6 +55,7 @@ RectF TextSelectController::CalculateEmptyValueCaretRect() const rect.SetLeft(contentRect_.Left()); rect.SetTop(contentRect_.Top()); rect.SetHeight(caretInfo_.rect.Height()); + rect.SetWidth(caretInfo_.rect.Width()); switch (layoutProperty->GetTextAlignValue(TextAlign::START)) { case TextAlign::START: rect.SetLeft(contentRect_.GetX()); @@ -104,6 +105,9 @@ void TextSelectController::UpdateCaretRectByPositionNearTouchOffset(int32_t posi CaretMetricsF caretMetrics; CalcCaretMetricsByPositionNearTouchOffset(position, caretMetrics, OffsetF(static_cast(touchOffset.GetX()), static_cast(touchOffset.GetY()))); + + CaretMetricsF CaretMetrics; + paragraph_->CalcCaretMetricsByPosition(position, CaretMetrics, TextAffinity::UPSTREAM); caretInfo_.UpdateOffset(caretMetrics.offset); UpdateCaretHeight(caretMetrics.height); } @@ -242,18 +246,22 @@ void TextSelectController::MoveHandleToContentRect(RectF& handleRect) } } + auto contentRightBoundary = contentRect_.GetX() + contentRect_.Width(); if (textRect.Width() > contentRect_.Width()) { - auto contentRightBoundary = contentRect_.GetX() + contentRect_.Width(); if (handleRect.GetX() < contentRect_.GetX()) { auto dx = contentRect_.GetX() - handleRect.GetX(); textRect.SetOffset(OffsetF(textRect.GetX() + dx, textRect.GetY())); handleRect.SetOffset(OffsetF(handleRect.GetX() + dx, handleRect.GetY())); - } else if (handleRect.GetX() + handleRect.Width() > contentRightBoundary) { - auto dx = handleRect.GetX() + handleRect.Width() - contentRightBoundary; + } else if (handleRect.GetX() > contentRightBoundary) { + auto dx = handleRect.GetX() - contentRightBoundary; textRect.SetOffset(OffsetF(textRect.GetX() - dx, textRect.GetY())); handleRect.SetOffset(OffsetF(handleRect.GetX() - dx, handleRect.GetY())); } } + if (GreatNotEqual(handleRect.GetX() + handleRect.Width(), contentRightBoundary) && + LessOrEqual(handleRect.Width(), contentRect_.Width())) { + handleRect.SetOffset(OffsetF(contentRightBoundary - handleRect.Width(), handleRect.GetY())); + } textFiled->SetTextRect(textRect); } @@ -298,9 +306,15 @@ void TextSelectController::MoveCaretToContentRect(int32_t index) OffsetF CaretOffset = CaretMetrics.offset; RectF caretRect; caretRect.SetOffset(CaretOffset); - caretRect.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), CaretMetrics.height }); + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + caretRect.SetSize({ caretInfo_.rect.Width(), + LessOrEqual(CaretMetrics.height, 0.0) ? textFiled->PreferredLineHeight() : CaretMetrics.height }); MoveHandleToContentRect(caretRect); caretInfo_.rect = caretRect; + caretRect.SetWidth(SelectHandleInfo::GetDefaultLineWidth().ConvertToPx()); UpdateRecordCaretIndex(caretInfo_.index); } @@ -320,7 +334,7 @@ void TextSelectController::UpdateSecondHandleOffset() secondHandleInfo_.rect.SetHeight(caretMetrics.height); } -void TextSelectController::TextSelectController::UpdateCaretOffset() +void TextSelectController::UpdateCaretOffset() { if (contentController_->IsEmpty()) { caretInfo_.rect = CalculateEmptyValueCaretRect(); @@ -328,8 +342,22 @@ void TextSelectController::TextSelectController::UpdateCaretOffset() } CaretMetricsF caretMetrics; CalcCaretMetricsByPosition(GetCaretIndex(), caretMetrics, TextAffinity::DOWNSTREAM); - caretInfo_.rect.SetOffset(caretMetrics.offset); - caretInfo_.rect.SetHeight(caretMetrics.height); + + RectF caretRect; + caretRect.SetOffset(caretMetrics.offset); + auto pattern = pattern_.Upgrade(); + CHECK_NULL_VOID(pattern); + auto textFiled = DynamicCast(pattern); + CHECK_NULL_VOID(textFiled); + caretRect.SetSize(SizeF(caretInfo_.rect.Width(), + LessOrEqual(caretMetrics.height, 0.0) ? textFiled->PreferredLineHeight() : caretMetrics.height)); + MoveHandleToContentRect(caretRect); + caretInfo_.rect = caretRect; +} + +void TextSelectController::UpdateCaretOffset(const OffsetF& offset) +{ + caretInfo_.rect.SetOffset(offset); } void TextSelectController::UpdateSecondHandleInfoByMouseOffset(const Offset& localOffset) @@ -367,7 +395,6 @@ void TextSelectController::FireSelectEvent() onAccessibilityCallback_(); eventHub->FireOnSelectionChange(firstHandleInfo_.index, secondHandleInfo_.index); } - } void TextSelectController::UpdateRecordCaretIndex(int32_t index) const diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h index d1789490e20..82ebbc65c04 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -173,6 +173,7 @@ public: void UpdateSecondHandleInfoByMouseOffset(const Offset& localOffset); void UpdateSelectByOffset(const Offset& localOffset); void UpdateCaretOffset(); + void UpdateCaretOffset(const OffsetF& offset); void UpdateFirstHandleOffset(); void UpdateSecondHandleOffset(); void MoveFirstHandleToContentRect(int32_t index); diff --git a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp index 812b4dafddb..e5f16908e56 100644 --- a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp @@ -29,9 +29,7 @@ std::optional TextInputLayoutAlgorithm::MeasureContent( // Construct text style. TextStyle textStyle; - std::string textContent; - bool showPlaceHolder = false; - ConstructTextStyles(frameNode, textStyle, textContent, showPlaceHolder); + ConstructTextStyles(frameNode, textStyle, textContent_, showPlaceHolder_); auto isInlineStyle = pattern->IsNormalInlineState(); @@ -39,18 +37,15 @@ std::optional TextInputLayoutAlgorithm::MeasureContent( textFieldLayoutProperty->GetTextInputTypeValue(TextInputType::UNSPECIFIED) == TextInputType::VISIBLE_PASSWORD; // Create paragraph. - auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder && !isInlineStyle; - if (pattern->IsDragging() && !showPlaceHolder) { - CreateParagraph(textStyle, pattern->GetDragContents(), textContent, - isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, disableTextAlign); + auto disableTextAlign = !pattern->IsTextArea() && !showPlaceHolder_ && !isInlineStyle; + if (pattern->IsDragging() && !showPlaceHolder_) { + CreateParagraph(textStyle, pattern->GetDragContents(), textContent_, + isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_, disableTextAlign); } else { - CreateParagraph(textStyle, textContent, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder, + CreateParagraph(textStyle, textContent_, isPasswordType && pattern->GetTextObscured() && !showPlaceHolder_, pattern->GetNakedCharPosition(), disableTextAlign); } - // constraint size. - auto contentIdealSize = CalculateConstraintSize(contentConstraint, layoutWrapper); - autoWidth_ = textFieldLayoutProperty->GetWidthAutoValue(false); // errorParagraph Layout. @@ -70,21 +65,19 @@ std::optional TextInputLayoutAlgorithm::MeasureContent( // Paragraph layout. if (isInlineStyle) { - return InlineMeasureContent(contentConstraint, layoutWrapper, contentIdealSize); - } else if (showPlaceHolder) { - return PlaceHolderMeasureContent(contentIdealSize, 0); + return InlineMeasureContent(contentConstraint, layoutWrapper); + } else if (showPlaceHolder_) { + return PlaceHolderMeasureContent(contentConstraint, layoutWrapper, 0); } else { - return TextInputMeasureConetnt(contentIdealSize, 0); + return TextInputMeasureContent(contentConstraint, layoutWrapper, 0); } } void TextInputLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) { const auto& layoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint(); - OptionalSizeF frameSize = - CreateIdealSize(layoutConstraint.value(), Axis::HORIZONTAL, MeasureType::MATCH_PARENT_MAIN_AXIS); + OptionalSizeF frameSize; const auto& content = layoutWrapper->GetGeometryNode()->GetContent(); - const auto& calcLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(); auto frameNode = layoutWrapper->GetHostNode(); CHECK_NULL_VOID(frameNode); auto pattern = frameNode->GetPattern(); @@ -100,42 +93,39 @@ void TextInputLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper) CHECK_NULL_VOID(pipeline); auto textFieldTheme = pipeline->GetTheme(); CHECK_NULL_VOID(textFieldTheme); - auto defaultHeight = textFieldTheme->GetHeight().ConvertToPx(); - if (!frameSize.Height().has_value()) { - if (calcLayoutConstraint && calcLayoutConstraint->maxSize.has_value() && - calcLayoutConstraint->maxSize.value().Height().has_value()) { - frameSize.SetHeight(std::max(layoutConstraint->maxSize.Height(), layoutConstraint->minSize.Height())); - } else if (!calcLayoutConstraint || NearZero(layoutConstraint->minSize.Height())) { - auto height = contentHeight + pattern->GetVerticalPaddingSum() < defaultHeight - ? defaultHeight - : contentHeight + pattern->GetVerticalPaddingSum(); - frameSize.SetHeight(std::min(layoutConstraint->maxSize.Height(), static_cast(height))); - } else { - frameSize.SetHeight(layoutConstraint->minSize.Height()); - } - } - auto textfieldLayoutProperty = AceType::DynamicCast(layoutWrapper->GetLayoutProperty()); - CHECK_NULL_VOID(textfieldLayoutProperty); + auto defaultHeight = static_cast(textFieldTheme->GetHeight().ConvertToPx()); - if (textfieldLayoutProperty->GetWidthAutoValue(false)) { - frameSize.SetWidth(std::min(textRect_.Width(), contentWidth) + pattern->GetHorizontalPaddingSum()); - } + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum()); + auto contentConstraint = layoutWrapper->GetLayoutProperty()->CreateContentConstraint(); + if (contentConstraint.selfIdealSize.Height().has_value()) { + frameSize.SetHeight(contentConstraint.maxSize.Height() + pattern->GetVerticalPaddingAndBorderSum()); + } else { + auto height = contentHeight + pattern->GetVerticalPaddingAndBorderSum() < defaultHeight + ? defaultHeight + : contentHeight + pattern->GetVerticalPaddingAndBorderSum(); + frameSize.SetHeight(height); + } if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { frameSize.Constrain(layoutConstraint->minSize, layoutConstraint->maxSize); } else { auto finalSize = UpdateOptionSizeByCalcLayoutConstraint(frameSize, layoutWrapper->GetLayoutProperty()->GetCalcLayoutConstraint(), layoutWrapper->GetLayoutProperty()->GetLayoutConstraint()->percentReference); - frameSize.SetWidth(finalSize.Width()); frameSize.SetHeight(finalSize.Height()); } layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); - auto responseArea = pattern->GetResponseArea(); if (responseArea && content) { + auto contentConstraint = layoutWrapper->GetLayoutProperty()->CreateContentConstraint(); auto childWidth = responseArea->Measure(layoutWrapper).Width(); - content->SetSize(SizeF(contentWidth - childWidth, contentHeight)); + if (LessOrEqual(contentWidth + childWidth, contentConstraint.maxSize.Width())) { + frameSize.SetWidth(contentWidth + pattern->GetHorizontalPaddingAndBorderSum() + childWidth); + } else { + content->SetSize(SizeF(contentConstraint.maxSize.Width() - childWidth, contentHeight)); + frameSize.SetWidth(contentConstraint.maxSize.Width() + pattern->GetHorizontalPaddingAndBorderSum()); + } + layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize.ConvertToSizeT()); } } @@ -161,12 +151,13 @@ void TextInputLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) align = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().value_or(align); hasAlign = layoutWrapper->GetLayoutProperty()->GetPositionProperty()->GetAlignment().has_value(); } + // Update content position. OffsetF contentOffset = Alignment::GetAlignPosition(size, contentSize, align); - content->SetOffset(OffsetF(pattern->GetPaddingLeft(), contentOffset.GetY())); + content->SetOffset(OffsetF(pattern->GetPaddingLeft() + pattern->GetBorderLeft(), contentOffset.GetY())); auto paintProperty = pattern->GetPaintProperty(); CHECK_NULL_VOID(paintProperty); - if (paragraph_->GetLongestLine() <= contentSize.Width()) { + if (LessOrEqual(textRect_.Width(), contentSize.Width())) { // adjust text rect to the basic padding float textRectOffsetX = 0.0f; if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { -- Gitee From a7828015f1e8af08d0583530238124558cb7c2e2 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Thu, 19 Oct 2023 14:00:29 +0800 Subject: [PATCH 06/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=85=89=E6=A0=87?= =?UTF-8?q?=E7=82=B9=E5=87=BB=20=E6=97=A0=E6=B3=95=E5=BC=B9=E5=87=BAmenu?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I5cdc6f4b01c40dc6c41092b59ea2591a33a5153c --- .../pattern/text_field/text_field_pattern.cpp | 8 ++++---- .../pattern/text_field/text_select_controller.cpp | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 9a869bfe06b..12441e67fe6 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1457,7 +1457,7 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) StartTwinkling(); SetIsSingleHandle(true); if (lastCaretIndex == selectController_->GetCaretIndex() && hasFocus && caretStatus_ == CaretStatus::SHOW && - !isUsingMouse_ && !IsSelected()) { + !isUsingMouse_) { ProcessOverlay(true); } else { CloseSelectOverlay(true); @@ -1907,8 +1907,8 @@ void TextFieldPattern::ProcessOverlay(bool animation, bool isShowMenu) selectController_->CalculateHandleOffset(); if (isSingleHandle_) { StartTwinkling(); - LOGD("Show single handle Handle info %{public}s", selectController_->GetSecondHandleRect().ToString().c_str()); - ShowSelectOverlay(std::nullopt, selectController_->GetSecondHandleRect(), animation, isShowMenu); + LOGD("Show single handle Handle info %{public}s", selectController_->GetCaretRect().ToString().c_str()); + ShowSelectOverlay(std::nullopt, selectController_->GetCaretRect(), animation, isShowMenu); } else { LOGD("Show handles firstHandle info %{public}s, secondHandle Info %{public}s", selectController_->GetFirstHandleRect().ToString().c_str(), @@ -3026,7 +3026,7 @@ void TextFieldPattern::Delete(int32_t start, int32_t end) SwapIfLarger(start, end); LOGI("Handle Delete within [%{public}d, %{public}d]", start, end); contentController_->erase(start, end - start); - selectController_->UpdateCaretIndex(start); + selectController_->MoveCaretToContentRect(start); FireOnTextChangeEvent(); CloseSelectOverlay(true); StartTwinkling(); diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 902857cb299..a2b63774112 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -118,8 +118,10 @@ void TextSelectController::UpdateCaretInfoByOffset(const Offset& localOffset) UpdateCaretIndex(index); if (!contentController_->IsEmpty()) { UpdateCaretRectByPositionNearTouchOffset(index, localOffset); + MoveCaretToContentRect(GetCaretIndex()); + } else { + caretInfo_.rect = CalculateEmptyValueCaretRect(); } - MoveCaretToContentRect(GetCaretIndex()); } int32_t TextSelectController::ConvertTouchOffsetToPosition(const Offset& localOffset) @@ -298,6 +300,7 @@ void TextSelectController::MoveSecondHandleToContentRect(int32_t index) void TextSelectController::MoveCaretToContentRect(int32_t index) { + index = std::clamp(index, 0, static_cast(contentController_->GetWideText().length())); CaretMetricsF CaretMetrics; caretInfo_.index = index; firstHandleInfo_.index = index; -- Gitee From 483066da72ff3d07bb45d2e15dba0be5f317f861 Mon Sep 17 00:00:00 2001 From: wangtao Date: Thu, 19 Oct 2023 09:06:40 +0000 Subject: [PATCH 07/31] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=A8=A1=E5=BC=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: Iee7b1ed1b843f7ce6e861db0c22104dfde3cae74 --- .../pattern/text_field/key_event_handler.cpp | 2 +- .../text_field_layout_algorithm.cpp | 11 --- .../text_field/text_field_layout_algorithm.h | 1 - .../pattern/text_field/text_field_pattern.cpp | 72 +++++-------------- .../pattern/text_field/text_field_pattern.h | 4 -- .../text_field/text_input_response_area.cpp | 56 ++++++++++----- .../text_field/text_input_response_area.h | 3 +- 7 files changed, 60 insertions(+), 89 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp b/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp index 430924be26b..b2d279fc312 100644 --- a/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp +++ b/frameworks/core/components_ng/pattern/text_field/key_event_handler.cpp @@ -100,7 +100,7 @@ bool KeyEventHandler::HandleKeyEvent(const KeyEvent& keyEvent) if (keyEvent.code == KeyCode::KEY_FORWARD_DEL) { #if defined(PREVIEW) pattern->DeleteBackward(TextFieldPattern::GetGraphemeClusterLength( - pattern->GetWideText(), pattern->GetCaretIndex().caretPosition, true)); + pattern->GetWideText(), pattern->GetCaretIndex(), true)); #else pattern->DeleteForward( TextFieldPattern::GetGraphemeClusterLength(pattern->GetWideText(), pattern->GetCaretIndex())); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp index 48d18c77290..3fced861a18 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp @@ -449,17 +449,6 @@ float TextFieldLayoutAlgorithm::GetTextFieldDefaultHeight() return static_cast(height.ConvertToPx()); } -float TextFieldLayoutAlgorithm::GetTextFieldDefaultImageHeight() -{ - const auto defaultHeight = 40.0_vp; - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_RETURN(pipeline, defaultHeight.ConvertToPx()); - auto textFieldTheme = pipeline->GetTheme(); - CHECK_NULL_RETURN(textFieldTheme, defaultHeight.ConvertToPx()); - auto height = textFieldTheme->GetIconHotZoneSize(); - return static_cast(height.ConvertToPx()); -} - void TextFieldLayoutAlgorithm::SetPropertyToModifier( const TextStyle& textStyle, RefPtr modifier) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h index e7d41b2ea1a..7766795704c 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h @@ -89,7 +89,6 @@ protected: void SetPropertyToModifier(const TextStyle& textStyle, RefPtr modifier); float GetTextFieldDefaultHeight(); - float GetTextFieldDefaultImageHeight(); void ConstructTextStyles( const RefPtr& frameNode, TextStyle& textStyle, std::string& textContent, bool& showPlaceHolder); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 12441e67fe6..501cd7f559a 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -359,42 +359,6 @@ void TextFieldPattern::AdjustTextInReasonableArea() } } -float TextFieldPattern::GetIconSize() -{ - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, 0.0f); - auto pipeline = tmpHost->GetContext(); - CHECK_NULL_RETURN(pipeline, 0.0f); - auto themeManager = pipeline->GetThemeManager(); - CHECK_NULL_RETURN(themeManager, 0.0f); - auto textFieldTheme = themeManager->GetTheme(); - CHECK_NULL_RETURN(textFieldTheme, 0.0f); - return static_cast(textFieldTheme->GetIconSize().ConvertToPx()); -} - -float TextFieldPattern::GetIconHotZoneSize() -{ - auto tmpHost = GetHost(); - CHECK_NULL_RETURN(tmpHost, 0.0f); - auto pipeline = tmpHost->GetContext(); - CHECK_NULL_RETURN(pipeline, 0.0f); - auto themeManager = pipeline->GetThemeManager(); - CHECK_NULL_RETURN(themeManager, 0.0f); - auto textFieldTheme = themeManager->GetTheme(); - CHECK_NULL_RETURN(textFieldTheme, 0.0f); - return static_cast(textFieldTheme->GetIconHotZoneSize().ConvertToPx()); -} - -float TextFieldPattern::GetIconRightOffset() -{ - auto iconSize = GetIconSize(); - auto iconHotZoneSize = GetIconHotZoneSize(); - if (NearZero(iconSize) || NearZero(iconHotZoneSize)) { - return 0.0f; - } - return (iconHotZoneSize - iconSize) / 2.0f; -} - bool TextFieldPattern::IsTextArea() const { auto tmpHost = GetHost(); @@ -877,7 +841,7 @@ void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) if (IsSelected()) { SetIsSingleHandle(false); } - updateSelectionAfterObscure_ = ResetObscureTickCountDown(); + ResetObscureTickCountDown(); GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); // move text to end if (IsTextArea() && GreatOrEqual(textRect_.Height(), contentRect_.Height())) { @@ -1862,11 +1826,14 @@ void TextFieldPattern::InitLongPressEvent() void TextFieldPattern::HandleLongPress(GestureEvent& info) { + auto host = GetHost(); + CHECK_NULL_VOID(host); + if (ResetObscureTickCountDown()) { + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } if (isUsingMouse_) { return; } - auto host = GetHost(); - CHECK_NULL_VOID(host); auto hub = host->GetEventHub(); CHECK_NULL_VOID(hub); auto gestureHub = hub->GetOrCreateGestureEventHub(); @@ -1880,7 +1847,6 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) #ifdef ENABLE_DRAG_FRAMEWORK gestureHub->SetIsTextDraggable(false); #endif - ResetObscureTickCountDown(); isUsingMouse_ = false; auto focusHub = GetFocusHub(); @@ -2692,7 +2658,11 @@ void TextFieldPattern::OnCursorMoveDone() CloseSelectOverlay(); selectionMode_ = SelectionMode::NONE; selectController_->MoveCaretToContentRect(GetCaretIndex()); - GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + if (ResetObscureTickCountDown()) { + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + } else { + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); + } } int32_t TextFieldPattern::GetWordLength(int32_t originCaretPosition, int32_t directionMove) @@ -2809,7 +2779,6 @@ bool TextFieldPattern::CharLineChanged(int32_t caretPosition) bool TextFieldPattern::CursorMoveLeft() { LOGI("Handle cursor move left"); - ResetObscureTickCountDown(); auto originCaretPosition = selectController_->GetCaretIndex(); if (IsSelected()) { selectController_->UpdateCaretIndex( @@ -2844,7 +2813,6 @@ bool TextFieldPattern::CursorMoveLeftWord() } else { UpdateCaretPositionWithClamp(originCaretPosition - leftWordLength); } - ResetObscureTickCountDown(); OnCursorMoveDone(); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2869,7 +2837,6 @@ bool TextFieldPattern::CursorMoveLineBegin() } else { UpdateCaretPositionWithClamp(0); } - ResetObscureTickCountDown(); OnCursorMoveDone(); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2902,7 +2869,6 @@ bool TextFieldPattern::CursorMoveHome() bool TextFieldPattern::CursorMoveRight() { LOGI("Handle cursor move right"); - ResetObscureTickCountDown(); auto originCaretPosition = selectController_->GetCaretIndex(); if (IsSelected()) { CloseSelectOverlay(); @@ -2935,7 +2901,6 @@ bool TextFieldPattern::CursorMoveRightWord() } else { UpdateCaretPositionWithClamp(originCaretPosition + rightWordLength); } - ResetObscureTickCountDown(); OnCursorMoveDone(); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2960,7 +2925,6 @@ bool TextFieldPattern::CursorMoveLineEnd() } else { UpdateCaretPositionWithClamp(textLength); } - ResetObscureTickCountDown(); OnCursorMoveDone(); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -3291,8 +3255,8 @@ void TextFieldPattern::InitSurfacePositionChangedCallback() void TextFieldPattern::DeleteBackward(int32_t length) { LOGI("Handle DeleteBackward %{public}d characters", length); + ResetObscureTickCountDown(); if (IsSelected()) { - ResetObscureTickCountDown(); Delete(selectController_->GetStartIndex(), selectController_->GetEndIndex()); return; } @@ -3300,7 +3264,6 @@ void TextFieldPattern::DeleteBackward(int32_t length) LOGW("Caret position at the beginning , cannot DeleteBackward"); return; } - ResetObscureTickCountDown(); auto start = std::max(selectController_->GetCaretIndex() - length, 0); contentController_->erase(start, length); selectController_->UpdateCaretIndex(start); @@ -3322,8 +3285,8 @@ void TextFieldPattern::DeleteBackward(int32_t length) void TextFieldPattern::DeleteForward(int32_t length) { LOGI("Handle DeleteForward %{public}d characters", length); + ResetObscureTickCountDown(); if (IsSelected()) { - ResetObscureTickCountDown(); Delete(selectController_->GetStartIndex(), selectController_->GetEndIndex()); return; } @@ -3331,7 +3294,6 @@ void TextFieldPattern::DeleteForward(int32_t length) LOGW("Caret position at the end , cannot DeleteForward"); return; } - ResetObscureTickCountDown(); contentController_->erase(selectController_->GetCaretIndex(), length); FireOnTextChangeEvent(); selectionMode_ = SelectionMode::NONE; @@ -3378,7 +3340,7 @@ void TextFieldPattern::AfterSelection() { LOGI("Selection %{public}s, caret position %{public}d", selectController_->ToString().c_str(), selectController_->GetCaretIndex()); - updateSelectionAfterObscure_ = ResetObscureTickCountDown(); + ResetObscureTickCountDown(); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); auto layoutProperty = GetHost()->GetLayoutProperty(); @@ -4916,11 +4878,13 @@ void TextFieldPattern::UpdateRecordCaretIndex(int32_t index) void TextFieldPattern::OnObscuredChanged(bool isObscured) { + ResetObscureTickCountDown(); textObscured_ = isObscured; + CloseSelectOverlay(false); + selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); + StartTwinkling(); auto host = GetHost(); CHECK_NULL_VOID(host); - selectController_->UpdateCaretIndex(selectController_->GetSecondHandleIndex()); - StartTwinkling(); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 87334416c23..5525059daac 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -566,10 +566,6 @@ public: return selectController_->GetCaretRect(); } - float GetIconRightOffset(); - float GetIconHotZoneSize(); - float GetIconSize(); - void HandleSurfaceChanged(int32_t newWidth, int32_t newHeight, int32_t prevWidth, int32_t prevHeight); void HandleSurfacePositionChanged(int32_t posX, int32_t posY) const; diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp index a53fc7efb3c..c0fc41bb57e 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -102,8 +102,8 @@ RefPtr PasswordResponseArea::CreateNode() { auto textFieldPattern = DynamicCast(hostPattern_.Upgrade()); CHECK_NULL_RETURN(textFieldPattern, nullptr); - auto iconSize = textFieldPattern->GetIconSize(); - auto rightOffset = textFieldPattern->GetIconRightOffset(); + auto iconSize = GetIconSize(); + auto rightOffset = GetIconRightOffset(); auto hotZoneSize = iconSize + rightOffset; auto stackNode = FrameNode::CreateFrameNode( @@ -137,19 +137,13 @@ void PasswordResponseArea::AddEvent(const RefPtr& node) CHECK_NULL_VOID(node); auto focusHub = node->GetOrCreateFocusHub(); CHECK_NULL_VOID(focusHub); - focusHub->SetFocusable(true); - - if (!clickListener_) { - auto gesture = node->GetOrCreateGestureEventHub(); - auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) { - auto button = weak.Upgrade(); - CHECK_NULL_VOID(button); - button->OnPasswordIconClicked(); - }; - clickListener_ = MakeRefPtr(std::move(clickCallback)); - gesture->AddClickEvent(clickListener_); - } - // TODO mouse hover event + auto gesture = node->GetOrCreateGestureEventHub(); + auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) { + auto button = weak.Upgrade(); + CHECK_NULL_VOID(button); + button->OnPasswordIconClicked(); + }; + gesture->AddClickEvent(MakeRefPtr(std::move(clickCallback))); } void PasswordResponseArea::OnPasswordIconClicked() @@ -184,6 +178,36 @@ OffsetF PasswordResponseArea::GetChildOffset(SizeF parentSize, RectF contentRect return OffsetF(parentSize.Width() - childSize.Width(), 0); } +float PasswordResponseArea::GetIconSize() +{ + auto textFieldPattern = hostPattern_.Upgrade(); + CHECK_NULL_RETURN(textFieldPattern, 0.0f); + auto tmpHost = textFieldPattern->GetHost(); + CHECK_NULL_RETURN(tmpHost, 0.0f); + auto pipeline = tmpHost->GetContext(); + CHECK_NULL_RETURN(pipeline, 0.0f); + auto themeManager = pipeline->GetThemeManager(); + CHECK_NULL_RETURN(themeManager, 0.0f); + auto textFieldTheme = themeManager->GetTheme(); + CHECK_NULL_RETURN(textFieldTheme, 0.0f); + return static_cast(textFieldTheme->GetIconSize().ConvertToPx()); +} + +float PasswordResponseArea::GetIconRightOffset() +{ + auto textFieldPattern = hostPattern_.Upgrade(); + CHECK_NULL_RETURN(textFieldPattern, 0.0f); + auto tmpHost = textFieldPattern->GetHost(); + auto pipeline = tmpHost->GetContext(); + CHECK_NULL_RETURN(pipeline, 0.0f); + auto themeManager = pipeline->GetThemeManager(); + CHECK_NULL_RETURN(themeManager, 0.0f); + auto textFieldTheme = themeManager->GetTheme(); + CHECK_NULL_RETURN(textFieldTheme, 0.0f); + auto themePadding = textFieldTheme->GetPadding(); + return static_cast(themePadding.Left().ConvertToPx()); +} + void PasswordResponseArea::LoadImageSourceInfo() { auto textFieldPattern = hostPattern_.Upgrade(); @@ -216,7 +240,6 @@ void PasswordResponseArea::UpdateImageSource() void PasswordResponseArea::DestoryArea() { TextInputResponseArea::DestoryArea(); - clickListener_.Reset(); isObscured_ = true; hostPattern_.Reset(); passwordNode_.Reset(); @@ -250,7 +273,6 @@ void UnitResponseArea::InitResponseArea(const WeakPtr& hostPattern) return; } auto unitNode = unitNode_.Upgrade(); - ; CHECK_NULL_VOID(unitNode); unitNode->MountToParent(host); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h index afd7f6c960c..7f7aefb628a 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h @@ -85,6 +85,8 @@ private: void UpdateImageSource(); bool IsShowPasswordIcon(); void OnPasswordIconClicked(); + float GetIconRightOffset(); + float GetIconSize(); RefPtr CreateNode(); std::optional GetCurrentSourceInfo() { @@ -93,7 +95,6 @@ private: bool isObscured_ = true; std::optional showIcon_; std::optional hideIcon_; - RefPtr clickListener_; WeakPtr passwordNode_; }; -- Gitee From 5c3afe7b099910b2967d8e37f5af797326038a26 Mon Sep 17 00:00:00 2001 From: lijuan Date: Thu, 19 Oct 2023 09:53:39 +0000 Subject: [PATCH 08/31] =?UTF-8?q?textfield=E4=BC=98=E5=8C=96:1=E3=80=81?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dsearch=E9=BB=98=E8=AE=A4=E9=AB=98=E5=BA=A6?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=E4=BB=A5=E5=8F=8A=E8=BE=93=E5=85=A5=E5=86=85?= =?UTF-8?q?=E5=AE=B9=E5=90=8E=E6=9C=AA=E6=98=BE=E7=A4=BA=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E9=97=AE=E9=A2=98;2=E3=80=81=E5=8F=8C?= =?UTF-8?q?=E6=89=8B=E6=9F=84=E6=97=B6=EF=BC=8C=E6=89=8B=E6=9F=84=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E5=8F=96=E6=9C=80=E5=A4=A7index=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E5=85=89=E6=A0=87=E4=BD=8D=E7=BD=AE=EF=BC=9B3=E3=80=81?= =?UTF-8?q?=E5=8F=8C=E6=89=8B=E6=89=8B=E6=9F=84=E9=87=8D=E5=90=88=E6=97=B6?= =?UTF-8?q?=E5=85=B3=E9=97=AD=E6=89=8B=E6=9F=84=EF=BC=8C=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E5=85=89=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I5f563073e71c1f1324f531a3ab21715ba5edb1c0 --- .../search/search_layout_algorithm.cpp | 2 +- .../pattern/search/search_model_ng.cpp | 33 ++++++++++++------- .../pattern/search/search_pattern.cpp | 18 ++++++++++ .../pattern/search/search_pattern.h | 1 + .../pattern/text_field/text_field_event_hub.h | 5 +++ .../pattern/text_field/text_field_pattern.cpp | 14 +++++--- .../text_field/text_select_controller.cpp | 7 +++- 7 files changed, 63 insertions(+), 17 deletions(-) diff --git a/frameworks/core/components_ng/pattern/search/search_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/search/search_layout_algorithm.cpp index cce66b18fcc..522298b26ee 100644 --- a/frameworks/core/components_ng/pattern/search/search_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/search/search_layout_algorithm.cpp @@ -154,7 +154,7 @@ void SearchLayoutAlgorithm::TextFieldMeasure(LayoutWrapper* layoutWrapper) float leftPadding = padding.left.value_or(0.0f); float rightPadding = padding.right.value_or(0.0f); auto textFieldWidth = searchWidthMax - searchTheme->GetSearchIconLeftSpace().ConvertToPx() - iconRenderWidth - - searchTheme->GetSearchIconRightSpace().ConvertToPx() - leftPadding - rightPadding; + searchTheme->GetSearchIconRightSpace().ConvertToPx() - leftPadding - rightPadding; if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) { textFieldWidth = searchWidthMax - searchTheme->GetSearchIconLeftSpace().ConvertToPx() - iconRenderWidth - searchTheme->GetSearchIconRightSpace().ConvertToPx(); diff --git a/frameworks/core/components_ng/pattern/search/search_model_ng.cpp b/frameworks/core/components_ng/pattern/search/search_model_ng.cpp index 06c61eae567..04dd5c8af41 100644 --- a/frameworks/core/components_ng/pattern/search/search_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/search/search_model_ng.cpp @@ -485,15 +485,19 @@ void SearchModelNG::SetOnChange(std::function&& onChan CHECK_NULL_VOID(searchTextField); auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), onChange]( - const std::string& value) { + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(pattern)), onChange](const std::string& value) { if (onChange) { onChange(value); } - auto node = weak.Upgrade(); - if (node) { - node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - } + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto searchPattern = AceType::DynamicCast(pattern); + CHECK_NULL_VOID(searchPattern); + searchPattern->UpdateChangeEvent(value); }; eventHub->SetOnChange(std::move(searchChangeFunc)); } @@ -628,6 +632,8 @@ void SearchModelNG::CreateTextField(const RefPtr& parentNode, const PaddingProperty padding; padding.left = CalcLength(0.0); padding.right = CalcLength(0.0); + padding.bottom = CalcLength(0.0); + padding.top = CalcLength(0.0); textFieldLayoutProperty->UpdatePadding(padding); pattern->SetEnableTouchAndHoverEffect(false); renderContext->UpdateBackgroundColor(Color::TRANSPARENT); @@ -819,15 +825,20 @@ void SearchModelNG::SetOnChangeEvent(std::function&& o CHECK_NULL_VOID(searchTextField); auto eventHub = searchTextField->GetEventHub(); CHECK_NULL_VOID(eventHub); - auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(searchTextField)), onChangeEvent]( + auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode(); + CHECK_NULL_VOID(frameNode); + auto pattern = frameNode->GetPattern(); + CHECK_NULL_VOID(pattern); + auto searchChangeFunc = [weak = AceType::WeakClaim(AceType::RawPtr(pattern)), onChangeEvent]( const std::string& value) { if (onChangeEvent) { onChangeEvent(value); } - auto node = weak.Upgrade(); - if (node) { - node->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); - } + auto pattern = weak.Upgrade(); + CHECK_NULL_VOID(pattern); + auto searchPattern = AceType::DynamicCast(pattern); + CHECK_NULL_VOID(searchPattern); + searchPattern->UpdateChangeEvent(value); }; eventHub->SetOnChangeEvent(std::move(searchChangeFunc)); } diff --git a/frameworks/core/components_ng/pattern/search/search_pattern.cpp b/frameworks/core/components_ng/pattern/search/search_pattern.cpp index a56b40a5ddd..6e3018a9e6f 100644 --- a/frameworks/core/components_ng/pattern/search/search_pattern.cpp +++ b/frameworks/core/components_ng/pattern/search/search_pattern.cpp @@ -173,6 +173,7 @@ void SearchPattern::OnModifyDone() InitButtonAndImageClickEvent(); InitCancelButtonClickEvent(); InitTextFieldMouseEvent(); + InitTextFieldValueChangeEvent(); InitButtonMouseEvent(searchButtonMouseEvent_, BUTTON_INDEX); InitButtonMouseEvent(cancelButtonMouseEvent_, CANCEL_BUTTON_INDEX); InitButtonTouchEvent(searchButtonTouchListener_, BUTTON_INDEX); @@ -184,6 +185,23 @@ void SearchPattern::OnModifyDone() InitClickEvent(); } +void SearchPattern::InitTextFieldValueChangeEvent() +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto textFieldFrameNode = AceType::DynamicCast(host->GetChildren().front()); + CHECK_NULL_VOID(textFieldFrameNode); + auto eventHub = textFieldFrameNode->GetEventHub(); + CHECK_NULL_VOID(eventHub); + if (!eventHub->GetOnChange()) { + auto searchChangeFunc = [weak = AceType::WeakClaim(this)](const std::string& value) { + auto searchPattern = weak.Upgrade(); + searchPattern->UpdateChangeEvent(value); + }; + eventHub->SetOnChange(std::move(searchChangeFunc)); + } +} + void SearchPattern::InitButtonAndImageClickEvent() { // Image click event diff --git a/frameworks/core/components_ng/pattern/search/search_pattern.h b/frameworks/core/components_ng/pattern/search/search_pattern.h index 1887632aedc..bde1cfd13bd 100644 --- a/frameworks/core/components_ng/pattern/search/search_pattern.h +++ b/frameworks/core/components_ng/pattern/search/search_pattern.h @@ -149,6 +149,7 @@ private: void RequestKeyboard(); // Init touch and hover event void InitTextFieldMouseEvent(); + void InitTextFieldValueChangeEvent(); void InitButtonTouchEvent(RefPtr& touchEvent, int32_t childId); void InitButtonMouseEvent(RefPtr& inputEvent, int32_t childId); void SetMouseStyle(MouseFormat format); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_event_hub.h b/frameworks/core/components_ng/pattern/text_field/text_field_event_hub.h index ec3d75fd8c0..eff175ea6c6 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_event_hub.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_event_hub.h @@ -76,6 +76,11 @@ public: onChange_ = std::move(func); } + const std::function& GetOnChange() const + { + return onChange_; + } + void FireOnChange(const std::string& value) { if (lastValue_.has_value() && lastValue_.value() == value) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 501cd7f559a..a8b7be6ae03 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -2134,10 +2134,16 @@ void TextFieldPattern::OnHandleMoveDone(const RectF& /* handleRect */, bool isFi auto proxy = GetSelectOverlayProxy(); CHECK_NULL_VOID(proxy); if (!isSingleHandle_) { - auto handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); - proxy->UpdateFirstSelectHandleInfo(handleInfo); - handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); - proxy->UpdateSecondSelectHandleInfo(handleInfo); + if (selectController_->GetFirstHandleIndex() == selectController_->GetSecondHandleIndex()) { + CloseSelectOverlay(true); + StartTwinkling(); + } else { + auto handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); + proxy->UpdateFirstSelectHandleInfo(handleInfo); + handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); + proxy->UpdateSecondSelectHandleInfo(handleInfo); + } + selectController_->UpdateCaretOffset(); } else { auto handleInfo = GetSelectHandleInfo(selectController_->GetCaretRect().GetOffset()); proxy->UpdateSecondSelectHandleInfo(handleInfo); diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index a2b63774112..1d11919e9cc 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -273,12 +273,14 @@ void TextSelectController::MoveFirstHandleToContentRect(int32_t index) firstHandleInfo_.index = index; CalcCaretMetricsByPosition(GetFirstHandleIndex(), firstHandleMetrics, TextAffinity::DOWNSTREAM); OffsetF firstHandleOffset = firstHandleMetrics.offset; - RectF firstHandle; firstHandle.SetOffset(firstHandleOffset); firstHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), firstHandleMetrics.height }); MoveHandleToContentRect(firstHandle); firstHandleInfo_.rect = firstHandle; + + caretInfo_.index = std::max(firstHandleInfo_.index, secondHandleInfo_.index); + UpdateSecondHandleOffset(); FireSelectEvent(); } @@ -294,6 +296,9 @@ void TextSelectController::MoveSecondHandleToContentRect(int32_t index) secondHandle.SetSize({ SelectHandleInfo::GetDefaultLineWidth().ConvertToPx(), secondHandleMetrics.height }); MoveHandleToContentRect(secondHandle); secondHandleInfo_.rect = secondHandle; + + caretInfo_.index = std::max(firstHandleInfo_.index, secondHandleInfo_.index); + UpdateFirstHandleOffset(); FireSelectEvent(); } -- Gitee From 77610799a402c315621d3b5ad394944eb2adab55 Mon Sep 17 00:00:00 2001 From: lijuan Date: Thu, 19 Oct 2023 12:28:39 +0000 Subject: [PATCH 09/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dplaceholder=E4=B8=8Ecar?= =?UTF-8?q?etposition=E5=90=8C=E6=97=B6=E8=AE=BE=E7=BD=AE=E5=90=8E?= =?UTF-8?q?=E3=80=82caretpositio=E5=8F=98=E6=88=900?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I7742952c9c316484193ee57afb11f7231657b102 --- .../pattern/text_field/text_field_model_ng.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp index 08f04aa57eb..a2156f37f4c 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp @@ -225,9 +225,8 @@ void TextFieldModelNG::SetCaretPosition(const int32_t& value) CHECK_NULL_VOID(frameNode); auto layoutProperty = frameNode->GetLayoutProperty(); auto pattern = frameNode->GetPattern(); - auto caretPosition = layoutProperty->GetPlaceholderValue().empty() ? value : 0; - ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, CaretPosition, caretPosition); - pattern->SetCaretPosition(caretPosition); + ACE_UPDATE_LAYOUT_PROPERTY(TextFieldLayoutProperty, CaretPosition, value); + pattern->SetCaretPosition(value); } void TextFieldModelNG::SetSelectedBackgroundColor(const Color& value) @@ -453,7 +452,7 @@ void TextFieldModelNG::SetShowCounter(bool value) CHECK_NULL_VOID(frameNode); auto pattern = frameNode->GetPattern(); CHECK_NULL_VOID(pattern); - if(value) { + if (value) { pattern->AddCounterNode(); } else { pattern->ClearCounterNode(); -- Gitee From 75a76386d9b7c4fd04dca39db1aba700eb86a38b Mon Sep 17 00:00:00 2001 From: lijuan Date: Thu, 19 Oct 2023 12:51:55 +0000 Subject: [PATCH 10/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=85=A8=E9=80=89?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=BB=9A=E5=8A=A8=E6=9D=A1=E4=BB=8D=E7=84=B6?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: If7c12f646d78b1f9e525cc26b78adcb02b9cb082 --- .../components_ng/pattern/text_field/text_field_pattern.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index a8b7be6ae03..d587cba920d 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -3905,9 +3905,6 @@ std::string TextFieldPattern::GetBarStateString() const void TextFieldPattern::UpdateScrollBarOffset() { - if (contentController_->IsEmpty()) { - return; - } if (!GetScrollBar() && !GetScrollBarProxy()) { return; } -- Gitee From d7d44392b5dc3402c9cc0bf38356fa9776c6f710 Mon Sep 17 00:00:00 2001 From: lijuan Date: Thu, 19 Oct 2023 13:27:56 +0000 Subject: [PATCH 11/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=83=AF=E6=80=A7?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E8=BF=87=E7=A8=8B=E4=B8=AD=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=85=89=E6=A0=87=E4=BD=8D=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I3a14a22c0d2cba8c5a302f06dc0b4fbaf5a97ea0 --- .../core/components_ng/pattern/text_field/text_field_pattern.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index d587cba920d..bcf6eb4d2c1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -273,6 +273,7 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir if (mouseStatus_ == MouseStatus::RELEASED) { mouseStatus_ = MouseStatus::NONE; } + StopScrollable(); if (IsTextArea()) { CheckScrollable(); } else { -- Gitee From 7efeb7637d463f6678ba6d93c4b2a926ca1f138b Mon Sep 17 00:00:00 2001 From: wangtao Date: Fri, 20 Oct 2023 03:33:37 +0000 Subject: [PATCH 12/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: Ie86733e5653828c9b658cc9b50aeeb138f768765 --- .../select_overlay/select_overlay_client.cpp | 119 +++++++++--------- .../select_overlay/select_overlay_client.h | 12 +- .../pattern/text_field/text_field_pattern.cpp | 43 +++---- .../pattern/text_field/text_field_pattern.h | 3 +- 4 files changed, 89 insertions(+), 88 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp index c57660745f1..d507ea89652 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -73,87 +73,82 @@ void SelectOverlayClient::InitSelectOverlay() selectOverlayInfo_.secondHandle.isShow = false; } -void SelectOverlayClient::RequestOpenSelectOverlay(ClientOverlayInfo showOverlayInfo) +void SelectOverlayClient::RequestOpenSelectOverlay(const ClientOverlayInfo& showOverlayInfo) { LOGI("RequestOpenSelectOverlay start, has first handle %{public}d, has second handle %{public}d", showOverlayInfo.firstHandleInfo.has_value(), showOverlayInfo.secondHandleInfo.has_value()); - auto firstHandleInfo = showOverlayInfo.firstHandleInfo; - auto secondHandleInfo = showOverlayInfo.secondHandleInfo; - HandleShowMode showMode; - if (firstHandleInfo.has_value() && secondHandleInfo.has_value()) { - showMode = HandleShowMode::DOUBLE; - firstHandleInfo->isShow = CheckHandleVisible(firstHandleInfo->paintRect); - secondHandleInfo->isShow = CheckHandleVisible(secondHandleInfo->paintRect); - } else if (!firstHandleInfo.has_value() && secondHandleInfo.has_value()) { - showMode = HandleShowMode::SINGLE; - secondHandleInfo->isShow = CheckHandleVisible(secondHandleInfo->paintRect); + if (SelectOverlayIsOn()) { + UpdateShowingSelectOverlay(showOverlayInfo); } else { - showMode = HandleShowMode::NONE; + CreateSelectOverlay(showOverlayInfo); } - auto getSelectOverlay = [&]() -> std::optional { - SelectOverlayInfo overlayInfo = selectOverlayInfo_; - if (showOverlayInfo.overlayInfoModifier) { - showOverlayInfo.overlayInfoModifier(overlayInfo); - } - overlayInfo.firstHandle = firstHandleInfo.has_value() ? *firstHandleInfo : overlayInfo.firstHandle; - overlayInfo.secondHandle = secondHandleInfo.has_value() ? *secondHandleInfo : overlayInfo.secondHandle; - overlayInfo.isSingleHandle = showMode == HandleShowMode::SINGLE; - overlayInfo.isSelectRegionVisible = CheckSelectionRectVisible(); - if (!GetMenuOptionItems().empty()) { - overlayInfo.menuOptionItems = GetMenuOptionItems(); - } - if (OnPreShowSelectOverlay(overlayInfo, showOverlayInfo.extraInfo)) { - return overlayInfo; - } - return std::nullopt; - }; - auto currentShowMode = IsShowingSingleHandle() ? HandleShowMode::SINGLE : HandleShowMode::DOUBLE; - if (showMode != currentShowMode) { - RequestCloseSelectOverlay(true); +} + +void SelectOverlayClient::CreateSelectOverlay(const ClientOverlayInfo& clientOverlayInfo) +{ + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto overlayInfo = GetSelectOverlayInfo(clientOverlayInfo); + CHECK_NULL_VOID(overlayInfo); + LOGD("first handle visibility %{public}d, second handle visibility %{public}d, select rect visibility " + "%{public}d", + overlayInfo.firstHandle.isShow, overlayInfo.secondHandle.isShow, overlayInfo.isSelectRegionVisible); + selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( + *overlayInfo, WeakClaim(this), clientOverlayInfo.animation); + StartListeningScrollableParent(GetClientHost()); +} + +std::optional SelectOverlayClient::GetSelectOverlayInfo(const ClientOverlayInfo& clientInfo) +{ + auto firstHandleInfo = clientInfo.firstHandleInfo; + auto secondHandleInfo = clientInfo.secondHandleInfo; + if (firstHandleInfo.has_value()) { + firstHandleInfo->isShow = CheckHandleVisible(firstHandleInfo->paintRect); } - if (SelectOverlayIsOn()) { - auto overlayInfo = getSelectOverlay(); - CHECK_NULL_VOID(overlayInfo); - UpdateShowingSelectOverlay(showMode, *overlayInfo); - return; + if (secondHandleInfo.has_value()) { + secondHandleInfo->isShow = CheckHandleVisible(secondHandleInfo->paintRect); + } + SelectOverlayInfo overlayInfo = selectOverlayInfo_; + overlayInfo.firstHandle = firstHandleInfo.has_value() ? *firstHandleInfo : overlayInfo.firstHandle; + overlayInfo.secondHandle = secondHandleInfo.has_value() ? *secondHandleInfo : overlayInfo.secondHandle; + overlayInfo.isSingleHandle = !firstHandleInfo && secondHandleInfo; + overlayInfo.isSelectRegionVisible = CheckSelectionRectVisible(); + if (!GetMenuOptionItems().empty()) { + overlayInfo.menuOptionItems = GetMenuOptionItems(); } - if (!SelectOverlayIsOn()) { - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(pipeline); - auto overlayInfo = getSelectOverlay(); - CHECK_NULL_VOID(overlayInfo); - LOGD("first handle visibility %{public}d, second handle visibility %{public}d, select rect visibility " - "%{public}d", - overlayInfo.firstHandle.isShow, overlayInfo.secondHandle.isShow, overlayInfo.isSelectRegionVisible); - selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( - *overlayInfo, WeakClaim(this), showOverlayInfo.animation); - StartListeningScrollableParent(GetClientHost()); + if (OnPreShowSelectOverlay(overlayInfo, clientInfo, SelectOverlayIsOn())) { + return overlayInfo; } + return std::nullopt; } -void SelectOverlayClient::UpdateShowingSelectOverlay(HandleShowMode mode, const SelectOverlayInfo& overlayInfo) +void SelectOverlayClient::UpdateShowingSelectOverlay(const ClientOverlayInfo& clientInfo) { - if (mode == HandleShowMode::SINGLE) { - auto proxy = GetSelectOverlayProxy(); - CHECK_NULL_VOID(proxy); - proxy->UpdateSelectMenuInfo([newMenuInfo = overlayInfo.menuInfo](SelectMenuInfo& menuInfo) { + auto isCurrentSingleHandle = IsShowingSingleHandle(); + auto hasRequestSingleHandle = !clientInfo.firstHandleInfo && clientInfo.secondHandleInfo; + if (clientInfo.isShowMouseMenu || isCurrentSingleHandle ^ hasRequestSingleHandle) { + RequestCloseSelectOverlay(true); + CreateSelectOverlay(clientInfo); + return; + } + auto selectOverlayInfo = GetSelectOverlayInfo(clientInfo); + CHECK_NULL_VOID(selectOverlayInfo); + auto proxy = GetSelectOverlayProxy(); + CHECK_NULL_VOID(proxy); + if (hasRequestSingleHandle) { + proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { menuInfo.showPaste = newMenuInfo.showPaste; menuInfo.showCopyAll = true; }); - proxy->UpdateSecondSelectHandleInfo(overlayInfo.secondHandle); - return; - } - - if (mode == HandleShowMode::DOUBLE) { - auto proxy = GetSelectOverlayProxy(); - CHECK_NULL_VOID(proxy); - proxy->UpdateSelectMenuInfo([newMenuInfo = overlayInfo.menuInfo](SelectMenuInfo& menuInfo) { + proxy->UpdateSecondSelectHandleInfo(selectOverlayInfo->secondHandle); + } else { + proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { menuInfo.showPaste = newMenuInfo.showPaste; menuInfo.showCopyAll = newMenuInfo.showCopyAll; menuInfo.showCopy = newMenuInfo.showCopy; menuInfo.showCut = newMenuInfo.showCut; }); - proxy->UpdateFirstAndSecondHandleInfo(overlayInfo.firstHandle, overlayInfo.secondHandle); + proxy->UpdateFirstAndSecondHandleInfo(selectOverlayInfo->firstHandle, selectOverlayInfo->secondHandle); } } diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h index 49649c87eed..c97b7628004 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h @@ -53,7 +53,8 @@ struct ClientOverlayInfo { std::optional secondHandleInfo; bool animation = true; bool isMenuShow = true; - std::function overlayInfoModifier; + bool isShowMouseMenu = false; + bool isShowPaste = false; OverlayExtraInfo extraInfo; }; @@ -74,7 +75,7 @@ class SelectOverlayClient : public SelectionHost { public: void InitSelectOverlay(); - void RequestOpenSelectOverlay(ClientOverlayInfo overlayInfo); + void RequestOpenSelectOverlay(const ClientOverlayInfo& overlayInfo); virtual void RequestCloseSelectOverlay(bool animation); bool SelectOverlayIsOn(); @@ -88,7 +89,8 @@ public: return false; } - virtual bool OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extraInfo) + virtual bool OnPreShowSelectOverlay( + SelectOverlayInfo& overlayInfo, const ClientOverlayInfo& clientInfo, bool isSelectOverlayOn) { return false; } @@ -156,7 +158,9 @@ protected: } private: - void UpdateShowingSelectOverlay(HandleShowMode mode, const SelectOverlayInfo& overlayInfo); + std::optional GetSelectOverlayInfo(const ClientOverlayInfo& clientInfo); + void CreateSelectOverlay(const ClientOverlayInfo& showOverlayInfo); + void UpdateShowingSelectOverlay(const ClientOverlayInfo& clientInfo); ParentScrollableCallback scrollCallback_; ScrollableParentInfo scrollableParentInfo_; SelectOverlayInfo selectOverlayInfo_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index bcf6eb4d2c1..ab967ff82d1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -67,6 +67,7 @@ #include "core/components_ng/render/paragraph.h" #include "core/components_v2/inspector/inspector_constants.h" #include "core/components_v2/inspector/utils.h" +#include "core/event/ace_events.h" #include "core/image/image_source_info.h" #include "core/pipeline_ng/pipeline_context.h" #if not defined(ACE_UNITTEST) @@ -105,8 +106,6 @@ const std::string EMAIL_WHITE_LIST = "[\\w.\\@]"; const std::string URL_WHITE_LIST = "[a-zA-z]+://[^\\s]*"; const std::string SHOW_PASSWORD_SVG = "SYS_SHOW_PASSWORD_SVG"; const std::string HIDE_PASSWORD_SVG = "SYS_HIDE_PASSWORD_SVG"; -const std::string CLIPBOARD_HAS_DATA = "HAS_DATA"; -const std::string SELECT_OVERLAY_MENU_IS_SHOW = "MENU_IS_SHOW"; void SwapIfLarger(int32_t& a, int32_t& b) { @@ -760,7 +759,6 @@ void TextFieldPattern::HandleBlurEvent() selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); auto eventHub = host->GetEventHub(); eventHub->FireOnEditChanged(false); - CloseSelectOverlay(true); host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -934,6 +932,7 @@ void TextFieldPattern::HandleOnPaste() if (textfield->IsTextArea() && layoutProperty->HasMaxLength()) { textfield->HandleCounterBorder(); } + textfield->CloseSelectOverlay(true); auto host = textfield->GetHost(); CHECK_NULL_VOID(host); auto eventHub = textfield->GetHost()->GetEventHub(); @@ -1354,7 +1353,7 @@ void TextFieldPattern::InitTouchEvent() auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) { auto pattern = weak.Upgrade(); CHECK_NULL_VOID(pattern); - pattern->isUsingMouse_ = false; + pattern->isUsingMouse_ = info.GetSourceDevice() == SourceType::MOUSE; pattern->HandleTouchEvent(info); }; touchListener_ = MakeRefPtr(std::move(touchTask)); @@ -1382,7 +1381,7 @@ void TextFieldPattern::HandleClickEvent(GestureEvent& info) TimeStamp clickTimeStamp = info.GetTimeStamp(); std::chrono::duration> timeout = clickTimeStamp - lastClickTimeStamp_; lastClickTimeStamp_ = info.GetTimeStamp(); - isUsingMouse_ = false; + isUsingMouse_ = info.GetSourceDevice() == SourceType::MOUSE; if (timeout.count() < DOUBLECLICK_INTERVAL_MS) { HandleDoubleClickEvent(info); // 注册手势事件 } else { @@ -1422,7 +1421,7 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) StartTwinkling(); SetIsSingleHandle(true); if (lastCaretIndex == selectController_->GetCaretIndex() && hasFocus && caretStatus_ == CaretStatus::SHOW && - !isUsingMouse_) { + info.GetSourceDevice() != SourceType::MOUSE) { ProcessOverlay(true); } else { CloseSelectOverlay(true); @@ -1438,7 +1437,7 @@ void TextFieldPattern::HandleDoubleClickEvent(GestureEvent& info) StopTwinkling(); SetIsSingleHandle(false); } - if (!isUsingMouse_) { + if (info.GetSourceDevice() != SourceType::MOUSE) { ProcessOverlay(true); } auto host = GetHost(); @@ -1818,7 +1817,7 @@ void TextFieldPattern::InitLongPressEvent() auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) { auto pattern = weak.Upgrade(); CHECK_NULL_VOID(pattern); - pattern->isUsingMouse_ = false; + pattern->isUsingMouse_ = info.GetSourceDevice() == SourceType::MOUSE; pattern->HandleLongPress(info); }; longPressEvent_ = MakeRefPtr(std::move(longPressCallback)); @@ -1832,7 +1831,7 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) if (ResetObscureTickCountDown()) { host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } - if (isUsingMouse_) { + if (info.GetSourceDevice() == SourceType::MOUSE) { return; } auto hub = host->GetEventHub(); @@ -1848,7 +1847,6 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) #ifdef ENABLE_DRAG_FRAMEWORK gestureHub->SetIsTextDraggable(false); #endif - isUsingMouse_ = false; auto focusHub = GetFocusHub(); if (!focusHub->IsFocusOnTouch().value_or(true) || !focusHub->RequestFocusImmediately()) { @@ -1910,8 +1908,9 @@ void TextFieldPattern::ShowSelectOverlay( secondHandleInfo.paintRect = handle; overlayInfo.secondHandleInfo = secondHandleInfo; } - overlayInfo.extraInfo.boolExtra.insert({ CLIPBOARD_HAS_DATA, hasData }); - overlayInfo.extraInfo.boolExtra.insert({ SELECT_OVERLAY_MENU_IS_SHOW, isMenuShow }); + overlayInfo.isShowPaste = hasData; + overlayInfo.isMenuShow = isMenuShow; + overlayInfo.isShowMouseMenu = pattern->IsUsingMouse(); pattern->RequestOpenSelectOverlay(overlayInfo); auto start = pattern->GetTextSelectController()->GetStartIndex(); auto end = pattern->GetTextSelectController()->GetEndIndex(); @@ -1920,7 +1919,8 @@ void TextFieldPattern::ShowSelectOverlay( clipboard_->HasData(hasDataCallback); } -bool TextFieldPattern::OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extraInfo) +bool TextFieldPattern::OnPreShowSelectOverlay( + SelectOverlayInfo& overlayInfo, const ClientOverlayInfo& clientInfo, bool isSelectOverlayOn) { auto host = GetHost(); CHECK_NULL_RETURN(host, false); @@ -1929,7 +1929,9 @@ bool TextFieldPattern::OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, Ov bool isHideSelectionMenu = layoutProperty->GetSelectionMenuHiddenValue(false); // right click menu if (IsUsingMouse()) { - CHECK_NULL_RETURN(isHideSelectionMenu, false); + if (isHideSelectionMenu && !isSelectOverlayOn) { + return false; + } overlayInfo.rightClickOffset = GetRightClickOffset(); overlayInfo.isUsingMouse = true; } else { @@ -1946,10 +1948,9 @@ bool TextFieldPattern::OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, Ov overlayInfo.menuInfo.showCopy = hasTextContent && AllowCopy() && IsSelected(); overlayInfo.menuInfo.showCut = overlayInfo.menuInfo.showCopy; overlayInfo.menuInfo.showCopyAll = hasTextContent && !IsSelectAll(); - auto hasData = extraInfo.GetBoolOrDefault(CLIPBOARD_HAS_DATA, false); + auto hasData = clientInfo.isShowPaste; overlayInfo.menuInfo.showPaste = hasData; - overlayInfo.menuInfo.menuIsShow = (hasTextContent || hasData) && !isHideSelectionMenu && - extraInfo.GetBoolOrDefault(SELECT_OVERLAY_MENU_IS_SHOW, false); + overlayInfo.menuInfo.menuIsShow = (hasTextContent || hasData) && !isHideSelectionMenu && clientInfo.isMenuShow; overlayInfo.isHandleLineShow = overlayInfo.isHandleLineShow && !IsSingleHandle(); overlayInfo.menuInfo.menuDisable = isHideSelectionMenu; auto gesture = host->GetOrCreateGestureEventHub(); @@ -2259,7 +2260,6 @@ void TextFieldPattern::HandleMouseEvent(MouseInfo& info) return; } pipeline->ChangeMouseStyle(frameId, MouseFormat::TEXT_CURSOR); - CloseSelectOverlay(true); isUsingMouse_ = true; if (info.GetButton() == MouseButton::RIGHT_BUTTON) { HandleRightMouseEvent(info); @@ -2270,7 +2270,10 @@ void TextFieldPattern::HandleMouseEvent(MouseInfo& info) void TextFieldPattern::HandleRightMouseEvent(MouseInfo& info) { - if (info.GetAction() == MouseAction::RELEASE) { + auto tmpHost = GetHost(); + CHECK_NULL_VOID(tmpHost); + auto focusHub = tmpHost->GetOrCreateFocusHub(); + if (info.GetAction() == MouseAction::RELEASE && focusHub->IsCurrentFocus()) { LOGI("Handle mouse right button release"); rightClickOffset_ = OffsetF( static_cast(info.GetGlobalLocation().GetX()), static_cast(info.GetGlobalLocation().GetY())); @@ -3201,7 +3204,6 @@ void TextFieldPattern::OnVisibleChange(bool isVisible) if (SelectOverlayIsOn()) { StartTwinkling(); } - CloseSelectOverlay(); } } @@ -4667,7 +4669,6 @@ void TextFieldPattern::StopEditing() } UpdateSelection(selectController_->GetCaretIndex()); StopTwinkling(); - CloseSelectOverlay(); CloseKeyboard(true); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 5525059daac..c39d824e5a1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -934,7 +934,8 @@ public: void OnHandleClosed(bool closedByGlobalEvent) override; bool CheckHandleVisible(const RectF& paintRect) override; bool CheckSelectionRectVisible() override; - bool OnPreShowSelectOverlay(SelectOverlayInfo& overlayInfo, OverlayExtraInfo& extra) override; + bool OnPreShowSelectOverlay( + SelectOverlayInfo& overlayInfo, const ClientOverlayInfo& clientInfo, bool isSelectOverlayOn) override; void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) override { switch (menuId) { -- Gitee From c76c30e47931f93bc5bc06e45f5ffe7f3b4e4aad Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Fri, 20 Oct 2023 16:37:24 +0800 Subject: [PATCH 13/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E8=87=AA=E8=BA=AB?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E9=9D=9E=E7=A7=BB=E5=8A=A8=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: Ib21c49958e74e1d5f31d602a0a1172825ff30f95 --- .../pattern/text_field/text_field_pattern.cpp | 8 +++++++- .../pattern/text_field/text_select_controller.cpp | 8 ++++++++ .../pattern/text_field/text_select_controller.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index ab967ff82d1..8331e3e64cc 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1178,6 +1178,8 @@ std::function&, const std::strin pattern->textFieldContentModifier_->ChangeDragStatus(); auto contentController = pattern->contentController_; auto selectController = pattern->selectController_; + pattern->dragTextStart_ = selectController->GetStartIndex(); + pattern->dragTextEnd_ = selectController->GetEndIndex(); std::string beforeStr = contentController->GetValueBeforeIndex(selectController->GetStartIndex()); std::string selectedStr = contentController->GetSelectedValue(selectController->GetStartIndex(), selectController->GetEndIndex()); @@ -3586,6 +3588,8 @@ bool TextFieldPattern::OnBackPressed() } LOGI("Closing keyboard on back press"); + selectController_->ResetHandles(); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); CloseKeyboard(true); #if defined(ANDROID_PLATFORM) return false; @@ -4868,7 +4872,9 @@ bool TextFieldPattern::NeedPaintSelect() RefPtr TextFieldPattern::GetFocusHub() const { - auto focusHub = GetHost()->GetOrCreateFocusHub(); + auto host = GetHost(); + CHECK_NULL_RETURN(host, nullptr); + auto focusHub = host->GetOrCreateFocusHub(); return focusHub; } diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 1d11919e9cc..2c78409175f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -413,4 +413,12 @@ void TextSelectController::UpdateRecordCaretIndex(int32_t index) const CHECK_NULL_VOID(textFiled); textFiled->UpdateRecordCaretIndex(index); } + +void TextSelectController::ResetHandles() +{ + firstHandleInfo_.index = caretInfo_.index; + secondHandleInfo_.index = caretInfo_.index; + UpdateFirstHandleOffset(); + UpdateSecondHandleOffset(); +} } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h index 82ebbc65c04..6e261eeda1e 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -167,6 +167,7 @@ public: return caretInfo_; } + void ResetHandles(); void UpdateHandleIndex(int32_t firstHandleIndex, int32_t secondHandleIndex); void UpdateCaretIndex(int32_t index); void UpdateCaretInfoByOffset(const Offset& localOffset); -- Gitee From 57ef5b24b95f04153ffb410f359e6b00bcfb7dd6 Mon Sep 17 00:00:00 2001 From: lijuan Date: Fri, 20 Oct 2023 09:31:45 +0000 Subject: [PATCH 14/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=85=E8=81=94?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=85=89=E6=A0=87=E9=83=A8=E5=88=86=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I8c29ccac121d60bd4cb6bd0883ae105b8c2aa983 --- .../pattern/text_field/text_field_pattern.cpp | 13 ++++++++----- .../pattern/text_field/text_select_controller.cpp | 5 ++--- .../components_ng/render/adapter/txt_paragraph.cpp | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 8331e3e64cc..86176b54e0a 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1613,8 +1613,11 @@ void TextFieldPattern::OnModifyDone() lastTextRectY_ = textRect_.GetY(); } ProcessInnerPadding(); - textRect_.SetLeft(GetPaddingLeft() + GetBorderLeft()); - textRect_.SetTop(GetPaddingTop() + GetBorderTop()); + // The textRect position can't be changed by only redraw. + if (CheckNeedMeasure(layoutProperty->GetPropertyChangeFlag())) { + textRect_.SetLeft(GetPaddingLeft() + GetBorderLeft()); + textRect_.SetTop(GetPaddingTop() + GetBorderTop()); + } CalculateDefaultCursor(); if (renderContext->HasBackgroundColor()) { paintProperty->UpdateBackgroundColor(renderContext->GetBackgroundColorValue()); @@ -1661,6 +1664,7 @@ void TextFieldPattern::OnModifyDone() } } else { SetAxis(Axis::HORIZONTAL); + SetScrollBar(DisplayMode::OFF); if (!GetScrollableEvent()) { AddScrollEvent(); SetScrollEnable(false); @@ -2063,10 +2067,10 @@ void TextFieldPattern::OnHandleMove(const RectF& handleRect, bool isFirstHandle) CHECK_NULL_VOID(SelectOverlayIsOn()); CHECK_NULL_VOID(!contentController_->IsEmpty()); auto localOffset = handleRect.GetOffset() - parentGlobalOffset_; - auto position = UpdateCaretPositionOnHandleMove(localOffset); if (isSingleHandle_) { - selectController_->MoveCaretToContentRect(position); + selectController_->UpdateCaretInfoByOffset(Offset(localOffset.GetX(), localOffset.GetY())); } else { + auto position = UpdateCaretPositionOnHandleMove(localOffset); if (isFirstHandle) { selectController_->MoveFirstHandleToContentRect(position); auto proxy = GetSelectOverlayProxy(); @@ -2261,7 +2265,6 @@ void TextFieldPattern::HandleMouseEvent(MouseInfo& info) pipeline->ChangeMouseStyle(frameId, MouseFormat::DEFAULT); return; } - pipeline->ChangeMouseStyle(frameId, MouseFormat::TEXT_CURSOR); isUsingMouse_ = true; if (info.GetButton() == MouseButton::RIGHT_BUTTON) { HandleRightMouseEvent(info); diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 2c78409175f..91bbbcd09a5 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -106,8 +106,6 @@ void TextSelectController::UpdateCaretRectByPositionNearTouchOffset(int32_t posi CalcCaretMetricsByPositionNearTouchOffset(position, caretMetrics, OffsetF(static_cast(touchOffset.GetX()), static_cast(touchOffset.GetY()))); - CaretMetricsF CaretMetrics; - paragraph_->CalcCaretMetricsByPosition(position, CaretMetrics, TextAffinity::UPSTREAM); caretInfo_.UpdateOffset(caretMetrics.offset); UpdateCaretHeight(caretMetrics.height); } @@ -118,7 +116,8 @@ void TextSelectController::UpdateCaretInfoByOffset(const Offset& localOffset) UpdateCaretIndex(index); if (!contentController_->IsEmpty()) { UpdateCaretRectByPositionNearTouchOffset(index, localOffset); - MoveCaretToContentRect(GetCaretIndex()); + MoveHandleToContentRect(caretInfo_.rect); + UpdateRecordCaretIndex(caretInfo_.index); } else { caretInfo_.rect = CalculateEmptyValueCaretRect(); } diff --git a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp index 69320b89b8a..738e42ef73b 100644 --- a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp +++ b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp @@ -509,7 +509,7 @@ bool TxtParagraph::CalcCaretMetricsByPosition( auto downStreamSuccess = ComputeOffsetForCaretDownstream(extent, metricsDownstream); auto upStreamSuccess = ComputeOffsetForCaretUpstream(extent, metricsUpstream); if (downStreamSuccess || upStreamSuccess) { - if (metricsDownstream.offset.GetY() < lastTouchOffset.GetY() && downStreamSuccess) { + if ((metricsDownstream.offset.GetY() < lastTouchOffset.GetY()) && downStreamSuccess) { caretCaretMetric = metricsDownstream; } else if (upStreamSuccess) { caretCaretMetric = metricsUpstream; -- Gitee From ffe14295ef286c3fc695abe9e3d9a4c0741196c9 Mon Sep 17 00:00:00 2001 From: wangtao Date: Fri, 20 Oct 2023 09:17:13 +0000 Subject: [PATCH 15/31] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E7=A9=BA=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E5=8D=95=E6=89=8B=E6=9F=84=E6=98=BE=E7=A4=BA=E6=8C=89?= =?UTF-8?q?=E9=92=AE=202.=E4=BF=AE=E6=94=B9=E5=8D=95=E6=89=8B=E6=9F=84?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E4=BD=8D=E7=BD=AE=E5=BC=82=E5=B8=B8=203.?= =?UTF-8?q?=E7=82=B9=E5=87=BB=E6=8B=89=E8=B5=B7=E8=BE=93=E5=85=A5=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: I2f2f674cfbeb1fbdc5942ce53648941e5596e830 --- .../select_overlay/select_overlay_client.cpp | 2 +- .../select_overlay_layout_algorithm.cpp | 1 + .../pattern/text_field/text_field_pattern.cpp | 40 +++++++++---------- .../pattern/text_field/text_field_pattern.h | 1 + 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp index d507ea89652..8218e72e202 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -138,7 +138,7 @@ void SelectOverlayClient::UpdateShowingSelectOverlay(const ClientOverlayInfo& cl if (hasRequestSingleHandle) { proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { menuInfo.showPaste = newMenuInfo.showPaste; - menuInfo.showCopyAll = true; + menuInfo.showCopyAll = newMenuInfo.showCopyAll; }); proxy->UpdateSecondSelectHandleInfo(selectOverlayInfo->secondHandle); } else { diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp index baa1d1c15b3..8f30ab5db65 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp @@ -177,6 +177,7 @@ OffsetF SelectOverlayLayoutAlgorithm::ComputeSelectMenuPosition(LayoutWrapper* l } else { menuPosition.SetY( static_cast(singleHandle.Bottom() + menuSpacingBetweenText + menuSpacingBetweenHandle)); + menuSpacing = static_cast(menuSpacingBetweenText + menuSpacingBetweenHandle); } } if (LessNotEqual(menuPosition.GetY(), viewPort.GetY() - menuSpacingBetweenText - menuHeight) || diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 86176b54e0a..4caefe9335d 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -572,9 +572,7 @@ void TextFieldPattern::HandleFocusEvent() } else { StartTwinkling(); } - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); + NotifyOnEditChanged(true); auto visible = layoutProperty->GetShowErrorTextValue(false); if (!visible && layoutProperty->GetShowUnderlineValue(false) && IsUnspecifiedOrTextType()) { auto renderContext = host->GetRenderContext(); @@ -757,8 +755,7 @@ void TextFieldPattern::HandleBlurEvent() StopTwinkling(); CloseKeyboard(true); selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); - auto eventHub = host->GetEventHub(); - eventHub->FireOnEditChanged(false); + NotifyOnEditChanged(false); host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -1428,7 +1425,9 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) } else { CloseSelectOverlay(true); } - needToRequestKeyboardInner_ = true; + if (RequestKeyboard(false, true, true)) { + NotifyOnEditChanged(true); + } host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -2351,10 +2350,8 @@ void TextFieldPattern::HandleLeftMouseReleaseEvent(MouseInfo& info) mouseStatus_ = MouseStatus::NONE; blockPress_ = false; leftMouseCanMove_ = false; - auto eventHub = GetHost()->GetEventHub(); - CHECK_NULL_VOID(eventHub); if (HasFocus() && RequestKeyboard(false, true, true)) { - eventHub->FireOnEditChanged(true); + NotifyOnEditChanged(true); GetHost()->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } } @@ -3193,9 +3190,7 @@ void TextFieldPattern::RequestKeyboardOnFocus() if (!RequestKeyboard(false, true, true)) { return; } - auto eventHub = GetHost()->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); + NotifyOnEditChanged(true); needToRequestKeyboardInner_ = false; } @@ -3863,11 +3858,7 @@ void TextFieldPattern::SearchRequestKeyboard() StartTwinkling(); selectionMode_ = SelectionMode::NONE; if (RequestKeyboard(false, true, true)) { - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto eventHub = tmpHost->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(true); + NotifyOnEditChanged(true); } } @@ -4668,11 +4659,7 @@ void TextFieldPattern::StopEditing() #else if (isCustomKeyboardAttached_) { #endif - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto eventHub = host->GetEventHub(); - CHECK_NULL_VOID(eventHub); - eventHub->FireOnEditChanged(false); + NotifyOnEditChanged(false); } UpdateSelection(selectController_->GetCaretIndex()); StopTwinkling(); @@ -4906,4 +4893,13 @@ void TextFieldPattern::CreateHandles() { ProcessOverlay(false, false); } + +void TextFieldPattern::NotifyOnEditChanged(bool isChanged) +{ + auto host = GetHost(); + CHECK_NULL_VOID(host); + auto eventHub = host->GetEventHub(); + CHECK_NULL_VOID(eventHub); + eventHub->FireOnEditChanged(isChanged); +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index c39d824e5a1..5c66619826b 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -1096,6 +1096,7 @@ private: { isSingleHandle_ = isSingleHandle; } + void NotifyOnEditChanged(bool isChanged); RectF frameRect_; RectF contentRect_; -- Gitee From c938c7491c204b9e1836f34e28622fa01ab52e65 Mon Sep 17 00:00:00 2001 From: wangtao Date: Sat, 21 Oct 2023 07:08:24 +0000 Subject: [PATCH 16/31] =?UTF-8?q?=E7=9B=91=E5=90=AC=E7=88=B6=E5=AE=B9?= =?UTF-8?q?=E5=99=A8=E6=BB=9A=E5=8A=A8=E4=BA=8B=E4=BB=B6=EF=BC=8C=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=89=8B=E6=9F=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: I8cb705958d190c74e6fe3ecd08b48921650bf957 --- .../select_overlay/select_overlay_client.cpp | 78 +++++++----- .../select_overlay/select_overlay_client.h | 14 +-- .../select_overlay/select_overlay_manager.cpp | 8 +- .../select_overlay/select_overlay_manager.h | 8 +- .../select_overlay_scroll_notifier.h | 17 ++- .../pattern/text_field/text_field_pattern.cpp | 112 +++++++++++------- .../pattern/text_field/text_field_pattern.h | 20 +++- 7 files changed, 159 insertions(+), 98 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp index 8218e72e202..c2f218fedec 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -73,9 +73,9 @@ void SelectOverlayClient::InitSelectOverlay() selectOverlayInfo_.secondHandle.isShow = false; } -void SelectOverlayClient::RequestOpenSelectOverlay(const ClientOverlayInfo& showOverlayInfo) +void SelectOverlayClient::RequestOpenSelectOverlay(ClientOverlayInfo& showOverlayInfo) { - LOGI("RequestOpenSelectOverlay start, has first handle %{public}d, has second handle %{public}d", + LOGI("first handle %{public}d, second handle %{public}d", showOverlayInfo.firstHandleInfo.has_value(), showOverlayInfo.secondHandleInfo.has_value()); if (SelectOverlayIsOn()) { UpdateShowingSelectOverlay(showOverlayInfo); @@ -90,12 +90,13 @@ void SelectOverlayClient::CreateSelectOverlay(const ClientOverlayInfo& clientOve CHECK_NULL_VOID(pipeline); auto overlayInfo = GetSelectOverlayInfo(clientOverlayInfo); CHECK_NULL_VOID(overlayInfo); - LOGD("first handle visibility %{public}d, second handle visibility %{public}d, select rect visibility " - "%{public}d", - overlayInfo.firstHandle.isShow, overlayInfo.secondHandle.isShow, overlayInfo.isSelectRegionVisible); + LOGI("first handle %{public}d, second handle %{public}d, select rect %{public}d", overlayInfo->firstHandle.isShow, + overlayInfo->secondHandle.isShow, overlayInfo->isSelectRegionVisible); selectOverlayProxy_ = pipeline->GetSelectOverlayManager()->CreateAndShowSelectOverlay( *overlayInfo, WeakClaim(this), clientOverlayInfo.animation); - StartListeningScrollableParent(GetClientHost()); + if (!overlayInfo->isUsingMouse) { + StartListeningScrollableParent(GetClientHost()); + } } std::optional SelectOverlayClient::GetSelectOverlayInfo(const ClientOverlayInfo& clientInfo) @@ -113,6 +114,9 @@ std::optional SelectOverlayClient::GetSelectOverlayInfo(const overlayInfo.secondHandle = secondHandleInfo.has_value() ? *secondHandleInfo : overlayInfo.secondHandle; overlayInfo.isSingleHandle = !firstHandleInfo && secondHandleInfo; overlayInfo.isSelectRegionVisible = CheckSelectionRectVisible(); + if (!clientInfo.isUpdateMenu) { + return overlayInfo; + } if (!GetMenuOptionItems().empty()) { overlayInfo.menuOptionItems = GetMenuOptionItems(); } @@ -122,12 +126,14 @@ std::optional SelectOverlayClient::GetSelectOverlayInfo(const return std::nullopt; } -void SelectOverlayClient::UpdateShowingSelectOverlay(const ClientOverlayInfo& clientInfo) +void SelectOverlayClient::UpdateShowingSelectOverlay(ClientOverlayInfo& clientInfo) { + LOGI("update select overlay, isUseMouse %{public}d", clientInfo.isShowMouseMenu); auto isCurrentSingleHandle = IsShowingSingleHandle(); auto hasRequestSingleHandle = !clientInfo.firstHandleInfo && clientInfo.secondHandleInfo; if (clientInfo.isShowMouseMenu || isCurrentSingleHandle ^ hasRequestSingleHandle) { RequestCloseSelectOverlay(true); + clientInfo.isUpdateMenu = true; CreateSelectOverlay(clientInfo); return; } @@ -136,18 +142,22 @@ void SelectOverlayClient::UpdateShowingSelectOverlay(const ClientOverlayInfo& cl auto proxy = GetSelectOverlayProxy(); CHECK_NULL_VOID(proxy); if (hasRequestSingleHandle) { - proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { - menuInfo.showPaste = newMenuInfo.showPaste; - menuInfo.showCopyAll = newMenuInfo.showCopyAll; - }); + if (clientInfo.isUpdateMenu) { + proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { + menuInfo.showPaste = newMenuInfo.showPaste; + menuInfo.showCopyAll = newMenuInfo.showCopyAll; + }); + } proxy->UpdateSecondSelectHandleInfo(selectOverlayInfo->secondHandle); } else { - proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { - menuInfo.showPaste = newMenuInfo.showPaste; - menuInfo.showCopyAll = newMenuInfo.showCopyAll; - menuInfo.showCopy = newMenuInfo.showCopy; - menuInfo.showCut = newMenuInfo.showCut; - }); + if (clientInfo.isUpdateMenu) { + proxy->UpdateSelectMenuInfo([newMenuInfo = selectOverlayInfo->menuInfo](SelectMenuInfo& menuInfo) { + menuInfo.showPaste = newMenuInfo.showPaste; + menuInfo.showCopyAll = newMenuInfo.showCopyAll; + menuInfo.showCopy = newMenuInfo.showCopy; + menuInfo.showCut = newMenuInfo.showCut; + }); + } proxy->UpdateFirstAndSecondHandleInfo(selectOverlayInfo->firstHandle, selectOverlayInfo->secondHandle); } } @@ -199,16 +209,6 @@ void SelectOverlayClient::StartListeningScrollableParent(const RefPtr CHECK_NULL_VOID(host); auto context = host->GetContext(); CHECK_NULL_VOID(context); - auto registerScrollCallback = [&](int32_t parentId, int32_t callbackId) { - if (!scrollCallback_) { - scrollCallback_ = [weak = WeakClaim(this)](bool isEnd) { - auto client = weak.Upgrade(); - CHECK_NULL_VOID(client); - client->OnParentScrollCallback(isEnd); - }; - } - context->GetSelectOverlayManager()->RegisterScrollCallback(parentId, callbackId, std::move(scrollCallback_)); - }; if (scrollableParentInfo_.parentIds.empty()) { auto parent = host->GetParent(); while (parent && parent->GetTag() != V2::PAGE_ETS_TAG) { @@ -217,7 +217,7 @@ void SelectOverlayClient::StartListeningScrollableParent(const RefPtr auto pattern = parentNode->GetPattern(); if (pattern) { scrollableParentInfo_.parentIds.emplace_back(parentNode->GetId()); - registerScrollCallback(parentNode->GetId(), host->GetId()); + RegisterParentScrollCallback(parentNode->GetId(), host->GetId()); } } parent = parent->GetParent(); @@ -226,11 +226,31 @@ void SelectOverlayClient::StartListeningScrollableParent(const RefPtr LOGI("find scrollable parent %{public}d", scrollableParentInfo_.hasParent); } else { for (const auto& scrollId : scrollableParentInfo_.parentIds) { - registerScrollCallback(scrollId, host->GetId()); + RegisterParentScrollCallback(scrollId, host->GetId()); } } } +void SelectOverlayClient::RegisterParentScrollCallback(int32_t parentId, int32_t callbackId) +{ + auto host = GetClientHost(); + CHECK_NULL_VOID(host); + auto context = host->GetContext(); + CHECK_NULL_VOID(context); + auto scrollCallback = [weak = WeakClaim(this)](Axis axis, bool offset, int32_t source) { + auto client = weak.Upgrade(); + CHECK_NULL_VOID(client); + if (source == SCROLL_FROM_START) { + client->OnParentScrollStartOrEnd(false); + } else if (source == -1) { + client->OnParentScrollStartOrEnd(true); + } else { + client->OnParentScrollCallback(axis, offset); + } + }; + context->GetSelectOverlayManager()->RegisterScrollCallback(parentId, callbackId, scrollCallback); +} + void SelectOverlayClient::StopListeningScrollableParent(const RefPtr& host) { CHECK_NULL_VOID(host); diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h index c97b7628004..85dced50bea 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h @@ -33,8 +33,6 @@ namespace OHOS::Ace::NG { enum class HandleShowMode { DOUBLE, SINGLE, NONE }; -using ParentScrollableCallback = std::function; - struct OverlayExtraInfo { std::map boolExtra; @@ -55,7 +53,7 @@ struct ClientOverlayInfo { bool isMenuShow = true; bool isShowMouseMenu = false; bool isShowPaste = false; - OverlayExtraInfo extraInfo; + bool isUpdateMenu = true; }; struct ScrollableParentInfo { @@ -75,7 +73,7 @@ class SelectOverlayClient : public SelectionHost { public: void InitSelectOverlay(); - void RequestOpenSelectOverlay(const ClientOverlayInfo& overlayInfo); + void RequestOpenSelectOverlay(ClientOverlayInfo& overlayInfo); virtual void RequestCloseSelectOverlay(bool animation); bool SelectOverlayIsOn(); @@ -119,7 +117,7 @@ public: return std::move(menuOptionItems_); } - virtual void OnParentScrollCallback(bool isEnd) + virtual void OnParentScrollStartOrEnd(bool isEnd) { auto proxy = GetSelectOverlayProxy(); CHECK_NULL_VOID(proxy); @@ -130,6 +128,8 @@ public: } } + virtual void OnParentScrollCallback(Axis axis, int32_t offset) {}; + void StartListeningScrollableParent(const RefPtr& host); void StopListeningScrollableParent(const RefPtr& host); @@ -158,10 +158,10 @@ protected: } private: + void RegisterParentScrollCallback(int32_t parentId, int32_t callbackId); std::optional GetSelectOverlayInfo(const ClientOverlayInfo& clientInfo); void CreateSelectOverlay(const ClientOverlayInfo& showOverlayInfo); - void UpdateShowingSelectOverlay(const ClientOverlayInfo& clientInfo); - ParentScrollableCallback scrollCallback_; + void UpdateShowingSelectOverlay(ClientOverlayInfo& clientInfo); ScrollableParentInfo scrollableParentInfo_; SelectOverlayInfo selectOverlayInfo_; RefPtr selectOverlayProxy_; diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp index 365cb39ae1f..e547cca6ecf 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.cpp @@ -339,7 +339,7 @@ void SelectOverlayManager::MarkDirty(PropertyChangeFlag flag) } } -void SelectOverlayManager::NotifyOnScrollCallback(int32_t id, bool isEnd) +void SelectOverlayManager::NotifyOnScrollCallback(int32_t id, Axis axis, float offset, int32_t source) { LOGI("NotifyOnScrollCallback scroll id %{public}d", id); if (parentScrollCallbacks_.empty()) { @@ -355,17 +355,17 @@ void SelectOverlayManager::NotifyOnScrollCallback(int32_t id, bool isEnd) return; } for (const auto& pair : callbackMap) { - pair.second(isEnd); + pair.second(axis, offset, source); } } void SelectOverlayManager::RegisterScrollCallback( - int32_t scrollableParentId, int32_t callbackId, std::function&& callback) + int32_t scrollableParentId, int32_t callbackId, ScrollableParentCallback&& callback) { LOGI("RegisterScrollCallback scroll parent id %{public}d, callbackId %{public}d", scrollableParentId, callbackId); auto it = parentScrollCallbacks_.find(scrollableParentId); if (it == parentScrollCallbacks_.end()) { - std::map> callbackMap = { { callbackId, std::move(callback) } }; + std::map callbackMap = { { callbackId, std::move(callback) } }; parentScrollCallbacks_.insert(std::make_pair(scrollableParentId, callbackMap)); } else { it->second.insert(std::make_pair(callbackId, std::move(callback))); diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h index 92edbdaef88..4b5adb69193 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_manager.h @@ -32,6 +32,8 @@ namespace OHOS::Ace::NG { +using ScrollableParentCallback = std::function; + // SelectOverlayManager is the class to show and control select handle and select menu. class ACE_EXPORT SelectOverlayManager : public virtual AceType { DECLARE_ACE_TYPE(SelectOverlayManager, AceType); @@ -73,9 +75,9 @@ public: return selectOverlayItem_; } - void NotifyOnScrollCallback(int32_t id, bool isEnd); + void NotifyOnScrollCallback(int32_t id, Axis axis, float offset, int32_t source); - void RegisterScrollCallback(int32_t scrollableParentId, int32_t callbackId, std::function&& callback); + void RegisterScrollCallback(int32_t scrollableParentId, int32_t callbackId, ScrollableParentCallback&& callback); void RemoveScrollCallback(int32_t callbackId); @@ -100,7 +102,7 @@ private: std::vector touchDownPoints_; std::vector touchTestResults_; - std::map>> parentScrollCallbacks_; + std::map> parentScrollCallbacks_; ACE_DISALLOW_COPY_AND_MOVE(SelectOverlayManager); }; diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h index 88d0ac410b9..acfdec96cca 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h @@ -16,7 +16,7 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_SCROLL_NOTIFIER_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_SCROLL_NOTIFIER_H -#include "core/components_ng/pattern/pattern.h" +#include "core/components_ng/pattern/scrollable/scrollable_pattern.h" #include "core/components_ng/pattern/scrollable/scrollable_properties.h" #include "core/pipeline_ng/pipeline_context.h" @@ -24,19 +24,17 @@ namespace OHOS::Ace::NG { class SelectOverlayScrollNotifier { public: - static inline void NotifyOnScrollCallback(WeakPtr pattern, float offset, int32_t source) + static inline void NotifyOnScrollCallback(WeakPtr pattern, float offset, int32_t source) { - if (source == SCROLL_FROM_START) { - NotifyOnScrollEvent(pattern, false); - } + NotifyOnScrollEvent(pattern, offset, source); } - static inline void NotifyOnScrollEnd(WeakPtr pattern) + static inline void NotifyOnScrollEnd(WeakPtr pattern) { - NotifyOnScrollEvent(pattern, true); + NotifyOnScrollEvent(pattern, 0, -1); } - static inline void NotifyOnScrollEvent(WeakPtr pattern, bool isEnd) + static inline void NotifyOnScrollEvent(WeakPtr pattern, float offset, int32_t source) { auto scrollablePattern = pattern.Upgrade(); CHECK_NULL_VOID(scrollablePattern); @@ -44,7 +42,8 @@ public: CHECK_NULL_VOID(host); auto context = host->GetContext(); CHECK_NULL_VOID(context); - context->GetSelectOverlayManager()->NotifyOnScrollCallback(host->GetId(), isEnd); + context->GetSelectOverlayManager()->NotifyOnScrollCallback( + host->GetId(), scrollablePattern->GetAxis(), offset, source); } }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 4caefe9335d..ff46e97bb8b 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -853,7 +853,7 @@ void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) CloseSelectOverlay(true); return; } - ProcessOverlay(true); + ProcessOverlay(true, true); } void TextFieldPattern::HandleOnCopy() @@ -1421,7 +1421,7 @@ void TextFieldPattern::HandleSingleClickEvent(GestureEvent& info) SetIsSingleHandle(true); if (lastCaretIndex == selectController_->GetCaretIndex() && hasFocus && caretStatus_ == CaretStatus::SHOW && info.GetSourceDevice() != SourceType::MOUSE) { - ProcessOverlay(true); + ProcessOverlay(true, true); } else { CloseSelectOverlay(true); } @@ -1439,7 +1439,7 @@ void TextFieldPattern::HandleDoubleClickEvent(GestureEvent& info) SetIsSingleHandle(false); } if (info.GetSourceDevice() != SourceType::MOUSE) { - ProcessOverlay(true); + ProcessOverlay(true, true); } auto host = GetHost(); CHECK_NULL_VOID(host); @@ -1862,7 +1862,7 @@ void TextFieldPattern::HandleLongPress(GestureEvent& info) StopTwinkling(); } SetIsSingleHandle(!IsSelected()); - ProcessOverlay(true); + ProcessOverlay(true, true); host->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -1872,56 +1872,73 @@ void TextFieldPattern::UpdateCaretPositionWithClamp(const int32_t& pos) std::clamp(pos, 0, static_cast(contentController_->GetWideText().length()))); } -void TextFieldPattern::ProcessOverlay(bool animation, bool isShowMenu) +void TextFieldPattern::ProcessOverlay(bool isUpdateMenu, bool animation, bool isShowMenu) { selectController_->CalculateHandleOffset(); + ShowSelectOverlayParams showOverlayParams = { .animation = animation, .isShowMenu = isShowMenu, + .isUpdateMenu = isUpdateMenu }; if (isSingleHandle_) { StartTwinkling(); LOGD("Show single handle Handle info %{public}s", selectController_->GetCaretRect().ToString().c_str()); - ShowSelectOverlay(std::nullopt, selectController_->GetCaretRect(), animation, isShowMenu); + showOverlayParams.firstHandle = std::nullopt; + showOverlayParams.secondHandle = selectController_->GetCaretRect(); + ShowSelectOverlay(showOverlayParams); } else { LOGD("Show handles firstHandle info %{public}s, secondHandle Info %{public}s", selectController_->GetFirstHandleRect().ToString().c_str(), selectController_->GetSecondHandleRect().ToString().c_str()); - ShowSelectOverlay( - selectController_->GetFirstHandleRect(), selectController_->GetSecondHandleRect(), animation, isShowMenu); + showOverlayParams.firstHandle = selectController_->GetFirstHandleRect(); + showOverlayParams.secondHandle = selectController_->GetSecondHandleRect(); + ShowSelectOverlay(showOverlayParams); } } -void TextFieldPattern::ShowSelectOverlay( - const std::optional& firstHandle, const std::optional& secondHandle, bool animation, bool isMenuShow) +void TextFieldPattern::ShowSelectOverlay(const ShowSelectOverlayParams& showOverlayParams) { if (isTransparent_) { return; } - auto hasDataCallback = [weak = WeakClaim(this), firstHandle, secondHandle, animation, isMenuShow](bool hasData) { + auto hasDataCallback = [weak = WeakClaim(this), params = showOverlayParams](bool hasData) { LOGI("HasData callback from clipboard, data available ? %{public}d", hasData); auto pattern = weak.Upgrade(); CHECK_NULL_VOID(pattern); - ClientOverlayInfo overlayInfo = { .animation = animation, .isMenuShow = isMenuShow }; - if (firstHandle.has_value()) { - auto handle = firstHandle.value(); - handle.SetOffset(handle.GetOffset() + pattern->GetTextPaintOffset()); - SelectHandleInfo firstHandleInfo; - firstHandleInfo.paintRect = handle; - overlayInfo.firstHandleInfo = firstHandleInfo; - } - if (secondHandle.has_value()) { - auto handle = secondHandle.value(); - handle.SetOffset(handle.GetOffset() + pattern->GetTextPaintOffset()); - SelectHandleInfo secondHandleInfo; - secondHandleInfo.paintRect = handle; - overlayInfo.secondHandleInfo = secondHandleInfo; - } - overlayInfo.isShowPaste = hasData; - overlayInfo.isMenuShow = isMenuShow; - overlayInfo.isShowMouseMenu = pattern->IsUsingMouse(); - pattern->RequestOpenSelectOverlay(overlayInfo); - auto start = pattern->GetTextSelectController()->GetStartIndex(); - auto end = pattern->GetTextSelectController()->GetEndIndex(); - pattern->UpdateSelectInfo(pattern->contentController_->GetSelectedValue(start, end)); + pattern->StartRequestSelectOverlay(params, hasData); + }; + if (showOverlayParams.isUpdateMenu) { + clipboard_->HasData(hasDataCallback); + } else { + StartRequestSelectOverlay(showOverlayParams); + } +} + +void TextFieldPattern::StartRequestSelectOverlay(const ShowSelectOverlayParams& params, bool isShowPaste) +{ + ClientOverlayInfo overlayInfo = { + .animation = params.animation, + .isMenuShow = params.isShowMenu, + .isUpdateMenu = params.isUpdateMenu }; - clipboard_->HasData(hasDataCallback); + if (params.firstHandle.has_value()) { + auto handle = params.firstHandle.value(); + handle.SetOffset(handle.GetOffset() + GetTextPaintOffset()); + SelectHandleInfo firstHandleInfo; + firstHandleInfo.paintRect = handle; + overlayInfo.firstHandleInfo = firstHandleInfo; + } + if (params.secondHandle.has_value()) { + auto handle = params.secondHandle.value(); + handle.SetOffset(handle.GetOffset() + GetTextPaintOffset()); + SelectHandleInfo secondHandleInfo; + secondHandleInfo.paintRect = handle; + overlayInfo.secondHandleInfo = secondHandleInfo; + } + overlayInfo.isShowPaste = isShowPaste; + overlayInfo.isMenuShow = params.isShowMenu; + overlayInfo.isShowMouseMenu = IsUsingMouse(); + RequestOpenSelectOverlay(overlayInfo); + auto start = GetTextSelectController()->GetStartIndex(); + auto end = GetTextSelectController()->GetEndIndex(); + UpdateSelectInfo(contentController_->GetSelectedValue(start, end)); } bool TextFieldPattern::OnPreShowSelectOverlay( @@ -3164,10 +3181,24 @@ void TextFieldPattern::OnValueChanged(bool needFireChangeEvent, bool needFireSel void TextFieldPattern::OnAreaChangedInner() { - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto context = PipelineContext::GetCurrentContext(); - CHECK_NULL_VOID(context); + RequestKeyboardOnFocus(); +} + +void TextFieldPattern::OnParentScrollCallback(Axis axis, int32_t offset) +{ + ProcessOverlayWhenParentScrolls(); +} + +void TextFieldPattern::OnParentScrollStartOrEnd(bool isEnd) +{ + SelectOverlayClient::OnParentScrollStartOrEnd(isEnd); + if (isEnd) { + ProcessOverlayWhenParentScrolls(); + } +} + +void TextFieldPattern::ProcessOverlayWhenParentScrolls() +{ auto parentGlobalOffset = GetTextPaintOffset(); if (parentGlobalOffset != parentGlobalOffset_) { parentGlobalOffset_ = parentGlobalOffset; @@ -3175,10 +3206,9 @@ void TextFieldPattern::OnAreaChangedInner() selectController_->UpdateCaretOffset(); selectController_->CalculateHandleOffset(); if (SelectOverlayIsOn()) { - ProcessOverlay(); + ProcessOverlay(false); } } - RequestKeyboardOnFocus(); } void TextFieldPattern::RequestKeyboardOnFocus() @@ -4891,7 +4921,7 @@ void TextFieldPattern::OnObscuredChanged(bool isObscured) void TextFieldPattern::CreateHandles() { - ProcessOverlay(false, false); + ProcessOverlay(true, false, false); } void TextFieldPattern::NotifyOnEditChanged(bool isChanged) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 5c66619826b..accfa73830e 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -129,6 +129,14 @@ struct PreInlineState { bool hasBorderColor = false; }; +struct ShowSelectOverlayParams { + std::optional firstHandle; + std::optional secondHandle; + bool animation = false; + bool isShowMenu = true; + bool isUpdateMenu = true; +}; + class TextFieldPattern : public ScrollablePattern, public TextDragBase, public ValueChangeObserver, @@ -936,6 +944,9 @@ public: bool CheckSelectionRectVisible() override; bool OnPreShowSelectOverlay( SelectOverlayInfo& overlayInfo, const ClientOverlayInfo& clientInfo, bool isSelectOverlayOn) override; + void OnObscuredChanged(bool isObscured); + void OnParentScrollCallback(Axis axis, int32_t offset) override; + void OnParentScrollStartOrEnd(bool isEnd) override; void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) override { switch (menuId) { @@ -959,8 +970,6 @@ public: return GetHost(); } - void OnObscuredChanged(bool isObscured); - void SetResponseArea(const RefPtr& responseArea) { if (responseArea_) { @@ -1012,13 +1021,12 @@ private: void HandleLeftMouseReleaseEvent(MouseInfo& info); void HandleLongPress(GestureEvent& info); void UpdateCaretPositionWithClamp(const int32_t& pos); - void ShowSelectOverlay(const std::optional& firstHandle, const std::optional& secondHandle, - bool animation = false, bool isMenuShow = true); + void ShowSelectOverlay(const ShowSelectOverlayParams& params); void CursorMoveOnClick(const Offset& offset); void UpdateCaretInfoToController() const; - void ProcessOverlay(bool animation = false, bool isShowMenu = true); + void ProcessOverlay(bool isUpdateMenu = true, bool animation = false, bool isShowMenu = true); SelectHandleInfo GetSelectHandleInfo(OffsetF info); void UpdateFirstHandlePosition(bool needLayout = false); void UpdateSecondHandlePosition(bool needLayout = false); @@ -1097,6 +1105,8 @@ private: isSingleHandle_ = isSingleHandle; } void NotifyOnEditChanged(bool isChanged); + void ProcessOverlayWhenParentScrolls(); + void StartRequestSelectOverlay(const ShowSelectOverlayParams& params, bool isShowPaste = false); RectF frameRect_; RectF contentRect_; -- Gitee From aabfbb6ccbc786558560c3c08a9a0c26112a49fa Mon Sep 17 00:00:00 2001 From: wangtao Date: Sat, 21 Oct 2023 07:54:12 +0000 Subject: [PATCH 17/31] =?UTF-8?q?=E5=9B=9E=E9=80=80OnAreaChangedInner?= =?UTF-8?q?=E7=9A=84=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: I31005f4fc28693667134537b19b170fb62bf5e69 --- .../pattern/text_field/text_field_pattern.cpp | 19 +----------- .../pattern/text_field/text_field_pattern.h | 3 -- .../text_field/text_input_response_area.cpp | 31 ++++++++++++++++--- .../text_field/text_input_response_area.h | 1 + 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index ff46e97bb8b..37b2c5a8a35 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -3180,24 +3180,6 @@ void TextFieldPattern::UpdateInputFilterErrorText(const std::string& errorText) void TextFieldPattern::OnValueChanged(bool needFireChangeEvent, bool needFireSelectChangeEvent) {} void TextFieldPattern::OnAreaChangedInner() -{ - RequestKeyboardOnFocus(); -} - -void TextFieldPattern::OnParentScrollCallback(Axis axis, int32_t offset) -{ - ProcessOverlayWhenParentScrolls(); -} - -void TextFieldPattern::OnParentScrollStartOrEnd(bool isEnd) -{ - SelectOverlayClient::OnParentScrollStartOrEnd(isEnd); - if (isEnd) { - ProcessOverlayWhenParentScrolls(); - } -} - -void TextFieldPattern::ProcessOverlayWhenParentScrolls() { auto parentGlobalOffset = GetTextPaintOffset(); if (parentGlobalOffset != parentGlobalOffset_) { @@ -3209,6 +3191,7 @@ void TextFieldPattern::ProcessOverlayWhenParentScrolls() ProcessOverlay(false); } } + RequestKeyboardOnFocus(); } void TextFieldPattern::RequestKeyboardOnFocus() diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index accfa73830e..527dafe3d77 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -945,8 +945,6 @@ public: bool OnPreShowSelectOverlay( SelectOverlayInfo& overlayInfo, const ClientOverlayInfo& clientInfo, bool isSelectOverlayOn) override; void OnObscuredChanged(bool isObscured); - void OnParentScrollCallback(Axis axis, int32_t offset) override; - void OnParentScrollStartOrEnd(bool isEnd) override; void OnSelectOverlayMenuClicked(SelectOverlayMenuId menuId) override { switch (menuId) { @@ -1105,7 +1103,6 @@ private: isSingleHandle_ = isSingleHandle; } void NotifyOnEditChanged(bool isChanged); - void ProcessOverlayWhenParentScrolls(); void StartRequestSelectOverlay(const ShowSelectOverlayParams& params, bool isShowPaste = false); RectF frameRect_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp index c0fc41bb57e..9c244ba8b83 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -125,6 +125,20 @@ RefPtr PasswordResponseArea::CreateNode() imageLayoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value()); imageLayoutProperty->UpdateImageFit(ImageFit::FILL); imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize))); + auto eventHub = imageNode->GetEventHub(); + CHECK_NULL_RETURN(eventHub, nullptr); + eventHub->SetOnError([ weakNode = WeakClaim(AceType::RawPtr(imageNode)), weakArea = WeakClaim(this) ] + (const LoadImageFailEvent& info) { + auto host = weakNode.Upgrade(); + CHECK_NULL_VOID(host); + auto area = weakArea.Upgrade(); + CHECK_NULL_VOID(area); + auto imagePattern = host->GetPattern(); + CHECK_NULL_VOID(imagePattern); + auto layoutProperty = host->GetLayoutProperty(); + layoutProperty->UpdateImageSourceInfo(area->GetDefaultSourceInfo(area->isObscured_)); + imagePattern->LoadImageDataIfNeed(); + }); imageNode->MarkModifyDone(); imageNode->MountToParent(stackNode); passwordNode_ = imageNode; @@ -214,13 +228,20 @@ void PasswordResponseArea::LoadImageSourceInfo() CHECK_NULL_VOID(textFieldPattern); auto layoutProperty = textFieldPattern->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); + showIcon_ = layoutProperty->GetShowPasswordSourceInfoValue(GetDefaultSourceInfo(false)); + hideIcon_ = layoutProperty->GetHidePasswordSourceInfoValue(GetDefaultSourceInfo(true)); +} + +ImageSourceInfo PasswordResponseArea::GetDefaultSourceInfo(bool isObscured) +{ + if (isObscured) { + ImageSourceInfo hideSystemSourceInfo; + hideSystemSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG); + return hideSystemSourceInfo; + } ImageSourceInfo showSystemSourceInfo; showSystemSourceInfo.SetResourceId(InternalResource::ResourceId::SHOW_PASSWORD_SVG); - showIcon_ = layoutProperty->GetShowPasswordSourceInfoValue(showSystemSourceInfo); - - ImageSourceInfo hideSystemSourceInfo; - hideSystemSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG); - hideIcon_ = layoutProperty->GetHidePasswordSourceInfoValue(hideSystemSourceInfo); + return showSystemSourceInfo; } void PasswordResponseArea::UpdateImageSource() diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h index 7f7aefb628a..3900c1dd45f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h @@ -82,6 +82,7 @@ public: private: void LoadImageSourceInfo(); + ImageSourceInfo GetDefaultSourceInfo(bool isObscured); void UpdateImageSource(); bool IsShowPasswordIcon(); void OnPasswordIconClicked(); -- Gitee From 1a3ab17506576c505d737b0f3c5005dfee250cf4 Mon Sep 17 00:00:00 2001 From: lijuan Date: Sun, 22 Oct 2023 07:22:34 +0000 Subject: [PATCH 18/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:1=E3=80=81=E6=89=8B?= =?UTF-8?q?=E6=9F=84=E6=8D=A2=E8=A1=8C=E5=A4=84=E4=BD=8D=E7=BD=AE=E4=B8=8D?= =?UTF-8?q?=E5=AF=B9=EF=BC=9B2=E3=80=81=E5=A4=B1=E7=84=A6=E6=BB=91?= =?UTF-8?q?=E5=8A=A8=E6=98=BE=E7=A4=BA=E6=BB=91=E5=8A=A8=E6=9D=A1=EF=BC=9B?= =?UTF-8?q?3=E3=80=81=E6=9C=89=E6=8D=A2=E8=A1=8C=E6=97=B6=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E8=A1=8C=E6=95=B0=E4=B8=8D=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: Ie53fabdcfd06706218f097bf56550c365b5a98c8 --- .../pattern/search/search_pattern.cpp | 4 +- .../text_field/text_field_controller.cpp | 7 +- .../text_field_layout_algorithm.cpp | 4 +- .../text_field/text_field_layout_property.h | 2 +- .../text_field_overlay_modifier.cpp | 2 +- .../pattern/text_field/text_field_pattern.cpp | 64 ++++++------------- .../pattern/text_field/text_field_pattern.h | 7 +- .../render/adapter/txt_paragraph.cpp | 2 +- 8 files changed, 28 insertions(+), 64 deletions(-) diff --git a/frameworks/core/components_ng/pattern/search/search_pattern.cpp b/frameworks/core/components_ng/pattern/search/search_pattern.cpp index 6e3018a9e6f..a07be091938 100644 --- a/frameworks/core/components_ng/pattern/search/search_pattern.cpp +++ b/frameworks/core/components_ng/pattern/search/search_pattern.cpp @@ -366,8 +366,8 @@ void SearchPattern::OnClickButtonAndImage() CHECK_NULL_VOID(textFieldFrameNode); auto textFieldPattern = textFieldFrameNode->GetPattern(); CHECK_NULL_VOID(textFieldPattern); - auto text = textFieldPattern->GetEditingValue(); - searchEventHub->UpdateSubmitEvent(text.text); + auto text = textFieldPattern->GetTextValue(); + searchEventHub->UpdateSubmitEvent(text); textFieldPattern->CloseKeyboard(true); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp index 3909c9eeca1..5af755c1e70 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_controller.cpp @@ -78,12 +78,7 @@ int32_t TextFieldController::GetTextContentLinesNum() if (!textFieldPattern->IsOperation()) { return lines; } - RectF textRect = textFieldPattern->GetTextRect(); - - if (static_cast(textFieldPattern->GetLineHeight()) == 0) { - return lines; - } - lines = static_cast(textRect.Height()) / static_cast(textFieldPattern->GetLineHeight()); + lines = textFieldPattern->GetLineCount(); return lines; } lines = getTextContentLinesNum_(); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp index 3fced861a18..2c65f91e288 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp @@ -53,9 +53,9 @@ void TextFieldLayoutAlgorithm::ConstructTextStyles( CHECK_NULL_VOID(textFieldLayoutProperty); auto isInlineStyle = pattern->IsNormalInlineState(); - if (!textFieldLayoutProperty->GetValueValue("").empty()) { + if (!pattern->GetTextValue().empty()) { UpdateTextStyle(frameNode, textFieldLayoutProperty, textFieldTheme, textStyle, pattern->IsDisabled()); - textContent = textFieldLayoutProperty->GetValueValue(""); + textContent = pattern->GetTextValue(); if (!pattern->IsTextArea() && isInlineStyle) { textStyle.SetTextOverflow(TextOverflow::ELLIPSIS); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h index 71f8949bc9d..372f0a3d965 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_property.h @@ -95,7 +95,7 @@ public: ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, TextAlign, TextAlign, PROPERTY_UPDATE_MEASURE_SELF); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, MaxLength, uint32_t, PROPERTY_UPDATE_MEASURE); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP(TextLineStyle, MaxLines, uint32_t, PROPERTY_UPDATE_MEASURE); - ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, std::string, PROPERTY_UPDATE_MEASURE); + ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, std::string, PROPERTY_UPDATE_NORMAL); ACE_DEFINE_PROPERTY_GROUP(PlaceholderFontStyle, FontStyle); ACE_DEFINE_PROPERTY_ITEM_WITH_GROUP_ITEM( diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp index d9f7bff64a0..098caf562ec 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.cpp @@ -194,7 +194,7 @@ void TextFieldOverlayModifier::PaintScrollBar(DrawingContext& context) { auto textFieldPattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(textFieldPattern); - if (textFieldPattern->GetScrollBarVisible() && textFieldPattern->IsFocus()) { + if (textFieldPattern->GetScrollBarVisible() && textFieldPattern->IsTextArea()) { ScrollBarOverlayModifier::onDraw(context); } } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 37b2c5a8a35..bfc9b213617 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -250,6 +250,7 @@ bool TextFieldPattern::OnDirtyLayoutWrapperSwap(const RefPtr& dir paragraphWidth_ = paragraphWidth; textRect_ = textRect; parentGlobalOffset_ = textFieldLayoutAlgorithm->GetParentGlobalOffset(); + FireOnTextChangeEvent(); UpdateSelectController(); UpdateTextFieldManager(Offset(parentGlobalOffset_.GetX(), parentGlobalOffset_.GetY()), frameRect_.Height()); AdjustTextInReasonableArea(); @@ -503,19 +504,6 @@ int32_t TextFieldPattern::ConvertTouchOffsetToCaretPositionNG(const Offset& loca return paragraph_->GetGlyphIndexByCoordinate(offset); } -bool TextFieldPattern::DisplayPlaceHolder() -{ - auto layoutProperty = GetLayoutProperty(); - CHECK_NULL_RETURN(layoutProperty, false); - auto value = layoutProperty->GetValueValue(""); - return value.empty(); -} - -const TextEditingValueNG& TextFieldPattern::GetEditingValue() const -{ - return textEditingValue_; -} - #if defined(IOS_PLATFORM) Offset TextFieldPattern::GetGlobalOffset() const { @@ -792,7 +780,6 @@ void TextFieldPattern::HandleOnUndoAction() auto textEditingValue = operationRecords_.back(); // record应该包含光标、select状态、文本 contentController_->SetTextValue(textEditingValue.text); selectController_->UpdateCaretIndex(textEditingValue.caretPosition); - FireOnTextChangeEvent(); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); @@ -813,7 +800,6 @@ void TextFieldPattern::HandleOnRedoAction() selectController_->UpdateCaretIndex(textEditingValue.caretPosition); redoOperationRecords_.pop_back(); operationRecords_.push_back(textEditingValue); - FireOnTextChangeEvent(); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); @@ -924,7 +910,6 @@ void TextFieldPattern::HandleOnPaste() static_cast(textfield->contentController_->GetWideText().length())); textfield->ResetObscureTickCountDown(); textfield->selectController_->UpdateCaretIndex(newCaretPosition); - textfield->FireOnTextChangeEvent(); textfield->UpdateEditingValueToRecord(); if (textfield->IsTextArea() && layoutProperty->HasMaxLength()) { textfield->HandleCounterBorder(); @@ -990,7 +975,6 @@ void TextFieldPattern::HandleOnCut() } contentController_->erase(start, end - start); UpdateSelection(start); - SetEditingValueToProperty(contentController_->GetTextValue()); CloseSelectOverlay(true); StartTwinkling(); UpdateEditingValueToRecord(); @@ -1589,7 +1573,6 @@ void TextFieldPattern::OnModifyDone() InitTouchEvent(); SetAccessibilityAction(); FilterInitializeText(); - FireOnTextChangeEvent(); InitSelectOverlay(); if (responseArea_) { responseArea_->InitResponseArea(WeakClaim(this)); @@ -1875,8 +1858,9 @@ void TextFieldPattern::UpdateCaretPositionWithClamp(const int32_t& pos) void TextFieldPattern::ProcessOverlay(bool isUpdateMenu, bool animation, bool isShowMenu) { selectController_->CalculateHandleOffset(); - ShowSelectOverlayParams showOverlayParams = { .animation = animation, .isShowMenu = isShowMenu, - .isUpdateMenu = isUpdateMenu }; + ShowSelectOverlayParams showOverlayParams = { + .animation = animation, .isShowMenu = isShowMenu, .isUpdateMenu = isUpdateMenu + }; if (isSingleHandle_) { StartTwinkling(); LOGD("Show single handle Handle info %{public}s", selectController_->GetCaretRect().ToString().c_str()); @@ -1914,9 +1898,7 @@ void TextFieldPattern::ShowSelectOverlay(const ShowSelectOverlayParams& showOver void TextFieldPattern::StartRequestSelectOverlay(const ShowSelectOverlayParams& params, bool isShowPaste) { ClientOverlayInfo overlayInfo = { - .animation = params.animation, - .isMenuShow = params.isShowMenu, - .isUpdateMenu = params.isUpdateMenu + .animation = params.animation, .isMenuShow = params.isShowMenu, .isUpdateMenu = params.isUpdateMenu }; if (params.firstHandle.has_value()) { auto handle = params.firstHandle.value(); @@ -2191,6 +2173,10 @@ void TextFieldPattern::InitEditingValueText(std::string content) { contentController_->SetTextValue(std::move(content)); selectController_->UpdateCaretIndex(static_cast(StringUtils::ToWstring(content).length())); + auto layoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + GetHost()->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF + : PROPERTY_UPDATE_MEASURE); } void TextFieldPattern::InitMouseEvent() @@ -2606,7 +2592,6 @@ void TextFieldPattern::InsertValue(const std::string& insertValue) selectionMode_ = SelectionMode::NONE; CloseSelectOverlay(true); StartTwinkling(); - FireOnTextChangeEvent(); auto layoutProperty = host->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); if (IsTextArea() && layoutProperty->HasMaxLength()) { @@ -3020,7 +3005,6 @@ void TextFieldPattern::Delete(int32_t start, int32_t end) LOGI("Handle Delete within [%{public}d, %{public}d]", start, end); contentController_->erase(start, end - start); selectController_->MoveCaretToContentRect(start); - FireOnTextChangeEvent(); CloseSelectOverlay(true); StartTwinkling(); UpdateEditingValueToRecord(); @@ -3035,27 +3019,10 @@ void TextFieldPattern::Delete(int32_t start, int32_t end) : PROPERTY_UPDATE_MEASURE); } -void TextFieldPattern::SetEditingValueToProperty(const std::string& newValueText) -{ - auto host = GetHost(); - CHECK_NULL_VOID(host); - auto layoutProperty = host->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - auto textCache = layoutProperty->GetValueValue(""); - layoutProperty->UpdateValue(newValueText); - if (textCache != newValueText) { - layoutProperty->UpdateNeedFireOnChange(true); - host->OnAccessibilityEvent(AccessibilityEventType::TEXT_CHANGE, textCache, newValueText); - } else { - layoutProperty->UpdateNeedFireOnChange(false); - } -} - void TextFieldPattern::ClearEditingValue() { contentController_->Reset(); selectController_->UpdateCaretIndex(0); - FireOnTextChangeEvent(); UpdateEditingValueToRecord(); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); @@ -3158,7 +3125,6 @@ void TextFieldPattern::UpdateEditingValue(const std::shared_ptrGetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); @@ -3289,7 +3255,6 @@ void TextFieldPattern::DeleteBackward(int32_t length) auto start = std::max(selectController_->GetCaretIndex() - length, 0); contentController_->erase(start, length); selectController_->UpdateCaretIndex(start); - FireOnTextChangeEvent(); CloseSelectOverlay(); StartTwinkling(); UpdateEditingValueToRecord(); @@ -3317,7 +3282,6 @@ void TextFieldPattern::DeleteForward(int32_t length) return; } contentController_->erase(selectController_->GetCaretIndex(), length); - FireOnTextChangeEvent(); selectionMode_ = SelectionMode::NONE; CloseSelectOverlay(); StartTwinkling(); @@ -3616,7 +3580,7 @@ int32_t TextFieldPattern::GetNakedCharPosition() const } auto layoutProperty = GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, -1); - auto content = layoutProperty->GetValueValue(""); + auto content = contentController_->GetTextValue(); if (content.empty()) { return -1; } @@ -4915,4 +4879,12 @@ void TextFieldPattern::NotifyOnEditChanged(bool isChanged) CHECK_NULL_VOID(eventHub); eventHub->FireOnEditChanged(isChanged); } + +int32_t TextFieldPattern::GetLineCount() const +{ + if (paragraph_) { + return paragraph_->GetLineCount(); + } + return 0; +} } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 527dafe3d77..e288eea1f82 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -258,7 +258,6 @@ public: textEditingController_ = textEditController; } - const TextEditingValueNG& GetEditingValue() const; std::string GetTextValue() const { return contentController_->GetTextValue(); @@ -281,7 +280,6 @@ public: contentController_->SetTextValue(value); selectController_->UpdateCaretIndex(caretPosition); } - void SetEditingValueToProperty(const std::string& newValueText); void UpdateCaretPositionByTouch(const Offset& offset); bool IsReachedBoundary(float offset); @@ -338,8 +336,6 @@ public: } #endif - bool DisplayPlaceHolder(); - const OffsetF& GetLastTouchOffset() { return lastTouchOffset_; @@ -483,7 +479,7 @@ public: int32_t GetLineEndPosition(int32_t originCaretPosition, bool needToCheckLineChanged = true); bool IsOperation() const { - return textEditingValue_.ToString().length() > 1; + return contentController_->GetTextValue().length() > 0; } bool CursorMoveLeft() override; @@ -793,6 +789,7 @@ public: void HandleOnCut(); void StripNextLine(std::wstring& data); bool OnKeyEvent(const KeyEvent& event); + int32_t GetLineCount() const; TextInputType GetKeyboard() { return keyboard_; diff --git a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp index 738e42ef73b..79f13645b5c 100644 --- a/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp +++ b/frameworks/core/components_ng/render/adapter/txt_paragraph.cpp @@ -341,7 +341,7 @@ bool TxtParagraph::ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& auto last = extent - placeHolderIndex_ - 1; auto index = static_cast(last) == text_.length() ? last : extent; prevChar = text_[std::max(0, index - 1)]; - if (prevChar == NEWLINE_CODE) { + if (prevChar == NEWLINE_CODE && !text_[index]) { // Return the start of next line. result.offset.SetX(MakeEmptyOffsetX()); #ifndef USE_GRAPHIC_TEXT_GINE -- Gitee From 0065ca4fc06d39220bb0bf09edb0a5d357a77c56 Mon Sep 17 00:00:00 2001 From: lijuan Date: Sun, 22 Oct 2023 09:28:36 +0000 Subject: [PATCH 19/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=AE=E7=9B=98?= =?UTF-8?q?=E5=B7=A6=E5=8F=B3=E9=94=AE=EF=BC=8Cctrl+end=E9=94=AE=E5=85=A5?= =?UTF-8?q?=E5=90=8E=E5=85=89=E6=A0=87=E4=BD=8D=E7=BD=AE=E4=B8=8D=E5=AF=B9?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I76cd3aabf582103fa9b0104d39ecbfd3726aeac6 --- .../pattern/text_field/text_field_pattern.cpp | 16 ++++++++-------- .../pattern/text_field/text_field_pattern.h | 2 +- .../text_field/text_select_controller.cpp | 12 ++++++------ .../pattern/text_field/text_select_controller.h | 2 +- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index bfc9b213617..7dbeb6a22f9 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -2667,11 +2667,11 @@ float TextFieldPattern::PreferredLineHeight() return PreferredTextHeight(contentController_->IsEmpty()); } -void TextFieldPattern::OnCursorMoveDone() +void TextFieldPattern::OnCursorMoveDone(TextAffinity textAffinity) { CloseSelectOverlay(); selectionMode_ = SelectionMode::NONE; - selectController_->MoveCaretToContentRect(GetCaretIndex()); + selectController_->MoveCaretToContentRect(GetCaretIndex(), textAffinity); if (ResetObscureTickCountDown()) { GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); } else { @@ -2769,8 +2769,8 @@ int32_t TextFieldPattern::GetLineEndPosition(int32_t originCaretPosition, bool n } int32_t moveLineEndOffset = 0; int32_t strIndex = 0; - for (strIndex = originCaretPosition + 1; (strIndex <= textLength && wideTextValue[strIndex] != L'\n') || - (needToCheckLineChanged && !CharLineChanged(strIndex)); + for (strIndex = originCaretPosition; (strIndex <= textLength && wideTextValue[strIndex] != L'\n') || + (needToCheckLineChanged && !CharLineChanged(strIndex)); strIndex++) { moveLineEndOffset++; } @@ -2804,7 +2804,7 @@ bool TextFieldPattern::CursorMoveLeft() selectController_->GetCaretIndex() - GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetCaretIndex(), true)); } - OnCursorMoveDone(); + OnCursorMoveDone(TextAffinity::DOWNSTREAM); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2863,7 +2863,7 @@ bool TextFieldPattern::CursorMoveToParagraphBegin() } auto originCaretPosition = selectController_->GetCaretIndex(); UpdateCaretPositionWithClamp(GetLineBeginPosition(originCaretPosition, false)); - OnCursorMoveDone(); + OnCursorMoveDone(TextAffinity::DOWNSTREAM); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2892,7 +2892,7 @@ bool TextFieldPattern::CursorMoveRight() selectController_->GetCaretIndex() + GetGraphemeClusterLength(contentController_->GetWideText(), selectController_->GetCaretIndex())); } - OnCursorMoveDone(); + OnCursorMoveDone(TextAffinity::DOWNSTREAM); return originCaretPosition != selectController_->GetCaretIndex(); } @@ -2951,7 +2951,7 @@ bool TextFieldPattern::CursorMoveToParagraphEnd() } auto originCaretPosition = selectController_->GetCaretIndex(); UpdateCaretPositionWithClamp(GetLineEndPosition(originCaretPosition, false)); - OnCursorMoveDone(); + OnCursorMoveDone(TextAffinity::DOWNSTREAM); return originCaretPosition != selectController_->GetCaretIndex(); } diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index e288eea1f82..ab14aefaf3f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -595,7 +595,7 @@ public: } void ProcessInnerPadding(); - void OnCursorMoveDone(); + void OnCursorMoveDone(TextAffinity textAffinity = TextAffinity::UPSTREAM); bool IsDisabled(); bool AllowCopy(); diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index 91bbbcd09a5..f46711ebe1e 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -302,14 +302,14 @@ void TextSelectController::MoveSecondHandleToContentRect(int32_t index) FireSelectEvent(); } -void TextSelectController::MoveCaretToContentRect(int32_t index) +void TextSelectController::MoveCaretToContentRect(int32_t index, TextAffinity textAffinity) { index = std::clamp(index, 0, static_cast(contentController_->GetWideText().length())); CaretMetricsF CaretMetrics; caretInfo_.index = index; firstHandleInfo_.index = index; secondHandleInfo_.index = index; - CalcCaretMetricsByPosition(GetCaretIndex(), CaretMetrics, TextAffinity::UPSTREAM); + CalcCaretMetricsByPosition(GetCaretIndex(), CaretMetrics, textAffinity); OffsetF CaretOffset = CaretMetrics.offset; RectF caretRect; caretRect.SetOffset(CaretOffset); @@ -415,9 +415,9 @@ void TextSelectController::UpdateRecordCaretIndex(int32_t index) const void TextSelectController::ResetHandles() { - firstHandleInfo_.index = caretInfo_.index; - secondHandleInfo_.index = caretInfo_.index; - UpdateFirstHandleOffset(); - UpdateSecondHandleOffset(); + firstHandleInfo_.index = caretInfo_.index; + secondHandleInfo_.index = caretInfo_.index; + UpdateFirstHandleOffset(); + UpdateSecondHandleOffset(); } } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h index 6e261eeda1e..368089995d6 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -179,7 +179,7 @@ public: void UpdateSecondHandleOffset(); void MoveFirstHandleToContentRect(int32_t index); void MoveSecondHandleToContentRect(int32_t index); - void MoveCaretToContentRect(int32_t index); + void MoveCaretToContentRect(int32_t index, TextAffinity textAffinity = TextAffinity::UPSTREAM); void MoveHandleToContentRect(RectF& handleRect); static int32_t GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev = false); void CalculateHandleOffset(); -- Gitee From 3872bb7db518ee7d9d1b1d218573ccd1fab60364 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Sun, 22 Oct 2023 16:07:08 +0800 Subject: [PATCH 20/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3disable=E5=90=8E?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=B8=8D=E5=8F=AF=E6=81=A2=E5=A4=8D=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I9450b767191a25bbad6443e16cf8dca4304df8c5 --- .../pattern/text_field/text_field_pattern.cpp | 45 ++++++++----------- .../pattern/text_field/text_field_pattern.h | 1 + 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 7dbeb6a22f9..381315128da 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -675,6 +675,22 @@ void TextFieldPattern::HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) } } +void TextFieldPattern::InitDisableColor() +{ + auto layoutProperty = GetLayoutProperty(); + CHECK_NULL_VOID(layoutProperty); + auto pipeline = PipelineBase::GetCurrentContext(); + CHECK_NULL_VOID(pipeline); + auto theme = pipeline->GetTheme(); + CHECK_NULL_VOID(theme); + if (layoutProperty->GetShowUnderlineValue(false) && IsUnspecifiedOrTextType()) { + underlineWidth_ = UNDERLINE_WIDTH; + underlineColor_ = + IsDisabled() ? theme->GetDisableUnderlineColor() : theme->GetUnderlineColor(); + SaveUnderlineStates(); + } +} + void TextFieldPattern::InitFocusEvent() { CHECK_NULL_VOID(!focusEventInitialized_); @@ -1522,7 +1538,7 @@ void TextFieldPattern::CheckIfNeedToResetKeyboard() LOGI("Keyboard action is %{public}d", action_); #if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) // if keyboard attached and keyboard is shown, pull up keyboard again - if (needToResetKeyboard && imeAttached_ && imeShown_) { + if (needToResetKeyboard && imeShown_) { CloseKeyboard(true); RequestKeyboard(false, true, true); } @@ -1554,12 +1570,6 @@ void TextFieldPattern::OnModifyDone() layoutProperty->UpdateTextInputType(TextInputType::TEXT); } CheckIfNeedToResetKeyboard(); - if (layoutProperty->GetShowUnderlineValue(false) && IsUnspecifiedOrTextType()) { - underlineWidth_ = UNDERLINE_WIDTH; - underlineColor_ = - IsDisabled() ? textFieldTheme->GetDisableUnderlineColor() : textFieldTheme->GetUnderlineColor(); - SaveUnderlineStates(); - } auto renderContext = host->GetRenderContext(); CHECK_NULL_VOID(renderContext); isTransparent_ = renderContext->GetOpacityValue(1.0f) == 0.0f; @@ -1574,6 +1584,7 @@ void TextFieldPattern::OnModifyDone() SetAccessibilityAction(); FilterInitializeText(); InitSelectOverlay(); + InitDisableColor(); if (responseArea_) { responseArea_->InitResponseArea(WeakClaim(this)); } @@ -1753,13 +1764,6 @@ bool TextFieldPattern::IsDisabled() CHECK_NULL_RETURN(eventHub, true); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_RETURN(layoutProperty, true); - auto pipeline = PipelineBase::GetCurrentContext(); - CHECK_NULL_RETURN(pipeline, true); - auto theme = pipeline->GetTheme(); - CHECK_NULL_RETURN(theme, true); - if (!eventHub->IsEnabled()) { - layoutProperty->UpdateTextColor(theme->GetDisableTextColor()); - } return !eventHub->IsEnabled(); } @@ -2415,9 +2419,6 @@ bool TextFieldPattern::RequestKeyboard(bool isFocusViewChanged, bool needStartTw MiscServices::TextConfig textConfig = optionalTextConfig.value(); LOGI("RequestKeyboard set calling window id is : %{public}u", textConfig.windowId); inputMethod->Attach(textChangeListener_, needShowSoftKeyboard, textConfig); -#if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) - imeAttached_ = true; -#endif #else if (!HasConnection()) { TextInputConfiguration config; @@ -2483,20 +2484,12 @@ bool TextFieldPattern::CloseKeyboard(bool forceClose) return CloseCustomKeyboard(); } #if defined(ENABLE_STANDARD_INPUT) -#if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) - if (!imeAttached_) { - return false; - } -#endif auto inputMethod = MiscServices::InputMethodController::GetInstance(); if (!inputMethod) { LOGE("Request close soft keyboard failed because input method is null."); return false; } inputMethod->Close(); -#if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) - imeAttached_ = false; -#endif #else if (HasConnection()) { connection_->Close(GetInstanceId()); @@ -3554,7 +3547,7 @@ bool TextFieldPattern::OnBackPressed() CHECK_NULL_RETURN(tmpHost, false); LOGI("Textfield %{public}d receives back press event", tmpHost->GetId()); #if defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) - if ((!imeAttached_ || (imeAttached_ && !imeShown_)) && !isCustomKeyboardAttached_) { + if (!imeShown_ && !isCustomKeyboardAttached_) { #else if (!isCustomKeyboardAttached_) { #endif diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index ab14aefaf3f..d17d75826d6 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -986,6 +986,7 @@ private: void HandleTouchDown(const Offset& offset); void HandleTouchUp(); + void InitDisableColor(); void InitFocusEvent(); void InitTouchEvent(); void InitLongPressEvent(); -- Gitee From 09068acbe224ab01b9ee5badf7e217a84b59f545 Mon Sep 17 00:00:00 2001 From: lijuan Date: Mon, 23 Oct 2023 07:52:32 +0000 Subject: [PATCH 21/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=BE=E7=BD=AEpaddi?= =?UTF-8?q?ng=E5=90=8E=E5=B8=83=E5=B1=80=E4=B8=8D=E5=AF=B9=E9=97=AE?= =?UTF-8?q?=E9=A2=98=EF=BC=8C=E5=86=85=E8=81=94=E6=A8=A1=E5=BC=8F=E9=83=A8?= =?UTF-8?q?=E5=88=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I00d79423c8419634ce456cecc0e239349377fba2 --- .../text_area/text_area_layout_algorithm.cpp | 2 +- .../text_field/text_field_model_ng.cpp | 2 +- .../pattern/text_field/text_field_pattern.cpp | 36 +++++++++---------- .../pattern/text_field/text_field_pattern.h | 1 - 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp index 399402a3410..b3c4f1798cf 100644 --- a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp @@ -192,7 +192,7 @@ void TextAreaLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) textRect_.SetOffset(OffsetF(0.0f, textRectOffSet.GetY()) + offsetBase); content->SetOffset(OffsetF(0.0f, textRectOffSet.GetY()) + offsetBase); } else { - textRect_.SetOffset(pattern->GetTextRect().GetOffset()); + textRect_.SetOffset(OffsetF(offsetBase.GetX(), pattern->GetTextRect().GetOffset().GetY())); content->SetOffset(offsetBase); } // CounterNode Layout. diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp index a2156f37f4c..e9ca6b9b4b2 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_model_ng.cpp @@ -113,7 +113,7 @@ void TextFieldModelNG::ProcessDefaultPadding(PaddingProperty& paddings) paddings.top = NG::CalcLength(themePadding.Top().ConvertToPx()); paddings.bottom = NG::CalcLength(themePadding.Top().ConvertToPx()); paddings.left = NG::CalcLength(themePadding.Left().ConvertToPx()); - paddings.right = NG::CalcLength(themePadding.Left().ConvertToPx()); + paddings.right = NG::CalcLength(themePadding.Right().ConvertToPx()); } RefPtr TextFieldModelNG::CreateTextInput( diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 381315128da..ef2c066d7ee 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -1796,8 +1796,23 @@ void TextFieldPattern::ProcessInnerPadding() ? CalcLength(themePadding.Top()).GetDimension().ConvertToPx() : paddingProperty->top.value_or(CalcLength(themePadding.Top())).GetDimension().ConvertToPx(); utilPadding_.top = top; - : paddingProperty->right.value_or(CalcLength(themePadding.Right())).GetDimension().ConvertToPx(); + auto bottom = + !paddingProperty + ? CalcLength(themePadding.Bottom()).GetDimension().ConvertToPx() + : paddingProperty->bottom.value_or(CalcLength(themePadding.Bottom())).GetDimension().ConvertToPx(); + utilPadding_.bottom = bottom; + auto right = !paddingProperty + ? CalcLength(themePadding.Right()).GetDimension().ConvertToPx() + : paddingProperty->right.value_or(CalcLength(themePadding.Right())).GetDimension().ConvertToPx(); + utilPadding_.right = right; lastBorderWidth_ = currentBorderWidth; + + PaddingProperty paddings; + paddings.top = NG::CalcLength(top); + paddings.bottom = NG::CalcLength(bottom); + paddings.left = NG::CalcLength(left); + paddings.right = NG::CalcLength(right); + layoutProperty->UpdatePadding(paddings); } void TextFieldPattern::InitLongPressEvent() @@ -2147,13 +2162,13 @@ void TextFieldPattern::OnHandleMoveDone(const RectF& /* handleRect */, bool isFi if (selectController_->GetFirstHandleIndex() == selectController_->GetSecondHandleIndex()) { CloseSelectOverlay(true); StartTwinkling(); + selectController_->UpdateCaretOffset(); } else { auto handleInfo = GetSelectHandleInfo(selectController_->GetFirstHandleOffset()); proxy->UpdateFirstSelectHandleInfo(handleInfo); handleInfo = GetSelectHandleInfo(selectController_->GetSecondHandleOffset()); proxy->UpdateSecondSelectHandleInfo(handleInfo); } - selectController_->UpdateCaretOffset(); } else { auto handleInfo = GetSelectHandleInfo(selectController_->GetCaretRect().GetOffset()); proxy->UpdateSecondSelectHandleInfo(handleInfo); @@ -4347,7 +4362,6 @@ void TextFieldPattern::ApplyInlineStates(bool focusStatus) layoutProperty->UpdatePadding( { CalcLength(padding), CalcLength(padding), CalcLength(padding), CalcLength(padding) }); ProcessInnerPadding(); - SetTextRectOffset(); MarginProperty margin; margin.bottom = CalcLength(inlineState_.padding.bottom->GetDimension() + inlineState_.margin.bottom->GetDimension()); @@ -4389,7 +4403,6 @@ void TextFieldPattern::RestorePreInlineStates() CHECK_NULL_VOID(pipeline); layoutProperty->UpdateTextColor(inlineState_.textColor); layoutProperty->UpdatePadding(inlineState_.padding); - ProcessInnerPadding(); inlinePadding_ = 0.0f; BorderWidthProperty currentBorderWidth; if (layoutProperty->GetBorderWidthProperty() != nullptr) { @@ -4413,6 +4426,7 @@ void TextFieldPattern::RestorePreInlineStates() if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } + ProcessInnerPadding(); selectionMode_ = SelectionMode::NONE; } @@ -4666,20 +4680,6 @@ bool TextFieldPattern::CheckSelectionRectVisible() return false; } -void TextFieldPattern::SetTextRectOffset() -{ - auto tmpHost = GetHost(); - CHECK_NULL_VOID(tmpHost); - auto layoutProperty = tmpHost->GetLayoutProperty(); - CHECK_NULL_VOID(layoutProperty); - if (barState_.has_value() && barState_.value() != layoutProperty->GetDisplayModeValue(DisplayMode::AUTO)) { - barState_ = layoutProperty->GetDisplayModeValue(DisplayMode::AUTO); - textRect_.SetOffset(OffsetF(GetPaddingLeft(), lastTextRectY_)); - } else { - textRect_.SetOffset(OffsetF(GetPaddingLeft(), GetPaddingTop())); - } -} - void TextFieldPattern::DumpInfo() { if (customKeyboardBulder_) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index d17d75826d6..11653d03e4e 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -1083,7 +1083,6 @@ private: void SaveInlineStates(); void ApplyInlineStates(bool focusStatus); void RestorePreInlineStates(); - void SetTextRectOffset(); bool ResetObscureTickCountDown(); bool IsInPasswordMode() const; -- Gitee From 7e6859eb5fec009235c02e19193d9c43418b6296 Mon Sep 17 00:00:00 2001 From: lijuan Date: Mon, 23 Oct 2023 08:29:05 +0000 Subject: [PATCH 22/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=86=85=E8=81=94?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=83=A8=E5=88=86=E9=97=AE=E9=A2=98=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=A4=B1=E5=8E=BB=E7=84=A6=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=A1=86=E7=82=B9=E5=87=BB=E5=88=87=E6=8D=A2=E5=B0=8F=E7=9C=BC?= =?UTF-8?q?=E7=9D=9B=E9=97=AA=E5=85=89=E6=A0=87=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: Iabdb45da36c2b6099c9ffccf187b6d09bd93bfff --- .../pattern/text_field/text_field_pattern.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index ef2c066d7ee..30c7ad080fc 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -555,8 +555,12 @@ void TextFieldPattern::HandleFocusEvent() CHECK_NULL_VOID(layoutProperty); if (IsNormalInlineState()) { ApplyInlineStates(true); - inlineSelectAllFlag_ = true; inlineFocusState_ = true; + if (contentController_->IsEmpty()) { + StartTwinkling(); + } else { + inlineSelectAllFlag_ = true; + } } else { StartTwinkling(); } @@ -4853,7 +4857,6 @@ void TextFieldPattern::OnObscuredChanged(bool isObscured) textObscured_ = isObscured; CloseSelectOverlay(false); selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); - StartTwinkling(); auto host = GetHost(); CHECK_NULL_VOID(host); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); -- Gitee From 7d15435a40f7781eb727a647a75daa16c3b4f512 Mon Sep 17 00:00:00 2001 From: wangtao Date: Mon, 23 Oct 2023 09:09:20 +0000 Subject: [PATCH 23/31] =?UTF-8?q?Controller=E8=AE=BE=E7=BD=AE=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=8C=BA=E6=97=B6=E4=B8=8D=E6=98=BE=E7=A4=BA=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E9=80=89=E6=8B=A9=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: wangtao Change-Id: I870e6cc7d7133a5ad14d4aecdb6eaf413bdf5c09 --- .../pattern/text_field/text_field_pattern.cpp | 31 +------------------ .../pattern/text_field/text_field_pattern.h | 3 -- 2 files changed, 1 insertion(+), 33 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 30c7ad080fc..45d90702de1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -583,11 +583,9 @@ void TextFieldPattern::HandleFocusEvent() void TextFieldPattern::HandleSetSelection(int32_t start, int32_t end, bool showHandle) { - // todo LOGI("HandleSetSelection %{public}d, %{public}d", start, end); StopTwinkling(); UpdateSelection(start, end); - AdjustTextSelectionRectOffsetX(); if (showHandle) { ProcessOverlay(); } else { @@ -599,33 +597,6 @@ void TextFieldPattern::HandleSetSelection(int32_t start, int32_t end, bool showH tmpHost->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } -void TextFieldPattern::AdjustTextSelectionRectOffsetX() -{ - if (textBoxes_.empty()) { - return; - } - auto contentLeftBoundary = contentRect_.GetX(); - auto contentRightBoundary = contentRect_.GetX() + contentRect_.GetSize().Width(); - auto selectionStart = textBoxes_.begin()->Left() + textRect_.GetX(); - auto selectionEnd = textBoxes_.begin()->Right() + textRect_.GetX(); - - float dx = 0.0f; - if (selectionEnd < contentLeftBoundary) { - if (selectionStart < selectionEnd) { - dx = contentLeftBoundary - selectionStart; - } else { - dx = contentLeftBoundary - selectionEnd; - } - } else if (selectionEnd > contentRightBoundary) { - if (selectionStart < selectionEnd) { - dx = selectionEnd - contentRightBoundary; - } else { - dx = selectionStart - contentRightBoundary; - } - } - textRect_.SetLeft(textRect_.GetX() + dx); -} - void TextFieldPattern::HandleExtendAction(int32_t action) { LOGI("HandleExtendAction %{public}d", action); @@ -3554,7 +3525,7 @@ void TextFieldPattern::SetSelectionFlag(int32_t selectionStart, int32_t selectio return; } cursorVisible_ = false; - HandleSetSelection(selectionStart, selectionEnd, true); + HandleSetSelection(selectionStart, selectionEnd, false); auto host = GetHost(); CHECK_NULL_VOID(host); host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index 11653d03e4e..d75f9c6e5e1 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -366,8 +366,6 @@ public: caretUpdateType_ = type; } - void AdjustTextSelectionRectOffsetX(); - float GetPaddingTop() const { return utilPadding_.top.value_or(0.0f); @@ -1183,7 +1181,6 @@ private: RefPtr textFieldController_; RefPtr textEditingController_; TextEditingValueNG textEditingValue_; - std::vector textBoxes_; // controls redraw of overlay modifier, update when need to redraw bool changeSelectedRects_ = false; RefPtr textFieldOverlayModifier_; -- Gitee From 6919b7c512637dca886073918402acfc5be03b91 Mon Sep 17 00:00:00 2001 From: lijuan Date: Mon, 23 Oct 2023 11:19:30 +0000 Subject: [PATCH 24/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dtextinput=E5=AE=BD?= =?UTF-8?q?=E5=BA=A6auto=E6=97=B6=EF=BC=8C=E7=88=B6=E8=8A=82=E7=82=B9?= =?UTF-8?q?=E6=9C=AA=E5=AF=B9=E5=85=B6=E9=87=8D=E6=96=B0=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I1dd256b09c5a79600373af4a357b82c0adc30cc3 --- .../pattern/text_field/text_field_pattern.cpp | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 45d90702de1..1f16ede5b0f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -775,8 +775,7 @@ void TextFieldPattern::HandleOnUndoAction() CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::HandleOnRedoAction() @@ -795,8 +794,7 @@ void TextFieldPattern::HandleOnRedoAction() CHECK_NULL_VOID(layoutProperty); auto tmpHost = GetHost(); CHECK_NULL_VOID(tmpHost); - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::HandleOnSelectAll(bool isKeyEvent, bool inlineStyle) @@ -2169,8 +2167,7 @@ void TextFieldPattern::InitEditingValueText(std::string content) selectController_->UpdateCaretIndex(static_cast(StringUtils::ToWstring(content).length())); auto layoutProperty = GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - GetHost()->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::InitMouseEvent() @@ -2580,8 +2577,7 @@ void TextFieldPattern::InsertValue(const std::string& insertValue) if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } - host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::UpdateEditingValueToRecord() @@ -2998,8 +2994,7 @@ void TextFieldPattern::Delete(int32_t start, int32_t end) if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } - GetHost()->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + GetHost()->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::ClearEditingValue() @@ -3011,8 +3006,7 @@ void TextFieldPattern::ClearEditingValue() CHECK_NULL_VOID(tmpHost); auto layoutProperty = tmpHost->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::HandleCounterBorder() @@ -3111,8 +3105,7 @@ void TextFieldPattern::UpdateEditingValue(const std::shared_ptrGetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); - host->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::UpdateInputFilterErrorText(const std::string& errorText) @@ -3248,8 +3241,7 @@ void TextFieldPattern::DeleteBackward(int32_t length) if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::DeleteForward(int32_t length) @@ -3276,8 +3268,7 @@ void TextFieldPattern::DeleteForward(int32_t length) if (IsTextArea() && layoutProperty->HasMaxLength()) { HandleCounterBorder(); } - tmpHost->MarkDirtyNode(layoutProperty->GetMaxLinesValue(Infinity()) <= 1 ? PROPERTY_UPDATE_MEASURE_SELF - : PROPERTY_UPDATE_MEASURE); + tmpHost->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } std::u16string TextFieldPattern::GetLeftTextOfCursor(int32_t number) @@ -4830,7 +4821,7 @@ void TextFieldPattern::OnObscuredChanged(bool isObscured) selectController_->UpdateCaretIndex(selectController_->GetCaretIndex()); auto host = GetHost(); CHECK_NULL_VOID(host); - host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF); + host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT); } void TextFieldPattern::CreateHandles() -- Gitee From 2d28dbc00f05eca6459e2fd6b17304b18646af28 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Mon, 23 Oct 2023 20:14:16 +0800 Subject: [PATCH 25/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3codeCheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I67aa31b39a1f6b5bed0c776a364af49327b4559d --- .../core/components_ng/pattern/search/search_text_field.cpp | 2 +- .../select_overlay/select_overlay_layout_algorithm.cpp | 2 +- .../pattern/select_overlay/select_overlay_layout_algorithm.h | 4 ++-- .../components_ng/pattern/text_field/content_controller.h | 2 +- .../pattern/text_field/text_field_overlay_modifier.h | 2 +- .../components_ng/pattern/text_field/text_field_pattern.h | 1 - .../pattern/text_field/text_select_controller.cpp | 2 +- .../components_ng/pattern/text_field/text_select_controller.h | 2 +- 8 files changed, 8 insertions(+), 9 deletions(-) diff --git a/frameworks/core/components_ng/pattern/search/search_text_field.cpp b/frameworks/core/components_ng/pattern/search/search_text_field.cpp index de8c91f0967..d59ebcca1c4 100644 --- a/frameworks/core/components_ng/pattern/search/search_text_field.cpp +++ b/frameworks/core/components_ng/pattern/search/search_text_field.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022-2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp index 8f30ab5db65..5a2245c64af 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.cpp @@ -15,7 +15,7 @@ #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h" -#include +#include #include diff --git a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h index 9fe18664606..e4b73255844 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h @@ -26,8 +26,8 @@ namespace OHOS::Ace::NG { struct ConstraintMenuParams { - float minSpacing; - float menuHeight; + float minSpacing = 0.0f; + float menuHeight = 0.0f; RefPtr anchorNode; RectF viewPort; }; diff --git a/frameworks/core/components_ng/pattern/text_field/content_controller.h b/frameworks/core/components_ng/pattern/text_field/content_controller.h index 517673d3712..a1a9000a422 100644 --- a/frameworks/core/components_ng/pattern/text_field/content_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/content_controller.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h index 76ddc28b3ca..5b8a0b2d7b3 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_overlay_modifier.h @@ -16,7 +16,7 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_OVERLAY_MODIFIER_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_FIELD_TEXT_FIELD_OVERLAY_MODIFIER_H -#include +#include #include "base/memory/ace_type.h" #include "core/components/common/properties/color.h" #include "core/components_ng/base/modifier.h" diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index d75f9c6e5e1..efdc8c35dbb 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -502,7 +502,6 @@ public: { return selectController_->GetSelectedRects(); } - // void CaretMoveToLastNewLineChar(); void ToJsonValue(std::unique_ptr& json) const override; void FromJson(const std::unique_ptr& json) override; void InitEditingValueText(std::string content); diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index f46711ebe1e..ceaa037c35f 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h index 368089995d6..52a0361c842 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at -- Gitee From b7cc095926aa378472b986da642c7a377dcb971f Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Mon, 23 Oct 2023 21:49:19 +0800 Subject: [PATCH 26/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: Ia63a7d49ed717678cc23b7b4d3225e28b7a83d65 --- .../components_ng/pattern/text_field/text_field_pattern.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 1f16ede5b0f..d4b550001c3 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -4646,7 +4646,7 @@ bool TextFieldPattern::CheckSelectionRectVisible() return false; } -void TextFieldPattern::DumpInfo() +void TextFieldPattern::DumpAdvanceInfo() { if (customKeyboardBulder_) { DumpLog::GetInstance().AddDesc(std::string("CustomKeyboard: true") -- Gitee From 5aaa45c6c8a855cec686d626b2ae40a4d4a6fae6 Mon Sep 17 00:00:00 2001 From: lijuan Date: Mon, 23 Oct 2023 14:09:27 +0000 Subject: [PATCH 27/31] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=A9=BA=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E5=8A=A8=E6=80=81=E5=88=87=E6=8D=A2=E5=AD=97=E5=8F=B7?= =?UTF-8?q?=EF=BC=8C=E7=BB=84=E4=BB=B6=E9=AB=98=E5=BA=A6=E5=81=8F=E5=A4=A7?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lijuan Change-Id: I108c7f669b067b75ec7c5dc88222eb3267f6d141 --- .../text_area/text_area_layout_algorithm.cpp | 7 +++-- .../text_field_layout_algorithm.cpp | 28 ++++++++++++++----- .../text_field/text_field_layout_algorithm.h | 1 - .../pattern/text_field/text_field_pattern.cpp | 8 +++--- .../pattern/text_field/text_field_pattern.h | 4 +-- .../text_input_layout_algorithm.cpp | 6 ++-- 6 files changed, 35 insertions(+), 19 deletions(-) diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp index b3c4f1798cf..3c928ed6aa4 100644 --- a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp @@ -50,9 +50,10 @@ std::optional TextAreaLayoutAlgorithm::MeasureContent( } else { CreateParagraph(textStyle, textContent_, false, pattern->GetNakedCharPosition()); } - - // Used for empty text. - preferredHeight_ = pattern->PreferredLineHeight(); + if (textContent_.empty()) { + // Used for empty text. + preferredHeight_ = pattern->PreferredLineHeight(true); + } // Paragraph layout.} if (isInlineStyle) { diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp index 2c65f91e288..609d8016b2a 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.cpp @@ -112,7 +112,11 @@ std::optional TextFieldLayoutAlgorithm::InlineMeasureContent( pattern->GetSingleLineHeight() * textFieldLayoutProperty->GetMaxViewLinesValue(INLINE_DEFAULT_VIEW_MAXLINE); } - return SizeF(contentWidth, std::min(inlineIdealHieght, std::max(preferredHeight_, paragraph_->GetHeight()))); + auto contentHeight = GreatNotEqual(paragraph_->GetLongestLine(), 0.0) + ? paragraph_->GetHeight() + : std::max(preferredHeight_, paragraph_->GetHeight()); + + return SizeF(contentWidth, std::min(inlineIdealHieght, contentHeight)); } float TextFieldLayoutAlgorithm::ConstraintWithMinWidth( @@ -144,8 +148,11 @@ SizeF TextFieldLayoutAlgorithm::PlaceHolderMeasureContent( auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper, imageWidth); auto counterNodeHeight = CounterNodeMeasure(contentWidth, layoutWrapper); - auto contentHeight = std::min( - contentConstraint.maxSize.Height() - counterNodeHeight, std::max(preferredHeight_, paragraph_->GetHeight())); + auto height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0) + ? paragraph_->GetHeight() + : std::max(preferredHeight_, paragraph_->GetHeight()); + + auto contentHeight = std::min(contentConstraint.maxSize.Height() - counterNodeHeight, height); textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); @@ -160,8 +167,11 @@ SizeF TextFieldLayoutAlgorithm::TextAreaMeasureContent( auto contentWidth = ConstraintWithMinWidth(contentConstraint, layoutWrapper); auto counterNodeHeight = CounterNodeMeasure(contentWidth, layoutWrapper); - auto contentHeight = std::min( - contentConstraint.maxSize.Height() - counterNodeHeight, std::max(preferredHeight_, paragraph_->GetHeight())); + auto height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0) + ? paragraph_->GetHeight() + : std::max(preferredHeight_, paragraph_->GetHeight()); + + auto contentHeight = std::min(contentConstraint.maxSize.Height() - counterNodeHeight, height); textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); return SizeF(contentWidth, contentHeight); @@ -183,8 +193,12 @@ SizeF TextFieldLayoutAlgorithm::TextInputMeasureContent( contentWidth = std::min(contentConstraint.maxSize.Width() - imageWidth, std::max(paragraph_->GetLongestLine(), contentConstraint.minSize.Width() - imageWidth)); } - auto contenHeight = - std::min(contentConstraint.maxSize.Height(), std::max(preferredHeight_, paragraph_->GetHeight())); + + auto height = GreatNotEqual(paragraph_->GetLongestLine(), 0.0) + ? paragraph_->GetHeight() + : std::max(preferredHeight_, paragraph_->GetHeight()); + + auto contenHeight = std::min(contentConstraint.maxSize.Height(), height); textRect_.SetSize(SizeF(std::max(0.0f, paragraph_->GetLongestLine()), paragraph_->GetHeight())); return SizeF(contentWidth, contenHeight); diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h index 7766795704c..b2537b898b8 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_layout_algorithm.h @@ -106,7 +106,6 @@ protected: SizeF TextInputMeasureContent( const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper, float imageWidth); SizeF TextAreaMeasureContent(const LayoutConstraintF& contentConstraint, LayoutWrapper* layoutWrapper); - RefPtr paragraph_; RefPtr errorParagraph_; RectF textRect_; diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index d4b550001c3..c0442a1c675 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -2596,9 +2596,9 @@ void TextFieldPattern::UpdateEditingValueToRecord() operationRecords_.emplace_back(record); } -float TextFieldPattern::PreferredTextHeight(bool isPlaceholder) +float TextFieldPattern::PreferredTextHeight(bool isPlaceholder, bool isAlgorithmMeasure) { - if (paragraph_ && paragraph_->GetHeight() != 0.0f) { + if (!isAlgorithmMeasure && paragraph_ && paragraph_->GetHeight() != 0.0f) { return paragraph_->GetHeight() / paragraph_->GetLineCount(); } RefPtr paragraph; @@ -2641,9 +2641,9 @@ float TextFieldPattern::PreferredTextHeight(bool isPlaceholder) return paragraph->GetHeight(); } -float TextFieldPattern::PreferredLineHeight() +float TextFieldPattern::PreferredLineHeight(bool isAlgorithmMeasure) { - return PreferredTextHeight(contentController_->IsEmpty()); + return PreferredTextHeight(contentController_->IsEmpty(), isAlgorithmMeasure); } void TextFieldPattern::OnCursorMoveDone(TextAffinity textAffinity) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h index efdc8c35dbb..c0079772af0 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.h @@ -530,7 +530,7 @@ public: return connection_; #endif } - float PreferredLineHeight(); + float PreferredLineHeight(bool isAlgorithmMeasure = false); void SearchRequestKeyboard(); @@ -1053,7 +1053,7 @@ private: void StopTwinkling(); void CheckIfNeedToResetKeyboard(); - float PreferredTextHeight(bool isPlaceholder); + float PreferredTextHeight(bool isPlaceholder, bool isAlgorithmMeasure = false); void SetCaretOffsetForEmptyTextOrPositionZero(); void UpdateTextFieldManager(const Offset& offset, float height); diff --git a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp index e5f16908e56..f65bd5e6a9c 100644 --- a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp @@ -60,8 +60,10 @@ std::optional TextInputLayoutAlgorithm::MeasureContent( } } - // Used for empty text. - preferredHeight_ = pattern->PreferredLineHeight(); + if (textContent_.empty()) { + // Used for empty text. + preferredHeight_ = pattern->PreferredLineHeight(true); + } // Paragraph layout. if (isInlineStyle) { -- Gitee From 9a1fe3fcb807ae7040e3dd5385755221fcb62c4d Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Mon, 23 Oct 2023 22:10:49 +0800 Subject: [PATCH 28/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3codeCheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I1d438221e3a8447f7b6ba54fbb1b4a8d8f05b5ce --- .../manager/select_overlay/select_overlay_client.cpp | 6 +----- .../select_overlay/select_overlay_scroll_notifier.h | 1 - .../components_ng/pattern/search/search_text_field.cpp | 2 -- .../core/components_ng/pattern/search/search_text_field.h | 1 - .../pattern/text_area/text_area_layout_algorithm.cpp | 1 - .../components_ng/pattern/text_field/content_controller.h | 2 -- .../pattern/text_field/text_field_pattern.cpp | 7 ++----- .../pattern/text_field/text_input_response_area.cpp | 1 - .../pattern/text_field/text_input_response_area.h | 1 - .../pattern/text_field/text_select_controller.cpp | 4 ---- .../pattern/text_field/text_select_controller.h | 5 +---- .../pattern/text_input/text_input_layout_algorithm.cpp | 1 - 12 files changed, 4 insertions(+), 28 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp index c2f218fedec..3fb46f49ff7 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.cpp @@ -15,8 +15,6 @@ #include "core/components_ng/manager/select_overlay/select_overlay_client.h" -#include - #include "base/memory/ace_type.h" #include "base/utils/utils.h" #include "core/components_ng/base/frame_node.h" @@ -25,7 +23,6 @@ #include "core/pipeline_ng/pipeline_context.h" namespace OHOS::Ace::NG { - void SelectOverlayClient::InitSelectOverlay() { selectOverlayInfo_.menuCallback.onCopy = [weak = WeakClaim(this)]() { @@ -131,7 +128,7 @@ void SelectOverlayClient::UpdateShowingSelectOverlay(ClientOverlayInfo& clientIn LOGI("update select overlay, isUseMouse %{public}d", clientInfo.isShowMouseMenu); auto isCurrentSingleHandle = IsShowingSingleHandle(); auto hasRequestSingleHandle = !clientInfo.firstHandleInfo && clientInfo.secondHandleInfo; - if (clientInfo.isShowMouseMenu || isCurrentSingleHandle ^ hasRequestSingleHandle) { + if (clientInfo.isShowMouseMenu || (isCurrentSingleHandle ^ hasRequestSingleHandle)) { RequestCloseSelectOverlay(true); clientInfo.isUpdateMenu = true; CreateSelectOverlay(clientInfo); @@ -258,5 +255,4 @@ void SelectOverlayClient::StopListeningScrollableParent(const RefPtr& CHECK_NULL_VOID(context); context->GetSelectOverlayManager()->RemoveScrollCallback(host->GetId()); } - } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h index acfdec96cca..072716f091e 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_scroll_notifier.h @@ -22,7 +22,6 @@ namespace OHOS::Ace::NG { class SelectOverlayScrollNotifier { - public: static inline void NotifyOnScrollCallback(WeakPtr pattern, float offset, int32_t source) { diff --git a/frameworks/core/components_ng/pattern/search/search_text_field.cpp b/frameworks/core/components_ng/pattern/search/search_text_field.cpp index d59ebcca1c4..915c1f91bab 100644 --- a/frameworks/core/components_ng/pattern/search/search_text_field.cpp +++ b/frameworks/core/components_ng/pattern/search/search_text_field.cpp @@ -18,7 +18,6 @@ #include "core/components_ng/pattern/search/search_event_hub.h" namespace OHOS::Ace::NG { - bool SearchTextFieldPattern::IsSearchParentNode() const { auto parentFrameNode = AceType::DynamicCast(GetHost()->GetParent()); @@ -50,5 +49,4 @@ TextInputAction SearchTextFieldPattern::GetDefaultTextInputAction() { return TextInputAction::SEARCH; } - } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/search/search_text_field.h b/frameworks/core/components_ng/pattern/search/search_text_field.h index 40caf9e3048..d3f6244fb6a 100644 --- a/frameworks/core/components_ng/pattern/search/search_text_field.h +++ b/frameworks/core/components_ng/pattern/search/search_text_field.h @@ -19,7 +19,6 @@ #include "core/components_ng/pattern/text_field/text_field_pattern.h" namespace OHOS::Ace::NG { - class SearchTextFieldPattern final : public TextFieldPattern { DECLARE_ACE_TYPE(SearchTextFieldPattern, TextFieldPattern); diff --git a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp index 3c928ed6aa4..47d24a2ee03 100644 --- a/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_area/text_area_layout_algorithm.cpp @@ -221,5 +221,4 @@ void TextAreaLayoutAlgorithm::CounterLayout(LayoutWrapper* layoutWrapper) counterNodeLayoutWrapper->Layout(); } } - } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/content_controller.h b/frameworks/core/components_ng/pattern/text_field/content_controller.h index a1a9000a422..6103f0b7c8c 100644 --- a/frameworks/core/components_ng/pattern/text_field/content_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/content_controller.h @@ -28,7 +28,6 @@ #include "core/components_ng/pattern/pattern.h" namespace OHOS::Ace::NG { - class ContentController : public virtual AceType { DECLARE_ACE_TYPE(ContentController, AceType); @@ -87,7 +86,6 @@ private: std::string content_; WeakPtr pattern_; }; - } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_CONTENT_CONTROLLER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index c0442a1c675..024953ce644 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -660,8 +659,7 @@ void TextFieldPattern::InitDisableColor() CHECK_NULL_VOID(theme); if (layoutProperty->GetShowUnderlineValue(false) && IsUnspecifiedOrTextType()) { underlineWidth_ = UNDERLINE_WIDTH; - underlineColor_ = - IsDisabled() ? theme->GetDisableUnderlineColor() : theme->GetUnderlineColor(); + underlineColor_ = IsDisabled() ? theme->GetDisableUnderlineColor() : theme->GetUnderlineColor(); SaveUnderlineStates(); } } @@ -2388,7 +2386,7 @@ bool TextFieldPattern::RequestKeyboard(bool isFocusViewChanged, bool needStartTw LOGI("Start to request keyboard"); if (customKeyboardBulder_) { #if defined(ENABLE_STANDARD_INPUT) && defined(OHOS_STANDARD_SYSTEM) && !defined(PREVIEW) - imeAttached_ = true; + imeAttached_ = true; #endif return RequestCustomKeyboard(); } @@ -2540,7 +2538,6 @@ void TextFieldPattern::InsertValue(const std::string& insertValue) CHECK_NULL_VOID(textFieldLayoutProperty); auto start = selectController_->GetStartIndex(); auto end = selectController_->GetEndIndex(); - // SwapIfLarger(start, end); if (IsSelected()) { LOGI("In select mode, replace selected text"); caretStart = start; diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp index 9c244ba8b83..b4b68f51ebe 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.cpp @@ -337,5 +337,4 @@ void UnitResponseArea::DestoryArea() hostPattern_.Reset(); unitNode_.Reset(); } // UnitResponseArea end - } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h index 3900c1dd45f..f8ac9e21800 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h +++ b/frameworks/core/components_ng/pattern/text_field/text_input_response_area.h @@ -125,7 +125,6 @@ private: bool IsShowUnit(); WeakPtr unitNode_; }; - } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_INPUT_TEXT_INPUT_RESPONSE_AREA_H diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp index ceaa037c35f..5d5b15e2cd9 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.cpp @@ -14,9 +14,6 @@ */ #include "core/components_ng/pattern/text_field/text_select_controller.h" -#include -#include - #include "base/geometry/ng/rect_t.h" #include "base/geometry/offset.h" #include "base/utils/utils.h" @@ -24,7 +21,6 @@ #include "core/components_ng/pattern/text_field/text_field_pattern.h" namespace OHOS::Ace::NG { - void TextSelectController::UpdateHandleIndex(int32_t firstHandleIndex, int32_t secondHandleIndex) { firstHandleInfo_.index = firstHandleIndex; diff --git a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h index 52a0361c842..db0c0a28799 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_select_controller.h +++ b/frameworks/core/components_ng/pattern/text_field/text_select_controller.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include "base/geometry/ng/offset_t.h" #include "base/geometry/ng/rect_t.h" @@ -32,9 +32,7 @@ namespace OHOS::Ace::NG { namespace { - using OnAccessibilityCallback = std::function; - } // namespace class TextSelectController : public Property { @@ -206,7 +204,6 @@ private: OnAccessibilityCallback onAccessibilityCallback_; WeakPtr pattern_; }; - } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_TEXT_SELECT_CONTROLLER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp index f65bd5e6a9c..55591436140 100644 --- a/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp +++ b/frameworks/core/components_ng/pattern/text_input/text_input_layout_algorithm.cpp @@ -192,5 +192,4 @@ void TextInputLayoutAlgorithm::Layout(LayoutWrapper* layoutWrapper) responseArea->Layout(layoutWrapper); } } - } // namespace OHOS::Ace::NG \ No newline at end of file -- Gitee From dc0382a243a2dd55aabaa0fb12e33ee942b96e1e Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Mon, 23 Oct 2023 23:00:07 +0800 Subject: [PATCH 29/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3codecheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I775dcf5f995ea0c399015965e89ee553d2f40bec --- .../select_overlay/select_overlay_client.h | 1 - frameworks/core/components_ng/pattern/BUILD.gn | 4 ++-- .../pattern/text_field/content_controller.cpp | 1 - .../core/components_ng/test/pattern/test_ng.cpp | 15 ++------------- .../core/components_ng/test/pattern/test_ng.h | 10 +++++++--- 5 files changed, 11 insertions(+), 20 deletions(-) diff --git a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h index 85dced50bea..f227630f97e 100644 --- a/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h +++ b/frameworks/core/components_ng/manager/select_overlay/select_overlay_client.h @@ -167,6 +167,5 @@ private: RefPtr selectOverlayProxy_; std::vector menuOptionItems_; }; - } // namespace OHOS::Ace::NG #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_SELECT_OVERLAY_SELECT_OVERLAY_CLIENT_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index 4699ebe707a..0c7385d9f68 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -420,6 +420,7 @@ build_component_ng("pattern_ng") { "text/text_paint_method.cpp", "text/text_pattern.cpp", "text/text_styles.cpp", + "text_area/text_area_layout_algorithm.cpp", "text_clock/text_clock_accessibility_property.cpp", "text_clock/text_clock_layout_algorithm.cpp", "text_clock/text_clock_layout_property.cpp", @@ -428,6 +429,7 @@ build_component_ng("pattern_ng") { "text_drag/text_drag_overlay_modifier.cpp", "text_drag/text_drag_paint_method.cpp", "text_drag/text_drag_pattern.cpp", + "text_input/text_input_layout_algorithm.cpp", "text_picker/textpicker_accessibility_property.cpp", "text_picker/textpicker_column_pattern.cpp", "text_picker/textpicker_dialog_view.cpp", @@ -437,8 +439,6 @@ build_component_ng("pattern_ng") { "text_picker/textpicker_pattern.cpp", "text_picker/textpicker_row_accessibility_property.cpp", "text_picker/toss_animation_controller.cpp", - "text_area/text_area_layout_algorithm.cpp", - "text_input/text_input_layout_algorithm.cpp", "texttimer/text_timer_accessibility_property.cpp", "texttimer/text_timer_layout_algorithm.cpp", "texttimer/text_timer_layout_property.cpp", diff --git a/frameworks/core/components_ng/pattern/text_field/content_controller.cpp b/frameworks/core/components_ng/pattern/text_field/content_controller.cpp index 30560405d1b..8e9b217e282 100644 --- a/frameworks/core/components_ng/pattern/text_field/content_controller.cpp +++ b/frameworks/core/components_ng/pattern/text_field/content_controller.cpp @@ -235,5 +235,4 @@ std::string ContentController::GetValueAfterIndex(int32_t index) { return StringUtils::ToString(GetWideText().substr(index, GetWideText().length() - index)); } - } // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/test/pattern/test_ng.cpp b/frameworks/core/components_ng/test/pattern/test_ng.cpp index 0480d9681aa..a3d03328e54 100644 --- a/frameworks/core/components_ng/test/pattern/test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/test_ng.cpp @@ -13,13 +13,10 @@ * limitations under the License. */ -#define private public #define protected public +#define private public #include "core/components_ng/test/pattern/test_ng.h" -#include "core/components_ng/base/view_stack_processor.h" -#include "core/components_ng/test/mock/render/mock_render_context.h" - namespace OHOS::Ace::NG { void TestNG::SetWidth(const Dimension& width) { @@ -46,7 +43,6 @@ void TestNG::RunMeasureAndLayout(const RefPtr& frameNode, float width LayoutConstraint.selfIdealSize = { width, height }; } LayoutConstraint.maxSize = { DEVICE_WIDTH, DEVICE_HEIGHT }; - frameNode->UpdateLayoutPropertyFlag(); frameNode->Measure(LayoutConstraint); frameNode->Layout(); } @@ -60,11 +56,4 @@ uint64_t TestNG::GetActions(const RefPtr& accessibilityPr } return actions; } - -void TestNG::MockGetPaintRectWithTransform(const RefPtr& frameNode, RectF paintRect) -{ - RefPtr renderContext = AceType::DynamicCast(MockRenderContext::Create()); - EXPECT_CALL(*renderContext, GetPaintRectWithTransform()).WillRepeatedly(Return(paintRect)); - frameNode->renderContext_ = renderContext; -} -} // namespace OHOS::Ace::NG +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/test/pattern/test_ng.h b/frameworks/core/components_ng/test/pattern/test_ng.h index ca68fcedeba..3a276410b03 100644 --- a/frameworks/core/components_ng/test/pattern/test_ng.h +++ b/frameworks/core/components_ng/test/pattern/test_ng.h @@ -18,15 +18,19 @@ #include "gtest/gtest.h" +#include "base/geometry/axis.h" #include "base/geometry/dimension.h" #include "base/memory/ace_type.h" #include "base/memory/referenced.h" +#include "base/utils/utils.h" #include "core/components_ng/base/frame_node.h" #include "core/components_ng/base/view_stack_processor.h" #include "core/components_ng/test/mock/render/mock_render_context.h" namespace OHOS::Ace::NG { namespace { +using namespace testing; +using namespace testing::ext; constexpr int32_t PLATFORM_VERSION_TEN = 10; constexpr int32_t PLATFORM_VERSION_ELEVEN = 11; constexpr float DEVICE_WIDTH = 480.f; @@ -40,8 +44,8 @@ class TestNG { public: static void SetWidth(const Dimension& width); static void SetHeight(const Dimension& height); - void RunMeasureAndLayout( - const RefPtr& frameNode, float width = DEVICE_WIDTH, float height = DEVICE_HEIGHT); + void RunMeasureAndLayout(const RefPtr& frameNode, + float width = DEVICE_WIDTH, float height = DEVICE_HEIGHT); uint64_t GetActions(const RefPtr& accessibilityProperty); AssertionResult IsEqualOverScrollOffset(const OverScrollOffset& actual, const OverScrollOffset& expected) @@ -128,4 +132,4 @@ public: } }; } // namespace OHOS::Ace::NG -#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H \ No newline at end of file -- Gitee From eb2c7f666f284d05145c59aa2078a85123252804 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Mon, 23 Oct 2023 23:38:04 +0800 Subject: [PATCH 30/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3tdd=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: Ic683786d15b03fbcb3ed7f459f4e9c38a6c5aab1 --- frameworks/core/components_ng/test/pattern/BUILD.gn | 1 - .../core/components_ng/test/pattern/grid/grid_test_ng.cpp | 2 +- test/unittest/core/BUILD.gn | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frameworks/core/components_ng/test/pattern/BUILD.gn b/frameworks/core/components_ng/test/pattern/BUILD.gn index 519cd006e2a..944a7fdfb54 100644 --- a/frameworks/core/components_ng/test/pattern/BUILD.gn +++ b/frameworks/core/components_ng/test/pattern/BUILD.gn @@ -81,7 +81,6 @@ group("pattern_unittest") { "text:text_test_ng", "text_clock:text_clock_test_ng", "text_drag:text_drag_test_ng", - "text_field:text_field_test_ng", "text_picker:text_picker_test_ng", "text_timer:text_timer_test_ng", "time_picker:time_picker_test_ng", diff --git a/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp b/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp index 3d865c104be..e00562508e7 100644 --- a/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp +++ b/frameworks/core/components_ng/test/pattern/grid/grid_test_ng.cpp @@ -2627,7 +2627,7 @@ HWTEST_F(GridTestNg, EventHub001, TestSize.Level1) gridModelNG.SetColumnsTemplate("1fr 1fr 1fr 1fr"); CreateVerticalItem(8); }); - RectF gridRect(0.f, 0.f, DEVICE_WIDTH, GRID_HEIGHT); + RectF gridRect(0.f, 0.f, DEVICE_WIDTH, DEVICE_HEIGHT); auto mockRenderContext = AceType::DynamicCast(frameNode_->renderContext_); mockRenderContext->rect_ = gridRect; diff --git a/test/unittest/core/BUILD.gn b/test/unittest/core/BUILD.gn index 8e5bb1a7adc..1dbf1a7b15f 100644 --- a/test/unittest/core/BUILD.gn +++ b/test/unittest/core/BUILD.gn @@ -22,7 +22,6 @@ group("core_unittest") { "common:core_common_unittest", "gestures:gestures_test_ng", "pattern:core_pattern_unittest", - "pipeline:pipeline_context_test_ng", "property:core_property_unittest", "render:render_unittest", ] -- Gitee From 813eeb91a09f5085b5ff3cfe754cd23b537daec0 Mon Sep 17 00:00:00 2001 From: jyj-0306 Date: Tue, 24 Oct 2023 11:28:52 +0800 Subject: [PATCH 31/31] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: jyj-0306 Change-Id: I6942a54437e034e402f35bf5a0acedaffe431ebc --- .../core/components_ng/pattern/text_field/text_field_pattern.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp index 024953ce644..8f7662132ed 100644 --- a/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp +++ b/frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp @@ -2462,7 +2462,6 @@ bool TextFieldPattern::CloseKeyboard(bool forceClose) { LOGI("Request close soft keyboard"); if (forceClose) { - isKeyboardClosedByUser_ = false; StopTwinkling(); CloseSelectOverlay(true); if (customKeyboardBulder_ && isCustomKeyboardAttached_) { -- Gitee