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 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
73 selectOverlayContentModifier_->SetHandleColor(textOverlayTheme->GetHandleColor());
74 } else {
75 selectOverlayContentModifier_->SetHandleColor(info_.handlerColor.value_or(textOverlayTheme->GetHandleColor()));
76 }
77 selectOverlayContentModifier_->SetInnerHandleColor(textOverlayTheme->GetHandleColorInner());
78 selectOverlayContentModifier_->SetHandleRadius(textOverlayTheme->GetHandleDiameter().ConvertToPx() / 2.0f);
79 selectOverlayContentModifier_->SetHandleStrokeWidth(textOverlayTheme->GetHandleDiameterStrokeWidth().ConvertToPx());
80 selectOverlayContentModifier_->SetInnerHandleRadius(
81 textOverlayTheme->GetHandleDiameterInner().ConvertToPx() / 2.0f);
82
83 selectOverlayContentModifier_->SetInShowArea(SelectOverlayLayoutAlgorithm::CheckInShowArea(info_));
84 selectOverlayContentModifier_->SetHandleReverse(info_.handleReverse);
85 selectOverlayContentModifier_->SetIsSingleHandle(info_.isSingleHandle);
86 selectOverlayContentModifier_->SetFirstHandleIsShow(info_.firstHandle.isShow || info_.firstHandle.forceDraw);
87 selectOverlayContentModifier_->SetSecondHandleIsShow(info_.secondHandle.isShow || info_.firstHandle.forceDraw);
88 selectOverlayContentModifier_->SetIsHandleLineShow(info_.isHandleLineShow);
89 selectOverlayContentModifier_->SetIsHiddenHandle(isHiddenHandle_);
90
91 selectOverlayContentModifier_->SetViewPort(viewPort);
92 auto isOverlayMode = (info_.handleLevelMode == HandleLevelMode::OVERLAY);
93 selectOverlayContentModifier_->SetPaintHandleUsePoints(
94 isOverlayMode && (info_.firstHandle.isPaintHandleWithPoints || info_.secondHandle.isPaintHandleWithPoints));
95 selectOverlayContentModifier_->SetFirstHandle(info_.GetFirstHandlePaintRect() - offset);
96 selectOverlayContentModifier_->SetFirstHandlePaintInfo(info_.firstHandle.paintInfo - offset);
97 selectOverlayContentModifier_->SetSecondHandle(info_.GetSecondHandlePaintRect() - offset);
98 selectOverlayContentModifier_->SetSecondHandlePaintInfo(info_.secondHandle.paintInfo - offset);
99 selectOverlayContentModifier_->SetIsOverlayMode(isOverlayMode);
100 selectOverlayContentModifier_->SetScale(info_.scale);
101 selectOverlayContentModifier_->SetFirstCircleIsShow(info_.firstHandle.isCircleShow);
102 selectOverlayContentModifier_->SetSecondCircleIsShow(info_.secondHandle.isCircleShow);
103 selectOverlayContentModifier_->SetClipHandleDrawRect(info_.clipHandleDrawRect && isOverlayMode);
104 }
105
CheckCirclesAndBackArrowIsShown()106 void SelectOverlayPaintMethod::CheckCirclesAndBackArrowIsShown()
107 {
108 if (isCreated_) {
109 circlesAndBackArrowIsShown_ = true;
110 }
111
112 if (!circlesAndBackArrowIsShown_) {
113 if (hasExtensionMenu_) {
114 if (hasShowAnimation_) {
115 AnimationOption option;
116 option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
117 option.SetCurve(Curves::SHARP);
118 auto pattern = pattern_.Upgrade();
119 auto host = pattern ? pattern->GetHost() : nullptr;
120 auto contextPtr = host ? host->GetContextRefPtr() : nullptr;
121
122 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
123 auto paintMethod = weak.Upgrade();
124 CHECK_NULL_VOID(paintMethod);
125 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
126 }, nullptr, nullptr, contextPtr);
127 } else {
128 selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
129 }
130 }
131 circlesAndBackArrowIsShown_ = true;
132 }
133 selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
134 }
135
CheckHasExtensionMenu()136 void SelectOverlayPaintMethod::CheckHasExtensionMenu()
137 {
138 if (selectOverlayModifier_->GetHasExtensionMenu() != hasExtensionMenu_) {
139 auto pattern = pattern_.Upgrade();
140 auto host = pattern ? pattern->GetHost() : nullptr;
141 auto contextPtr = host ? host->GetContextRefPtr() : nullptr;
142 if (hasExtensionMenu_) {
143 AnimationOption option;
144 option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
145 option.SetCurve(Curves::SHARP);
146
147 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
148 auto paintMethod = weak.Upgrade();
149 CHECK_NULL_VOID(paintMethod);
150 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
151 }, nullptr, nullptr, contextPtr);
152 } else {
153 AnimationOption option;
154 option.SetDuration(MENU_HIDE_ANIMATION_DURATION);
155 option.SetCurve(Curves::SHARP);
156
157 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
158 auto paintMethod = weak.Upgrade();
159 CHECK_NULL_VOID(paintMethod);
160 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(0.0);
161 }, nullptr, nullptr, contextPtr);
162 }
163 selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
164 }
165 }
166
CheckHandleIsShown()167 void SelectOverlayPaintMethod::CheckHandleIsShown()
168 {
169 if (isCreated_) {
170 handleIsShown_ = true;
171 }
172
173 if (!handleIsShown_) {
174 if (hasShowAnimation_) {
175 AnimationOption option;
176 option.SetDuration(HANDLE_ANIMATION_DURATION);
177 option.SetCurve(Curves::SHARP);
178 auto pattern = pattern_.Upgrade();
179 auto host = pattern ? pattern->GetHost() : nullptr;
180 auto contextPtr = host ? host->GetContextRefPtr() : nullptr;
181
182 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
183 auto paintMethod = weak.Upgrade();
184 CHECK_NULL_VOID(paintMethod);
185 paintMethod->selectOverlayContentModifier_->SetHandleOpacity(1.0);
186 }, nullptr, nullptr, contextPtr);
187 } else {
188 selectOverlayContentModifier_->SetHandleOpacity(1.0);
189 }
190 handleIsShown_ = true;
191 }
192 }
193
IsModeSwitchComplete() const194 bool SelectOverlayPaintMethod::IsModeSwitchComplete() const
195 {
196 if (info_.enableHandleLevel && info_.handleLevelMode == HandleLevelMode::EMBED) {
197 CHECK_NULL_RETURN(selectOverlayContentModifier_, false);
198 auto pattern = selectOverlayContentModifier_->GetSelectOverlayPattern();
199 CHECK_NULL_RETURN(pattern, false);
200 auto host = pattern->GetHost();
201 CHECK_NULL_RETURN(host, false);
202 auto parentNode = host->GetAncestorNodeOfFrame(true);
203 CHECK_NULL_RETURN(parentNode, false);
204 auto callerNode = info_.callerFrameNode.Upgrade();
205 CHECK_NULL_RETURN(callerNode, false);
206 return parentNode == info_.callerFrameNode.Upgrade();
207 }
208 return true;
209 }
210 } // namespace OHOS::Ace::NG