From f77eb8e4de4e6ec12c7544f9498ade141cdc75ed Mon Sep 17 00:00:00 2001 From: xuyue Date: Thu, 29 Feb 2024 14:41:54 +0800 Subject: [PATCH 1/4] =?UTF-8?q?:qY=E3=80=90RichEditor=E3=80=91=E6=8A=BD?= =?UTF-8?q?=E5=8F=96=E6=94=BE=E5=A4=A7=E9=95=9C=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xuyue Change-Id: I5e36edd57a674d3b952ac552e540e9257e6454ea --- .../core/components_ng/pattern/BUILD.gn | 2 + .../pattern/select_overlay/magnifier.h | 36 +++ .../magnifier_controller.cpp | 117 ++++++--- .../magnifier_controller.h | 35 +++ .../select_overlay/magnifier_painter.cpp | 241 ++++++++++++++++++ .../select_overlay/magnifier_painter.h | 53 ++++ .../components_ng/pattern/text/text_base.h | 36 +++ .../components_ng/pattern/text_field/BUILD.gn | 1 - .../text_field_overlay_modifier.cpp | 202 +-------------- .../text_field/text_field_overlay_modifier.h | 4 +- .../pattern/text_field/text_field_pattern.cpp | 43 +--- .../pattern/text_field/text_field_pattern.h | 81 ++---- test/unittest/BUILD.gn | 3 +- .../pattern/text_input/text_input_test.cpp | 8 +- 14 files changed, 521 insertions(+), 341 deletions(-) create mode 100644 frameworks/core/components_ng/pattern/select_overlay/magnifier.h rename frameworks/core/components_ng/pattern/{text_field => select_overlay}/magnifier_controller.cpp (54%) rename frameworks/core/components_ng/pattern/{text_field => select_overlay}/magnifier_controller.h (73%) create mode 100644 frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp create mode 100644 frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.h diff --git a/frameworks/core/components_ng/pattern/BUILD.gn b/frameworks/core/components_ng/pattern/BUILD.gn index d978b2236a8..d450ed71ab7 100644 --- a/frameworks/core/components_ng/pattern/BUILD.gn +++ b/frameworks/core/components_ng/pattern/BUILD.gn @@ -366,6 +366,8 @@ build_component_ng("pattern_ng") { "select/select_layout_algorithm.cpp", "select/select_model_ng.cpp", "select/select_pattern.cpp", + "select_overlay/magnifier_controller.cpp", + "select_overlay/magnifier_painter.cpp", "select_overlay/select_overlay_content_modifier.cpp", "select_overlay/select_overlay_layout_algorithm.cpp", "select_overlay/select_overlay_modifier.cpp", diff --git a/frameworks/core/components_ng/pattern/select_overlay/magnifier.h b/frameworks/core/components_ng/pattern/select_overlay/magnifier.h new file mode 100644 index 00000000000..88a5f65ee3b --- /dev/null +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 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_PATTERNS_MAGNIFIER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MAGNIFIER_H + +#include "base/memory/referenced.h" +#include "base/memory/type_info_base.h" +#include "core/components_ng/pattern/select_overlay/magnifier_controller.h" + +namespace OHOS::Ace::NG { +class Magnifier : public virtual AceType { + DECLARE_ACE_TYPE(Magnifier, AceType); + +public: + RefPtr GetMagnifierController() + { + return magnifierController_; + } + RefPtr magnifierController_; +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MAGNIFIER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text_field/magnifier_controller.cpp b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp similarity index 54% rename from frameworks/core/components_ng/pattern/text_field/magnifier_controller.cpp rename to frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp index 6fb24254b5d..967c13827f1 100644 --- a/frameworks/core/components_ng/pattern/text_field/magnifier_controller.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp @@ -12,7 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "core/components_ng/pattern/text_field/magnifier_controller.h" + +#include "core/components_ng/pattern/select_overlay/magnifier_controller.h" #include "core/components/common/properties/color.h" #include "core/components_ng/pattern/text_field/text_field_pattern.h" @@ -21,13 +22,22 @@ namespace OHOS::Ace::NG { +void MagnifierController::UpdateShowMagnifier(bool isShowMagnifier) +{ + isShowMagnifier_ = isShowMagnifier; + if (isShowMagnifier_) { + OpenMagnifier(); + } else { + CloseMagnifier(); + } +} + void MagnifierController::OpenMagnifier() { auto pattern = pattern_.Upgrade(); CHECK_NULL_VOID(pattern); - auto textFieldpattern = DynamicCast(pattern); - CHECK_NULL_VOID(textFieldpattern); - auto magnifierRect = textFieldpattern->GetMagnifierRect(); + auto textBasePattern = DynamicCast(pattern); + CHECK_NULL_VOID(textBasePattern); if (!magnifierFrameNode_) { CreateMagnifierChildNode(); } @@ -48,15 +58,14 @@ void MagnifierController::OpenMagnifier() CHECK_NULL_VOID(childPattern); auto childContext = magnifierFrameNode_->GetRenderContext(); CHECK_NULL_VOID(childContext); - childContext->UpdatePosition(OffsetT(Dimension(textFieldpattern->GetTextPaintOffset().GetX()), - Dimension(textFieldpattern->GetTextPaintOffset().GetY()))); - childContext->SetContentRectToFrame(RectF( - textFieldpattern->GetTextPaintOffset().GetX(), textFieldpattern->GetTextPaintOffset().GetY(), 0.0f, 0.0f)); + + auto paintOffset = textBasePattern->GetTextPaintOffset(); + childContext->UpdatePosition(OffsetT(Dimension(paintOffset.GetX()), Dimension(paintOffset.GetY()))); + childContext->SetContentRectToFrame(RectF(paintOffset.GetX(), paintOffset.GetY(), 0.0f, 0.0f)); SetMagnifierRect(childPattern); magnifierFrameNode_->ForceSyncGeometryNode(); magnifierFrameNode_->MarkDirtyNode(PROPERTY_UPDATE_RENDER); - return; } void MagnifierController::CloseMagnifier() @@ -64,18 +73,19 @@ void MagnifierController::CloseMagnifier() CHECK_NULL_VOID(magnifierFrameNode_); auto pattern = pattern_.Upgrade(); CHECK_NULL_VOID(pattern); - auto textFieldpattern = DynamicCast(pattern); - CHECK_NULL_VOID(textFieldpattern); + auto textBasePattern = DynamicCast(pattern); + CHECK_NULL_VOID(textBasePattern); + auto layoutProperty = magnifierFrameNode_->GetLayoutProperty(); CHECK_NULL_VOID(layoutProperty); layoutProperty->UpdateVisibility(VisibleType::GONE); - auto magnifierRect = textFieldpattern->GetMagnifierRect(); + auto childContext = magnifierFrameNode_->GetRenderContext(); CHECK_NULL_VOID(childContext); - childContext->UpdatePosition(OffsetT(Dimension(textFieldpattern->GetTextPaintOffset().GetX()), - Dimension(textFieldpattern->GetTextPaintOffset().GetY()))); - childContext->SetContentRectToFrame(RectF( - textFieldpattern->GetTextPaintOffset().GetX(), textFieldpattern->GetTextPaintOffset().GetY(), 0.0f, 0.0f)); + + auto paintOffset = textBasePattern->GetTextPaintOffset(); + childContext->UpdatePosition(OffsetT(Dimension(paintOffset.GetX()), Dimension(paintOffset.GetY()))); + childContext->SetContentRectToFrame(RectF(paintOffset.GetX(), paintOffset.GetY(), 0.0f, 0.0f)); magnifierFrameNode_->ForceSyncGeometryNode(); magnifierFrameNode_->MarkDirtyNode(PROPERTY_UPDATE_RENDER); } @@ -86,8 +96,10 @@ void MagnifierController::CreateMagnifierChildNode() CHECK_NULL_VOID(pattern); auto textFieldpattern = DynamicCast(pattern); CHECK_NULL_VOID(textFieldpattern); + auto host = textFieldpattern->GetHost(); CHECK_NULL_VOID(host); + auto nodeId = ElementRegister::GetInstance()->MakeUniqueId(); ACE_SCOPED_TRACE("Create[%s][self:%d]", V2::TEXTINPUT_ETS_TAG, nodeId); auto childNode = FrameNode::GetOrCreateFrameNode( @@ -96,34 +108,57 @@ void MagnifierController::CreateMagnifierChildNode() magnifierFrameNode_ = childNode; auto childPattern = childNode->GetPattern(); CHECK_NULL_VOID(childPattern); - auto magnifierRect = textFieldpattern->GetMagnifierRect(); - magnifierRect.parent = pattern_; - magnifierRect.childNodeId = childNode->GetId(); - magnifierRect.isChildNode = true; - childPattern->SetMagnifierRect(magnifierRect); - magnifierRect.isChildNode = false; - textFieldpattern->SetMagnifierRect(magnifierRect); + auto childController = childPattern->GetMagnifierController(); + CHECK_NULL_VOID(childController); + + magnifierRect_.parent = pattern_; + magnifierRect_.childNodeId = childNode->GetId(); + magnifierRect_.isChildNode = true; + childController->SetMagnifierRect(magnifierRect_); + magnifierRect_.isChildNode = false; } -void MagnifierController::SetMagnifierRect(const RefPtr& childTextFieldPattern) +void MagnifierController::SetMagnifierRect(const RefPtr& childPattern) { + auto childTextFieldPattern = DynamicCast(childPattern); CHECK_NULL_VOID(childTextFieldPattern); - auto childPattern = DynamicCast(childTextFieldPattern); - CHECK_NULL_VOID(childPattern); - auto pattern = pattern_.Upgrade(); - CHECK_NULL_VOID(pattern); - auto textFieldpattern = DynamicCast(pattern); - CHECK_NULL_VOID(textFieldpattern); - auto magnifierRect = textFieldpattern->GetMagnifierRect(); - magnifierRect.localOffset = textFieldpattern->GetLocalOffset(); - magnifierRect.cursorOffset = textFieldpattern->GetCaretOffset(); - magnifierRect.contentSize = - SizeF(textFieldpattern->GetContentRect().Width(), textFieldpattern->GetContentRect().Height()); - magnifierRect.contentOffset = - OffsetF(textFieldpattern->GetContentRect().GetX(), textFieldpattern->GetContentRect().GetY()); - magnifierRect.isChildNode = true; - childPattern->SetMagnifierRect(magnifierRect); - magnifierRect.isChildNode = false; - textFieldpattern->SetMagnifierRect(magnifierRect); + auto childController = childTextFieldPattern->GetMagnifierController(); + CHECK_NULL_VOID(childController); + + auto textBasepattern = DynamicCast(pattern_.Upgrade()); + CHECK_NULL_VOID(textBasepattern); + + auto contentRect = textBasepattern->GetContentRect(); + magnifierRect_.localOffset = localOffset_; + magnifierRect_.cursorOffset = textBasepattern->GetCaretOffset(); + magnifierRect_.contentSize = SizeF(contentRect.Width(), contentRect.Height()); + magnifierRect_.contentOffset = OffsetF(contentRect.GetX(), contentRect.GetY()); + magnifierRect_.isChildNode = true; + childController->SetMagnifierRect(magnifierRect_); + magnifierRect_.isChildNode = false; +} + +RefPtr MagnifierController::GetPixelMap() +{ + auto pipeline = PipelineContext::GetCurrentContext(); + CHECK_NULL_RETURN(pipeline, NULL); + auto overlayManager = pipeline->GetOverlayManager(); + CHECK_NULL_RETURN(overlayManager, NULL); + auto rootUINode = overlayManager->GetRootNode().Upgrade(); + CHECK_NULL_RETURN(rootUINode, NULL); + auto rootFrameNode = DynamicCast(rootUINode); + CHECK_NULL_RETURN(rootFrameNode, NULL); + + auto context = rootFrameNode->GetRenderContext(); + if (!context) { + UpdateShowMagnifier(); + } + CHECK_NULL_RETURN(context, NULL); + auto pixelMap = context->GetThumbnailPixelMap(); + if (!pixelMap) { + UpdateShowMagnifier(); + } + CHECK_NULL_RETURN(pixelMap, NULL); + return pixelMap; } } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/magnifier_controller.h b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.h similarity index 73% rename from frameworks/core/components_ng/pattern/text_field/magnifier_controller.h rename to frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.h index ff05b153a0f..a66722f2cf1 100644 --- a/frameworks/core/components_ng/pattern/text_field/magnifier_controller.h +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.h @@ -16,6 +16,7 @@ #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_MAGNIFIER_CONTROLLER_H #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_PATTERN_MAGNIFIER_CONTROLLER_H +#include "base/memory/type_info_base.h" #include "base/geometry/ng/offset_t.h" #include "base/geometry/ng/size_t.h" #include "base/image/pixel_map.h" @@ -51,10 +52,44 @@ public: void OpenMagnifier(); void CloseMagnifier(); + RefPtr GetPixelMap(); + + void UpdateShowMagnifier(bool isShowMagnifier = false); + + bool GetShowMagnifier() const + { + return isShowMagnifier_; + } + + void SetMagnifierRect(MagnifierRect magnifierRect) + { + magnifierRect_ = magnifierRect; + } + + MagnifierRect GetMagnifierRect() + { + return magnifierRect_; + } + + void SetLocalOffset(OffsetF localOffset) + { + localOffset_.SetX(localOffset.GetX()); + localOffset_.SetY(localOffset.GetY()); + UpdateShowMagnifier(true); + } + + OffsetF GetLocalOffset() const + { + return localOffset_; + } + private: void CreateMagnifierChildNode(); void SetMagnifierRect(const RefPtr& childPattern); + bool isShowMagnifier_ = false; + MagnifierRect magnifierRect_; + OffsetF localOffset_; WeakPtr pattern_; RefPtr magnifierFrameNode_ = nullptr; }; diff --git a/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp new file mode 100644 index 00000000000..445b9750265 --- /dev/null +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2024 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/select_overlay/magnifier_painter.h" +#include "core/components_ng/pattern/select_overlay/magnifier_controller.h" +#include "core/components_ng/pattern/text_field/text_field_pattern.h" +#include "core/components_ng/render/adapter/pixelmap_image.h" +#include "core/components_ng/render/drawing_prop_convertor.h" +#include "core/components_ng/render/image_painter.h" + +namespace OHOS::Ace::NG { +namespace { +constexpr float MAGNIFIER_GAIN = 1.25f; +constexpr Dimension MAGNIFIER_WIDTH = 140.0_vp; +constexpr Dimension MAGNIFIER_HEIGHT = 48.0_vp; +constexpr Dimension MAGNIFIER_OFFSET_Y = 4.0_vp; +constexpr Dimension PIXEL_MAP_IMAGE_OFFSET = 4.0_vp; +constexpr Dimension MAGNIFIER_BOUNDRY_WIDTH = 1.0_vp; +constexpr Dimension DEFAULT_STATUS_BAR_HEIGHT = 48.0_vp; +} // namespace + +// constructor +MagnifierPainter::MagnifierPainter(const WeakPtr& pattern) : pattern_(pattern) {} + +void MagnifierPainter::PaintMagnifier(RSCanvas& canvas) +{ + auto pattern = DynamicCast(pattern_.Upgrade()); + CHECK_NULL_VOID(pattern); + auto controller = pattern->GetMagnifierController(); + CHECK_NULL_VOID(controller); + + auto textBasePattern = DynamicCast(pattern_.Upgrade()); + CHECK_NULL_VOID(textBasePattern); + + magnifierRect_ = controller->GetMagnifierRect(); + auto parentPattern = DynamicCast(magnifierRect_.parent.Upgrade()); + CHECK_NULL_VOID(parentPattern); + auto parentController = parentPattern->GetMagnifierController(); + CHECK_NULL_VOID(parentController); + + if (!magnifierRect_.isChildNode || !parentController->GetShowMagnifier()) { + return; + } + auto pixelMap = parentController->GetPixelMap(); + CHECK_NULL_VOID(pixelMap); + + if (!GetMagnifierRect(magnifierRect_)) { + return; + } + + canvas.Save(); + RSBrush brush; + brush.SetColor(RSColor::COLOR_WHITE); + brush.SetAntiAlias(true); + canvas.AttachBrush(brush); + + std::vector pathPoints = GetTextPoints(magnifierRect_, false); + auto drawPath = GetPathByPoints(pathPoints); + auto clipPath = GetPathByPoints(pathPoints); + PaintShadow(*drawPath, ShadowConfig::DefaultShadowM, canvas); + canvas.DrawPath(*drawPath); + canvas.ClipPath(*clipPath, RSClipOp::INTERSECT, true); + + auto magnifierGain = MAGNIFIER_GAIN; + auto pixelMapImageOffset = PIXEL_MAP_IMAGE_OFFSET.ConvertToPx(); + + PixelMapImage pixelMapImage(pixelMap); + auto magnifierPaintConfig = pixelMapImage.GetPaintConfig(); + magnifierPaintConfig.scaleX_ = magnifierGain; + magnifierPaintConfig.scaleY_ = magnifierGain; + pixelMapImage.SetPaintConfig(magnifierPaintConfig); + + auto cursorOffsetY = magnifierRect_.cursorOffset.GetY(); + auto localOffsetX = magnifierRect_.localOffset.GetX(); + RectF dstRect; + dstRect.SetRect( + localOffsetX - localOffsetX * magnifierGain - textBasePattern->GetTextPaintOffset().GetX() * magnifierGain, + magnifierRect_.startY - textBasePattern->GetTextPaintOffset().GetY() * magnifierGain + - cursorOffsetY * magnifierGain + pixelMapImageOffset, + pixelMap->GetWidth() * magnifierGain, pixelMap->GetHeight() * magnifierGain); + pixelMapImage.DrawRect(canvas, ToRSRect(dstRect)); + + canvas.DetachBrush(); + canvas.Restore(); +} + +bool MagnifierPainter::GetMagnifierRect(MagnifierRect& rect) +{ + auto localOffsetX = magnifierRect_.localOffset.GetX(); + auto cursorOffsetY = magnifierRect_.cursorOffset.GetY(); + return GetMagnifierRect(rect.startX, rect.startY, rect.endX, rect.endY, localOffsetX, cursorOffsetY); +} + +bool MagnifierPainter::GetMagnifierRect( + float& startX, float& startY, float& endX, float& endY, float& localOffsetX, float& cursorOffsetY) +{ + auto textDragBasePattern = DynamicCast(magnifierRect_.parent.Upgrade()); + auto textBasePattern = DynamicCast(magnifierRect_.parent.Upgrade()); + CHECK_NULL_RETURN(textDragBasePattern, false); + CHECK_NULL_RETURN(textBasePattern, false); + + auto cursorOffsetX = magnifierRect_.cursorOffset.GetX(); + auto magnifierWidth = MAGNIFIER_WIDTH.ConvertToPx(); + auto magnifierHeight = MAGNIFIER_HEIGHT.ConvertToPx(); + auto magnifierOffsetY = MAGNIFIER_OFFSET_Y.ConvertToPx(); + auto localOffsetY = magnifierRect_.localOffset.GetY(); + localOffsetX = std::max(localOffsetX, magnifierRect_.contentOffset.GetX()); + localOffsetX = std::min(localOffsetX, magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX()); + auto textBoxesLeft = 0.0f; + if (!textDragBasePattern->GetTextBoxes().empty()) { + textBoxesLeft = textDragBasePattern->GetTextBoxes()[0].Left(); + } + auto firstHandleOffsetY = textBasePattern->GetFirstHandleOffset().GetY(); + auto secondHandleOffsetY = textBasePattern->GetSecondHandleOffset().GetY(); + if (textBasePattern->IsSelected() && firstHandleOffsetY != secondHandleOffsetY && + localOffsetY < firstHandleOffsetY + textDragBasePattern->GetLineHeight() && + localOffsetY < secondHandleOffsetY + textDragBasePattern->GetLineHeight()) { + if (firstHandleOffsetY < secondHandleOffsetY) { + cursorOffsetY = firstHandleOffsetY; + } else if (secondHandleOffsetY < firstHandleOffsetY) { + cursorOffsetY = secondHandleOffsetY; + } + } + startY = cursorOffsetY - magnifierHeight - magnifierOffsetY; + if ((textDragBasePattern->GetParentGlobalOffset().GetY() + startY) < DEFAULT_STATUS_BAR_HEIGHT.ConvertToPx()) { + startY = cursorOffsetY + textDragBasePattern->GetLineHeight() + magnifierHeight + magnifierOffsetY; + } + startX = localOffsetX - magnifierWidth / 2.0f; + if (((textBasePattern->GetCaretIndex() == textBasePattern->GetContentWideTextLength() + && localOffsetX >= cursorOffsetX) || (textBasePattern->GetCaretIndex() == 0 && localOffsetX <= cursorOffsetX)) + && (cursorOffsetY == textBasePattern->GetCaretOffset().GetY())) { + startX = cursorOffsetX - magnifierWidth / 2.0f; + localOffsetX = cursorOffsetX; + } + startX = std::max(startX, 0.0f); + endX = startX + magnifierWidth; + endY = startY; + if (endX > magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX() * 2.0f) { + endX = magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX() * 2.0f; + startX = endX - magnifierWidth; + } + return true; +} + +std::vector MagnifierPainter::GetTextPoints(const MagnifierRect& rect, bool haveOffset) +{ + return GetTextPoints(rect.startX, rect.startY, rect.endX, rect.endY, haveOffset); +} + +std::vector MagnifierPainter::GetTextPoints( + float startX, float startY, float endX, float endY, bool haveOffset) +{ + std::vector textPoints; + auto lineHeight = MAGNIFIER_HEIGHT.ConvertToPx(); + auto offset = MAGNIFIER_BOUNDRY_WIDTH.ConvertToPx(); + if (haveOffset) { + textPoints.emplace_back(TextPoint(startX - offset, startY - offset)); + textPoints.emplace_back(TextPoint(endX + offset, endY - offset)); + textPoints.emplace_back(TextPoint(endX + offset, endY + lineHeight + offset)); + textPoints.emplace_back(TextPoint(startX - offset, endY + lineHeight + offset)); + textPoints.emplace_back(TextPoint(startX - offset, endY - offset)); + textPoints.emplace_back(TextPoint(endX + offset, endY - offset)); + return textPoints; + } + textPoints.emplace_back(TextPoint(startX, startY)); + textPoints.emplace_back(TextPoint(endX, endY)); + textPoints.emplace_back(TextPoint(endX, endY + lineHeight)); + textPoints.emplace_back(TextPoint(startX, endY + lineHeight)); + textPoints.emplace_back(TextPoint(startX, endY)); + textPoints.emplace_back(TextPoint(endX, endY)); + return textPoints; +} + +std::shared_ptr MagnifierPainter::GetPathByPoints(const std::vector& points) +{ + std::shared_ptr path = std::make_shared(); + auto radius = MAGNIFIER_HEIGHT.ConvertToPx() / 2.0f; + path->MoveTo(points[0].x + radius, points[0].y); + size_t step = 2; + for (size_t i = 0; i + step < points.size(); i++) { + auto firstPoint = points[i]; + auto crossPoint = points[i + 1]; + auto secondPoint = points[i + step]; + + if (crossPoint.y == firstPoint.y) { + int32_t directionX = (crossPoint.x - firstPoint.x) > 0 ? 1 : -1; + int32_t directionY = (secondPoint.y - crossPoint.y) > 0 ? 1 : -1; + auto direction = + (directionX * directionY > 0) ? RSPathDirection::CW_DIRECTION : RSPathDirection::CCW_DIRECTION; + path->LineTo(crossPoint.x - radius * directionX, crossPoint.y); + path->ArcTo(radius, radius, 0.0f, direction, crossPoint.x, crossPoint.y + radius * directionY); + } else { + int32_t directionX = (secondPoint.x - crossPoint.x) > 0 ? 1 : -1; + int32_t directionY = (crossPoint.y - firstPoint.y) > 0 ? 1 : -1; + auto direction = + (directionX * directionY < 0) ? RSPathDirection::CW_DIRECTION : RSPathDirection::CCW_DIRECTION; + path->LineTo(crossPoint.x, crossPoint.y - radius * directionY); + path->ArcTo(radius, radius, 0.0f, direction, crossPoint.x + radius * directionX, secondPoint.y); + } + } + return path; +} + +void MagnifierPainter::PaintShadow(const RSPath& path, const Shadow& shadow, RSCanvas& canvas) +{ + canvas.Save(); +#ifndef USE_ROSEN_DRAWING + RSPath rsPath = path; +#else + RSRecordingPath rsPath; + rsPath.AddPath(path); +#endif + rsPath.Offset(shadow.GetOffset().GetX(), shadow.GetOffset().GetY()); + RSColor spotColor = ToRSColor(shadow.GetColor()); + RSPoint3 planeParams = { 0.0f, 0.0f, shadow.GetElevation() }; +#ifndef USE_ROSEN_DRAWING + RSPoint3 lightPos = { rsPath.GetBounds().GetLeft() / 2 + rsPath.GetBounds().GetRight(), + rsPath.GetBounds().GetTop() / 2.0 + rsPath.GetBounds().GetBottom() / 2.0, shadow.GetLightHeight() }; +#else + auto bounds = rsPath.GetBounds(); + RSPoint3 lightPos = { bounds.GetLeft() / 2.0 + bounds.GetRight() / 2.0, + bounds.GetTop() / 2.0 + bounds.GetBottom() / 2.0, shadow.GetLightHeight() }; +#endif + RSColor ambientColor = RSColor(0, 0, 0, 0); + canvas.DrawShadow(rsPath, planeParams, lightPos, shadow.GetLightRadius(), ambientColor, spotColor, + RSShadowFlags::TRANSPARENT_OCCLUDER); + canvas.Restore(); +} +} // namespace OHOS::Ace::NG \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.h b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.h new file mode 100644 index 00000000000..fe7085b10d4 --- /dev/null +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024 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_PATTERNS_MAGNIFIER_PAINTER_H +#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MAGNIFIER_PAINTER_H + +#include +#include +#include "base/memory/referenced.h" +#include "base/memory/type_info_base.h" +#include "core/components_ng/base/modifier.h" +#include "core/components_ng/pattern/text_drag/text_drag_pattern.h" +#include "core/components_ng/pattern/select_overlay/magnifier_controller.h" +#include "core/components_ng/render/drawing_forward.h" +#include "core/components/common/properties/shadow.h" + +namespace OHOS::Ace::NG { + +class MagnifierPainter : public virtual AceType { + DECLARE_ACE_TYPE(MagnifierPainter, AceType); + +public: + MagnifierPainter(const WeakPtr& pattern); + void PaintMagnifier(RSCanvas& canvas); + +private: + bool GetMagnifierRect(MagnifierRect& rect); + bool GetMagnifierRect( + float& startX, float& startY, float& endX, float& endY, float& localOffsetX, float& cursorOffsetY); + std::vector GetTextPoints(const MagnifierRect& rect, bool haveOffset); + std::vector GetTextPoints( + float startX, float startY, float endX, float endY, bool haveOffset); + std::shared_ptr GetPathByPoints(const std::vector& points); + void PaintShadow(const RSPath& path, const Shadow& shadow, RSCanvas& canvas); + + WeakPtr pattern_; + MagnifierRect magnifierRect_; +}; +} // namespace OHOS::Ace::NG + +#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_MAGNIFIER_PAINTER_H \ No newline at end of file diff --git a/frameworks/core/components_ng/pattern/text/text_base.h b/frameworks/core/components_ng/pattern/text/text_base.h index 2acd4648b4a..17b4f4e8996 100644 --- a/frameworks/core/components_ng/pattern/text/text_base.h +++ b/frameworks/core/components_ng/pattern/text/text_base.h @@ -181,12 +181,48 @@ public: virtual void GetCaretMetrics(CaretMetricsF& caretCaretMetric) {} virtual void OnVirtualKeyboardAreaChanged() {} + + const RectF& GetContentRect() const + { + return contentRect_; + } + + virtual int32_t GetContentWideTextLength() + { + return 0; + } + + virtual int32_t GetCaretIndex() const + { + return 0; + } + + virtual OffsetF GetCaretOffset() const + { + return OffsetF(); + } + + virtual OffsetF GetTextPaintOffset() const + { + return OffsetF(); + } + + virtual OffsetF GetFirstHandleOffset() const + { + return OffsetF(); + } + + virtual OffsetF GetSecondHandleOffset() const + { + return OffsetF(); + } protected: TextSelector textSelector_; bool showSelect_ = true; std::vector dragContents_; MouseStatus mouseStatus_ = MouseStatus::NONE; + RectF contentRect_; ACE_DISALLOW_COPY_AND_MOVE(TextBase); }; } // namespace OHOS::Ace::NG diff --git a/frameworks/core/components_ng/pattern/text_field/BUILD.gn b/frameworks/core/components_ng/pattern/text_field/BUILD.gn index cd9edb02638..5b6fa813bc9 100644 --- a/frameworks/core/components_ng/pattern/text_field/BUILD.gn +++ b/frameworks/core/components_ng/pattern/text_field/BUILD.gn @@ -17,7 +17,6 @@ import( build_component_ng("text_field_pattern_ng") { sources = [ "content_controller.cpp", - "magnifier_controller.cpp", "text_field_accessibility_property.cpp", "text_field_content_modifier.cpp", "text_field_controller.cpp", 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 949190453c4..556fc5d2ca5 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 @@ -24,19 +24,9 @@ #include "core/components_ng/render/image_painter.h" namespace OHOS::Ace::NG { -namespace { -constexpr float MAGNIFIER_GAIN = 1.25f; -constexpr Dimension MAGNIFIER_WIDTH = 140.0_vp; -constexpr Dimension MAGNIFIER_HEIGHT = 48.0_vp; -constexpr Dimension MAGNIFIER_OFFSET_Y = 4.0_vp; -constexpr Dimension PIXEL_MAP_IMAGE_OFFSET = 4.0_vp; -constexpr Dimension MAGNIFIER_BOUNDRY_WIDTH = 1.0_vp; -constexpr Dimension DEFAULT_STATUS_BAR_HEIGHT = 48.0_vp; -} // namespace - TextFieldOverlayModifier::TextFieldOverlayModifier( const WeakPtr& pattern, WeakPtr&& edgeEffect) - : pattern_(pattern), edgeEffect_(edgeEffect) + : pattern_(pattern), edgeEffect_(edgeEffect), magnifierPainter_(pattern) { auto textFieldPattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(textFieldPattern); @@ -104,7 +94,7 @@ void TextFieldOverlayModifier::onDraw(DrawingContext& context) PaintScrollBar(context); PaintEdgeEffect(frameSize_->Get(), context.canvas); PaintUnderline(context.canvas); - PaintMagnifier(context); + magnifierPainter_.PaintMagnifier(context.canvas); } void TextFieldOverlayModifier::GetFrameRectClip(RSRect& clipRect, std::vector& clipRadius) @@ -225,7 +215,9 @@ void TextFieldOverlayModifier::PaintCursor(DrawingContext& context) const auto& canvas = context.canvas; auto textFieldPattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(textFieldPattern); - if (textFieldPattern->GetShowMagnifier()) { + auto magnifierController = textFieldPattern->GetMagnifierController(); + CHECK_NULL_VOID(magnifierController); + if (magnifierController->GetShowMagnifier()) { cursorVisible_->Set(true); } if (!cursorVisible_->Get() || textFieldPattern->IsSelected()) { @@ -268,190 +260,6 @@ void TextFieldOverlayModifier::PaintScrollBar(DrawingContext& context) } } -void TextFieldOverlayModifier::PaintMagnifier(DrawingContext& context) -{ - auto pattern = DynamicCast(pattern_.Upgrade()); - CHECK_NULL_VOID(pattern); - magnifierRect_ = pattern->GetMagnifierRect(); - auto textFieldpattern = DynamicCast(magnifierRect_.parent.Upgrade()); - CHECK_NULL_VOID(textFieldpattern); - if (!magnifierRect_.isChildNode || !textFieldpattern->GetShowMagnifier()) { - return; - } - auto pixelMap = textFieldpattern->GetPixelMap(); - CHECK_NULL_VOID(pixelMap); - auto& canvas = context.canvas; - canvas.Save(); - - auto cursorOffsetY = magnifierRect_.cursorOffset.GetY(); - auto localOffsetX = magnifierRect_.localOffset.GetX(); - if (!GetMagnifierRect(magnifierRect_.startX, magnifierRect_.startY, magnifierRect_.endX, magnifierRect_.endY, - localOffsetX, cursorOffsetY)) { - return; - } - - RSBrush brush; - brush.SetColor(RSColor::COLOR_WHITE); - brush.SetAntiAlias(true); - canvas.AttachBrush(brush); - - std::vector drawPathPoints = - GetTextPoints(magnifierRect_.startX, magnifierRect_.startY, magnifierRect_.endX, magnifierRect_.endY, false); - auto drawPath = GetPathByPoints(drawPathPoints); - PaintShadow(*drawPath, ShadowConfig::DefaultShadowM, canvas); - canvas.DrawPath(*drawPath); - std::vector clipPathPoints = - GetTextPoints(magnifierRect_.startX, magnifierRect_.startY, magnifierRect_.endX, magnifierRect_.endY, false); - auto clipPath = GetPathByPoints(clipPathPoints); - canvas.ClipPath(*clipPath, RSClipOp::INTERSECT, true); - - auto magnifierGain = MAGNIFIER_GAIN; - auto pixelMapImageOffset = PIXEL_MAP_IMAGE_OFFSET.ConvertToPx(); - - PixelMapImage pixelMapImage(pixelMap); - auto magnifierPaintConfig = pixelMapImage.GetPaintConfig(); - magnifierPaintConfig.scaleX_ = magnifierGain; - magnifierPaintConfig.scaleY_ = magnifierGain; - pixelMapImage.SetPaintConfig(magnifierPaintConfig); - - RectF dstRect; - dstRect.SetRect(localOffsetX - localOffsetX * magnifierGain - pattern->GetTextPaintOffset().GetX() * magnifierGain, - magnifierRect_.startY - pattern->GetTextPaintOffset().GetY() * magnifierGain - cursorOffsetY * magnifierGain + - pixelMapImageOffset, - pixelMap->GetWidth() * magnifierGain, pixelMap->GetHeight() * magnifierGain); - pixelMapImage.DrawRect(canvas, ToRSRect(dstRect)); - - canvas.DetachBrush(); - canvas.Restore(); -} - -bool TextFieldOverlayModifier::GetMagnifierRect( - float& startX, float& startY, float& endX, float& endY, float& localOffsetX, float& cursorOffsetY) -{ - auto pattern = DynamicCast(magnifierRect_.parent.Upgrade()); - CHECK_NULL_RETURN(pattern, false); - auto cursorOffsetX = magnifierRect_.cursorOffset.GetX(); - auto magnifierWidth = MAGNIFIER_WIDTH.ConvertToPx(); - auto magnifierHeight = MAGNIFIER_HEIGHT.ConvertToPx(); - auto magnifierOffsetY = MAGNIFIER_OFFSET_Y.ConvertToPx(); - auto localOffsetY = magnifierRect_.localOffset.GetY(); - localOffsetX = std::max(localOffsetX, magnifierRect_.contentOffset.GetX()); - localOffsetX = std::min(localOffsetX, magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX()); - auto textBoxesLeft = 0.0f; - if (!pattern->GetTextBoxes().empty()) { - textBoxesLeft = pattern->GetTextBoxes()[0].Left(); - } - auto firstHandleOffsetY = pattern->GetTextSelectController()->GetFirstHandleOffset().GetY(); - auto secondHandleOffsetY = pattern->GetTextSelectController()->GetSecondHandleOffset().GetY(); - if (pattern->IsSelected() && firstHandleOffsetY != secondHandleOffsetY && - localOffsetY < firstHandleOffsetY + pattern->GetLineHeight() && - localOffsetY < secondHandleOffsetY + pattern->GetLineHeight()) { - if (firstHandleOffsetY < secondHandleOffsetY) { - cursorOffsetY = firstHandleOffsetY; - } else if (secondHandleOffsetY < firstHandleOffsetY) { - cursorOffsetY = secondHandleOffsetY; - } - } - startY = cursorOffsetY - magnifierHeight - magnifierOffsetY; - if ((pattern->GetParentGlobalOffset().GetY() + startY) < DEFAULT_STATUS_BAR_HEIGHT.ConvertToPx()) { - startY = cursorOffsetY + pattern->GetLineHeight() + magnifierHeight + magnifierOffsetY; - } - startX = localOffsetX - magnifierWidth / 2.0f; - if (((pattern->GetCaretIndex() == pattern->GetContentWideTextLength() && localOffsetX >= cursorOffsetX) || - (pattern->GetCaretIndex() == 0 && localOffsetX <= cursorOffsetX)) && - (cursorOffsetY == pattern->GetCaretOffset().GetY())) { - startX = cursorOffsetX - magnifierWidth / 2.0f; - localOffsetX = cursorOffsetX; - } - startX = std::max(startX, 0.0f); - endX = startX + magnifierWidth; - endY = startY; - if (endX > magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX() * 2.0f) { - endX = magnifierRect_.contentSize.Width() + magnifierRect_.contentOffset.GetX() * 2.0f; - startX = endX - magnifierWidth; - } - return true; -} - -std::vector TextFieldOverlayModifier::GetTextPoints( - float startX, float startY, float endX, float endY, bool haveOffset) -{ - std::vector textPoints; - auto lineHeight = MAGNIFIER_HEIGHT.ConvertToPx(); - auto offset = MAGNIFIER_BOUNDRY_WIDTH.ConvertToPx(); - if (haveOffset) { - textPoints.emplace_back(TextPoint(startX - offset, startY - offset)); - textPoints.emplace_back(TextPoint(endX + offset, endY - offset)); - textPoints.emplace_back(TextPoint(endX + offset, endY + lineHeight + offset)); - textPoints.emplace_back(TextPoint(startX - offset, endY + lineHeight + offset)); - textPoints.emplace_back(TextPoint(startX - offset, endY - offset)); - textPoints.emplace_back(TextPoint(endX + offset, endY - offset)); - return textPoints; - } - textPoints.emplace_back(TextPoint(startX, startY)); - textPoints.emplace_back(TextPoint(endX, endY)); - textPoints.emplace_back(TextPoint(endX, endY + lineHeight)); - textPoints.emplace_back(TextPoint(startX, endY + lineHeight)); - textPoints.emplace_back(TextPoint(startX, endY)); - textPoints.emplace_back(TextPoint(endX, endY)); - return textPoints; -} - -std::shared_ptr TextFieldOverlayModifier::GetPathByPoints(std::vector points) -{ - std::shared_ptr path = std::make_shared(); - auto radius = MAGNIFIER_HEIGHT.ConvertToPx() / 2.0f; - path->MoveTo(points[0].x + radius, points[0].y); - size_t step = 2; - for (size_t i = 0; i + step < points.size(); i++) { - auto firstPoint = points[i]; - auto crossPoint = points[i + 1]; - auto secondPoint = points[i + step]; - - if (crossPoint.y == firstPoint.y) { - int32_t directionX = (crossPoint.x - firstPoint.x) > 0 ? 1 : -1; - int32_t directionY = (secondPoint.y - crossPoint.y) > 0 ? 1 : -1; - auto direction = - (directionX * directionY > 0) ? RSPathDirection::CW_DIRECTION : RSPathDirection::CCW_DIRECTION; - path->LineTo(crossPoint.x - radius * directionX, crossPoint.y); - path->ArcTo(radius, radius, 0.0f, direction, crossPoint.x, crossPoint.y + radius * directionY); - } else { - int32_t directionX = (secondPoint.x - crossPoint.x) > 0 ? 1 : -1; - int32_t directionY = (crossPoint.y - firstPoint.y) > 0 ? 1 : -1; - auto direction = - (directionX * directionY < 0) ? RSPathDirection::CW_DIRECTION : RSPathDirection::CCW_DIRECTION; - path->LineTo(crossPoint.x, crossPoint.y - radius * directionY); - path->ArcTo(radius, radius, 0.0f, direction, crossPoint.x + radius * directionX, secondPoint.y); - } - } - return path; -} -void TextFieldOverlayModifier::PaintShadow(const RSPath& path, const Shadow& shadow, RSCanvas& canvas) -{ - canvas.Save(); -#ifndef USE_ROSEN_DRAWING - RSPath rsPath = path; -#else - RSRecordingPath rsPath; - rsPath.AddPath(path); -#endif - rsPath.Offset(shadow.GetOffset().GetX(), shadow.GetOffset().GetY()); - RSColor spotColor = ToRSColor(shadow.GetColor()); - RSPoint3 planeParams = { 0.0f, 0.0f, shadow.GetElevation() }; -#ifndef USE_ROSEN_DRAWING - RSPoint3 lightPos = { rsPath.GetBounds().GetLeft() / 2 + rsPath.GetBounds().GetRight(), - rsPath.GetBounds().GetTop() / 2.0 + rsPath.GetBounds().GetBottom() / 2.0, shadow.GetLightHeight() }; -#else - auto bounds = rsPath.GetBounds(); - RSPoint3 lightPos = { bounds.GetLeft() / 2.0 + bounds.GetRight() / 2.0, - bounds.GetTop() / 2.0 + bounds.GetBottom() / 2.0, shadow.GetLightHeight() }; -#endif - RSColor ambientColor = RSColor(0, 0, 0, 0); - canvas.DrawShadow(rsPath, planeParams, lightPos, shadow.GetLightRadius(), ambientColor, spotColor, - RSShadowFlags::TRANSPARENT_OCCLUDER); - canvas.Restore(); -} - void TextFieldOverlayModifier::SetCursorColor(Color& value) { cursorColor_->Set(LinearColor(value)); 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 e51704112f9..e956eccc427 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 @@ -27,11 +27,11 @@ #include "core/components_ng/pattern/scroll/inner/scroll_bar_overlay_modifier.h" #include "core/components_ng/pattern/scroll/scroll_edge_effect.h" #include "core/components_ng/pattern/text_drag/text_drag_pattern.h" -#include "core/components_ng/pattern/text_field/magnifier_controller.h" #include "core/components_ng/pattern/text_field/text_field_paint_property.h" #include "core/components_ng/property/property.h" #include "core/components_ng/render/animation_utils.h" #include "core/components_ng/render/drawing.h" +#include "core/components_ng/pattern/select_overlay/magnifier_painter.h" namespace OHOS::Ace::NG { class TextFieldOverlayModifier : public ScrollBarOverlayModifier { @@ -102,7 +102,7 @@ private: RefPtr frameSize_; RefPtr changeSelectedRects_; RectF textRect_; - MagnifierRect magnifierRect_; + MagnifierPainter magnifierPainter_; ACE_DISALLOW_COPY_AND_MOVE(TextFieldOverlayModifier); }; } // 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 62ab41541af..98ca5b33460 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 @@ -979,7 +979,7 @@ void TextFieldPattern::HandleBlurEvent() needToRequestKeyboardInner_ = false; isLongPress_ = false; isFocusedBeforeClick_ = false; - UpdateShowMagnifier(); + magnifierController_->UpdateShowMagnifier(); CloseSelectOverlay(!isKeyboardClosedByUser_); StopTwinkling(); if ((customKeyboardBuilder_ && isCustomKeyboardAttached_)) { @@ -1388,8 +1388,8 @@ void TextFieldPattern::HandleTouchUp() if (isMousePressed_) { isMousePressed_ = false; } - if (GetShowMagnifier()) { - UpdateShowMagnifier(); + if (magnifierController_->GetShowMagnifier()) { + magnifierController_->UpdateShowMagnifier(); } if (enableTouchAndHoverEffect_ && !HasStateStyle(UI_STATE_PRESSED)) { auto tmpHost = GetHost(); @@ -2637,7 +2637,7 @@ void TextFieldPattern::OnHandleMove(const RectF& handleRect, bool isFirstHandle) CHECK_NULL_VOID(SelectOverlayIsOn()); CHECK_NULL_VOID(!contentController_->IsEmpty()); auto localOffset = handleRect.GetOffset() - parentGlobalOffset_; - SetLocalOffset(localOffset); + magnifierController_->SetLocalOffset(localOffset); if (isSingleHandle_) { selectController_->UpdateCaretInfoByOffset(Offset(localOffset.GetX(), localOffset.GetY())); } else { @@ -2712,7 +2712,7 @@ void TextFieldPattern::UpdateCopyAllStatus() void TextFieldPattern::OnHandleMoveDone(const RectF& /* handleRect */, bool isFirstHandle) { UpdateCopyAllStatus(); - UpdateShowMagnifier(); + magnifierController_->UpdateShowMagnifier(); auto proxy = GetSelectOverlayProxy(); CHECK_NULL_VOID(proxy); if (!isSingleHandle_) { @@ -2745,8 +2745,8 @@ void TextFieldPattern::OnHandleClosed(bool closedByGlobalEvent) if (closedByGlobalEvent) { UpdateSelectMenuVisibility(false); } - if (GetShowMagnifier()) { - UpdateShowMagnifier(); + if (magnifierController_->GetShowMagnifier()) { + magnifierController_->UpdateShowMagnifier(); } } @@ -3340,9 +3340,6 @@ void TextFieldPattern::UpdateObscure(const std::string& insertValue, bool hasIns void TextFieldPattern::InsertValue(const std::string& insertValue) { - if (!HasFocus()) { - return; - } if (focusIndex_ != FocuseIndex::TEXT && insertValue == " ") { HandleSpaceEvent(); return; @@ -4620,7 +4617,7 @@ void TextFieldPattern::SetCaretPosition(int32_t position) { TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "Set caret position to %{public}d", position); selectController_->MoveCaretToContentRect(position, TextAffinity::DOWNSTREAM); - if (HasFocus() && !GetShowMagnifier()) { + if (HasFocus() && !magnifierController_->GetShowMagnifier()) { StartTwinkling(); FireOnSelectionChange(position, position); } @@ -6471,30 +6468,6 @@ void TextFieldPattern::ScrollToSafeArea() const textFieldManager->ScrollTextFieldToSafeArea(); } -RefPtr TextFieldPattern::GetPixelMap() -{ - auto pipeline = PipelineContext::GetCurrentContext(); - CHECK_NULL_RETURN(pipeline, NULL); - auto overlayManager = pipeline->GetOverlayManager(); - CHECK_NULL_RETURN(overlayManager, NULL); - auto rootUINode = overlayManager->GetRootNode().Upgrade(); - CHECK_NULL_RETURN(rootUINode, NULL); - auto rootFrameNode = DynamicCast(rootUINode); - CHECK_NULL_RETURN(rootFrameNode, NULL); - - auto context = rootFrameNode->GetRenderContext(); - if (!context) { - UpdateShowMagnifier(); - } - CHECK_NULL_RETURN(context, NULL); - auto pixelMap = context->GetThumbnailPixelMap(); - if (!pixelMap) { - UpdateShowMagnifier(); - } - CHECK_NULL_RETURN(pixelMap, NULL); - return pixelMap; -} - void TextFieldPattern::ShowMenu() { auto selectOverlayProxy = GetSelectOverlayProxy(); 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 0518f68f720..4a1933ba06d 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 @@ -50,7 +50,6 @@ #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/magnifier_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" @@ -63,6 +62,8 @@ #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/components_ng/pattern/select_overlay/magnifier_controller.h" +#include "core/components_ng/pattern/select_overlay/magnifier.h" #if not defined(ACE_UNITTEST) #if defined(ENABLE_STANDARD_INPUT) @@ -145,8 +146,10 @@ class TextFieldPattern : public ScrollablePattern, public TextDragBase, public ValueChangeObserver, public TextInputClient, - public TextBase { - DECLARE_ACE_TYPE(TextFieldPattern, ScrollablePattern, TextDragBase, ValueChangeObserver, TextInputClient, TextBase); + public TextBase, + public Magnifier { + DECLARE_ACE_TYPE(TextFieldPattern, ScrollablePattern, TextDragBase, ValueChangeObserver, TextInputClient, TextBase, + Magnifier); public: TextFieldPattern(); @@ -316,11 +319,21 @@ public: return contentController_->GetWideText(); } - int32_t GetCaretIndex() const + int32_t GetCaretIndex() const override { return selectController_->GetCaretIndex(); } + OffsetF GetFirstHandleOffset() const override + { + return selectController_->GetFirstHandleOffset(); + } + + OffsetF GetSecondHandleOffset() const override + { + return selectController_->GetSecondHandleOffset(); + } + ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(TextInputAction, TextInputAction) const RefPtr& GetParagraph() const @@ -355,7 +368,7 @@ public: return rightClickOffset_; } - OffsetF GetCaretOffset() const + OffsetF GetCaretOffset() const override { return selectController_->GetCaretRect().GetOffset(); } @@ -442,11 +455,6 @@ public: textRect_ = textRect; } - const RectF& GetContentRect() const - { - return contentRect_; - } - const RectF& GetFrameRect() const { return frameRect_; @@ -1023,38 +1031,9 @@ public: bool HandleSpaceEvent(); - RefPtr GetPixelMap(); - - void UpdateShowMagnifier(bool isShowMagnifier = false) - { - isShowMagnifier_ = isShowMagnifier; - if (isShowMagnifier_) { - magnifierController_->OpenMagnifier(); - } else { - magnifierController_->CloseMagnifier(); - } - } - - bool GetShowMagnifier() const - { - return isShowMagnifier_; - } - virtual void InitBackGroundColorAndBorderRadius(); - void SetLocalOffset(OffsetF localOffset) - { - localOffset_.SetX(localOffset.GetX()); - localOffset_.SetY(localOffset.GetY()); - UpdateShowMagnifier(true); - } - - OffsetF GetLocalOffset() const - { - return localOffset_; - } - - int32_t GetContentWideTextLength() + int32_t GetContentWideTextLength() override { return static_cast(contentController_->GetWideText().length()); } @@ -1089,22 +1068,7 @@ public: void GetCaretMetrics(CaretMetricsF& caretCaretMetric) override; - void SetMagnifierRect(MagnifierRect magnifierRect) - { - magnifierRect_ = magnifierRect; - } - - MagnifierRect GetMagnifierRect() - { - return magnifierRect_; - } - - OffsetF GetTextPaintOffset() const; - - const RefPtr& GetMagnifierController() - { - return magnifierController_; - } + OffsetF GetTextPaintOffset() const override; void NeedRequestKeyboard() { @@ -1282,7 +1246,6 @@ private: void UpdateOverlaySelectArea(); RectF frameRect_; - RectF contentRect_; RectF textRect_; RefPtr paragraph_; RefPtr errorParagraph_; @@ -1432,16 +1395,12 @@ private: bool isSupportCameraInput_ = false; std::function processOverlayDelayTask_; FocuseIndex focusIndex_ = FocuseIndex::TEXT; - bool isShowMagnifier_ = false; - OffsetF localOffset_; bool isTouchCaret_ = false; bool needSelectAll_ = false; bool isModifyDone_ = false; bool initTextRect_ = false; bool colorModeChange_ = false; Offset clickLocation_; - MagnifierRect magnifierRect_; - RefPtr magnifierController_; bool isKeyboardClosedByUser_ = false; bool lockRecord_ = false; }; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 0f7277251dd..4f90e22106c 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -846,6 +846,8 @@ ohos_source_set("ace_components_pattern") { "$ace_root/frameworks/core/components_ng/pattern/select/select_layout_algorithm.cpp", "$ace_root/frameworks/core/components_ng/pattern/select/select_model_ng.cpp", "$ace_root/frameworks/core/components_ng/pattern/select/select_pattern.cpp", + "$ace_root/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp", + "$ace_root/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.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", @@ -931,7 +933,6 @@ ohos_source_set("ace_components_pattern") { "$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/magnifier_controller.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", diff --git a/test/unittest/core/pattern/text_input/text_input_test.cpp b/test/unittest/core/pattern/text_input/text_input_test.cpp index 9d44fc9e8a7..4a94a6cdd24 100644 --- a/test/unittest/core/pattern/text_input/text_input_test.cpp +++ b/test/unittest/core/pattern/text_input/text_input_test.cpp @@ -2644,7 +2644,9 @@ HWTEST_F(TextFieldUXTest, onDraw001, TestSize.Level1) * @tc.steps: step2. Move handle */ OffsetF localOffset(1.0f, 1.0f); - pattern_->SetLocalOffset(localOffset); + auto controller = pattern_->GetMagnifierController(); + ASSERT_NE(controller, nullptr); + controller->SetLocalOffset(localOffset); RectF handleRect; pattern_->OnHandleMove(handleRect, false); @@ -2652,7 +2654,7 @@ HWTEST_F(TextFieldUXTest, onDraw001, TestSize.Level1) * @tc.steps: step3. Test magnifier open or close * @tc.expected: magnifier is open */ - auto ret = pattern_->GetShowMagnifier(); + auto ret = controller->GetShowMagnifier(); EXPECT_TRUE(ret); /** @@ -2686,7 +2688,7 @@ HWTEST_F(TextFieldUXTest, onDraw001, TestSize.Level1) * @tc.steps: step8. Test magnifier open or close * @tc.expected: magnifier is close */ - ret = pattern_->GetShowMagnifier(); + ret = controller->GetShowMagnifier(); EXPECT_FALSE(ret); } -- Gitee From 2769dd266b6635e76f477ff28e270bd27b1d2030 Mon Sep 17 00:00:00 2001 From: xuyue Date: Sat, 2 Mar 2024 08:15:37 +0000 Subject: [PATCH 2/4] update frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp. Signed-off-by: xuyue --- .../pattern/select_overlay/magnifier_controller.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp index 967c13827f1..d7f3def008d 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_controller.cpp @@ -120,9 +120,9 @@ void MagnifierController::CreateMagnifierChildNode() void MagnifierController::SetMagnifierRect(const RefPtr& childPattern) { - auto childTextFieldPattern = DynamicCast(childPattern); - CHECK_NULL_VOID(childTextFieldPattern); - auto childController = childTextFieldPattern->GetMagnifierController(); + auto childMagnifier = DynamicCast(childPattern); + CHECK_NULL_VOID(childMagnifier); + auto childController = childMagnifier->GetMagnifierController(); CHECK_NULL_VOID(childController); auto textBasepattern = DynamicCast(pattern_.Upgrade()); -- Gitee From 485ef4f741f7a77b6cbfbfc79d2927a0e614179b Mon Sep 17 00:00:00 2001 From: xuyue Date: Sat, 2 Mar 2024 08:21:12 +0000 Subject: [PATCH 3/4] update frameworks/core/components_ng/pattern/text_field/text_field_pattern.cpp. Signed-off-by: xuyue --- .../components_ng/pattern/text_field/text_field_pattern.cpp | 3 +++ 1 file changed, 3 insertions(+) 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 3e9e552f891..fbd74e67e1e 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 @@ -3361,6 +3361,9 @@ void TextFieldPattern::UpdateObscure(const std::string& insertValue, bool hasIns void TextFieldPattern::InsertValue(const std::string& insertValue) { + if (!HasFocus()) { + return; + } if (focusIndex_ != FocuseIndex::TEXT && insertValue == " ") { HandleSpaceEvent(); return; -- Gitee From 436ca8040b78a4da47649ccdf42d29215f79d621 Mon Sep 17 00:00:00 2001 From: xuyue Date: Sat, 2 Mar 2024 08:31:23 +0000 Subject: [PATCH 4/4] update frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp. Signed-off-by: xuyue --- .../components_ng/pattern/select_overlay/magnifier_painter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp index 445b9750265..928ef995812 100644 --- a/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp +++ b/frameworks/core/components_ng/pattern/select_overlay/magnifier_painter.cpp @@ -36,7 +36,7 @@ MagnifierPainter::MagnifierPainter(const WeakPtr& pattern) : pattern_(p void MagnifierPainter::PaintMagnifier(RSCanvas& canvas) { - auto pattern = DynamicCast(pattern_.Upgrade()); + auto pattern = DynamicCast(pattern_.Upgrade()); CHECK_NULL_VOID(pattern); auto controller = pattern->GetMagnifierController(); CHECK_NULL_VOID(controller); -- Gitee