1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/pattern/select_overlay/select_overlay_paint_method.h"
17
18 #include "core/components/text_overlay/text_overlay_theme.h"
19 #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h"
20
21 namespace OHOS::Ace::NG {
22 constexpr float AGING_MIN_SCALE = 1.75f;
23 constexpr float HALF = 2.0f;
UpdateOverlayModifier(PaintWrapper * paintWrapper)24 void SelectOverlayPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
25 {
26 CHECK_NULL_VOID(paintWrapper);
27 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
28 CHECK_NULL_VOID(pipeline);
29 auto textOverlayTheme = pipeline->GetTheme<TextOverlayTheme>();
30 CHECK_NULL_VOID(textOverlayTheme);
31
32 const auto& padding = textOverlayTheme->GetMenuPadding();
33 auto left = padding.Left().ConvertToPx();
34 auto right = padding.Right().ConvertToPx();
35 auto top = padding.Top().ConvertToPx();
36 auto sideWidth = textOverlayTheme->GetMenuToolbarHeight().ConvertToPx() - padding.Top().ConvertToPx() -
37 padding.Bottom().ConvertToPx();
38 auto buttonRadius = sideWidth / HALF;
39 auto tempY = static_cast<float>(buttonRadius + top);
40 if (GreatOrEqual(pipeline->GetFontScale(), AGING_MIN_SCALE)) {
41 tempY = static_cast<float>(selectMenuHeight_ / HALF);
42 }
43 auto offset = isReversePaint_ ? defaultMenuStartOffset_ + OffsetF(static_cast<float>(buttonRadius + left), tempY)
44 : defaultMenuEndOffset_ + OffsetF(static_cast<float>(-buttonRadius - right), tempY);
45
46 CheckCirclesAndBackArrowIsShown();
47 selectOverlayModifier_->SetIsReverse(isReversePaint_);
48 selectOverlayModifier_->SetMenuOptionOffset(offset);
49 selectOverlayModifier_->SetFirstHandleIsShow(info_.firstHandle.isShow);
50 selectOverlayModifier_->SetSecondHandleIsShow(info_.secondHandle.isShow);
51 selectOverlayModifier_->SetIsNewAvoid(info_.isNewAvoid);
52 }
53
UpdateContentModifier(PaintWrapper * paintWrapper)54 void SelectOverlayPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
55 {
56 CHECK_NULL_VOID(paintWrapper);
57 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
58 CHECK_NULL_VOID(pipeline);
59 auto textOverlayTheme = pipeline->GetTheme<TextOverlayTheme>();
60 CHECK_NULL_VOID(textOverlayTheme);
61 if (!IsModeSwitchComplete()) {
62 return;
63 }
64
65 auto offset = paintWrapper->GetGeometryNode()->GetFrameOffset();
66 auto viewPort = paintWrapper->GetGeometryNode()->GetFrameRect() - offset;
67 info_.GetCallerNodeAncestorViewPort(viewPort);
68
69 CheckHandleIsShown();
70
71 selectOverlayContentModifier_->SetIsUsingMouse(info_.isUsingMouse);
72
73 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
74 selectOverlayContentModifier_->SetHandleColor(textOverlayTheme->GetHandleColor());
75 } else {
76 selectOverlayContentModifier_->SetHandleColor(info_.handlerColor.value_or(textOverlayTheme->GetHandleColor()));
77 }
78 selectOverlayContentModifier_->SetInnerHandleColor(textOverlayTheme->GetHandleColorInner());
79 selectOverlayContentModifier_->SetHandleRadius(textOverlayTheme->GetHandleDiameter().ConvertToPx() / 2.0f);
80 selectOverlayContentModifier_->SetHandleStrokeWidth(textOverlayTheme->GetHandleDiameterStrokeWidth().ConvertToPx());
81 selectOverlayContentModifier_->SetInnerHandleRadius(
82 textOverlayTheme->GetHandleDiameterInner().ConvertToPx() / 2.0f);
83
84 selectOverlayContentModifier_->SetInShowArea(SelectOverlayLayoutAlgorithm::CheckInShowArea(info_));
85 selectOverlayContentModifier_->SetHandleReverse(info_.handleReverse);
86 selectOverlayContentModifier_->SetIsSingleHandle(info_.isSingleHandle);
87 selectOverlayContentModifier_->SetFirstHandleIsShow(info_.firstHandle.isShow || info_.firstHandle.forceDraw);
88 selectOverlayContentModifier_->SetSecondHandleIsShow(info_.secondHandle.isShow || info_.firstHandle.forceDraw);
89 selectOverlayContentModifier_->SetIsHandleLineShow(info_.isHandleLineShow);
90 selectOverlayContentModifier_->SetIsHiddenHandle(isHiddenHandle_);
91
92 selectOverlayContentModifier_->SetViewPort(viewPort);
93 auto isOverlayMode = (info_.handleLevelMode == HandleLevelMode::OVERLAY);
94 selectOverlayContentModifier_->SetPaintHandleUsePoints(
95 isOverlayMode && (info_.firstHandle.isPaintHandleWithPoints || info_.secondHandle.isPaintHandleWithPoints));
96 selectOverlayContentModifier_->SetFirstHandle(info_.GetFirstHandlePaintRect() - offset);
97 selectOverlayContentModifier_->SetFirstHandlePaintInfo(info_.firstHandle.paintInfo - offset);
98 selectOverlayContentModifier_->SetSecondHandle(info_.GetSecondHandlePaintRect() - offset);
99 selectOverlayContentModifier_->SetSecondHandlePaintInfo(info_.secondHandle.paintInfo - offset);
100 selectOverlayContentModifier_->SetIsOverlayMode(isOverlayMode);
101 selectOverlayContentModifier_->SetScale(info_.scale);
102 selectOverlayContentModifier_->SetFirstCircleIsShow(info_.firstHandle.isCircleShow);
103 selectOverlayContentModifier_->SetSecondCircleIsShow(info_.secondHandle.isCircleShow);
104 selectOverlayContentModifier_->SetClipHandleDrawRect(info_.clipHandleDrawRect && isOverlayMode);
105 }
106
CheckCirclesAndBackArrowIsShown()107 void SelectOverlayPaintMethod::CheckCirclesAndBackArrowIsShown()
108 {
109 if (isCreated_) {
110 circlesAndBackArrowIsShown_ = true;
111 }
112
113 if (!circlesAndBackArrowIsShown_) {
114 if (hasExtensionMenu_) {
115 if (hasShowAnimation_) {
116 AnimationOption option;
117 option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
118 option.SetCurve(Curves::SHARP);
119
120 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
121 auto paintMethod = weak.Upgrade();
122 CHECK_NULL_VOID(paintMethod);
123 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
124 });
125 } else {
126 selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
127 }
128 }
129 circlesAndBackArrowIsShown_ = true;
130 }
131 selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
132 }
133
CheckHasExtensionMenu()134 void SelectOverlayPaintMethod::CheckHasExtensionMenu()
135 {
136 if (selectOverlayModifier_->GetHasExtensionMenu() != hasExtensionMenu_) {
137 if (hasExtensionMenu_) {
138 AnimationOption option;
139 option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
140 option.SetCurve(Curves::SHARP);
141
142 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
143 auto paintMethod = weak.Upgrade();
144 CHECK_NULL_VOID(paintMethod);
145 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
146 });
147 } else {
148 AnimationOption option;
149 option.SetDuration(MENU_HIDE_ANIMATION_DURATION);
150 option.SetCurve(Curves::SHARP);
151
152 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
153 auto paintMethod = weak.Upgrade();
154 CHECK_NULL_VOID(paintMethod);
155 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(0.0);
156 });
157 }
158 selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
159 }
160 }
161
CheckHandleIsShown()162 void SelectOverlayPaintMethod::CheckHandleIsShown()
163 {
164 if (isCreated_) {
165 handleIsShown_ = true;
166 }
167
168 if (!handleIsShown_) {
169 if (hasShowAnimation_) {
170 AnimationOption option;
171 option.SetDuration(HANDLE_ANIMATION_DURATION);
172 option.SetCurve(Curves::SHARP);
173
174 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
175 auto paintMethod = weak.Upgrade();
176 CHECK_NULL_VOID(paintMethod);
177 paintMethod->selectOverlayContentModifier_->SetHandleOpacity(1.0);
178 });
179 } else {
180 selectOverlayContentModifier_->SetHandleOpacity(1.0);
181 }
182 handleIsShown_ = true;
183 }
184 }
185
IsModeSwitchComplete() const186 bool SelectOverlayPaintMethod::IsModeSwitchComplete() const
187 {
188 if (info_.enableHandleLevel && info_.handleLevelMode == HandleLevelMode::EMBED) {
189 CHECK_NULL_RETURN(selectOverlayContentModifier_, false);
190 auto pattern = selectOverlayContentModifier_->GetSelectOverlayPattern();
191 CHECK_NULL_RETURN(pattern, false);
192 auto host = pattern->GetHost();
193 CHECK_NULL_RETURN(host, false);
194 auto parentNode = host->GetAncestorNodeOfFrame(true);
195 CHECK_NULL_RETURN(parentNode, false);
196 auto callerNode = info_.callerFrameNode.Upgrade();
197 CHECK_NULL_RETURN(callerNode, false);
198 return parentNode == info_.callerFrameNode.Upgrade();
199 }
200 return true;
201 }
202 } // namespace OHOS::Ace::NG