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 "base/geometry/ng/offset_t.h"
19 #include "base/utils/utils.h"
20 #include "core/components/text_overlay/text_overlay_theme.h"
21 #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h"
22 #include "core/components_ng/pattern/select_overlay/select_overlay_property.h"
23 #include "core/components_ng/render/drawing.h"
24 #include "core/pipeline_ng/pipeline_context.h"
25 
26 namespace OHOS::Ace::NG {
27 constexpr float AGING_MIN_SCALE = 1.75f;
28 constexpr float HALF = 2.0f;
UpdateOverlayModifier(PaintWrapper * paintWrapper)29 void SelectOverlayPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
30 {
31     CHECK_NULL_VOID(paintWrapper);
32     auto pipeline = PipelineContext::GetCurrentContextSafely();
33     CHECK_NULL_VOID(pipeline);
34     auto textOverlayTheme = pipeline->GetTheme<TextOverlayTheme>();
35     CHECK_NULL_VOID(textOverlayTheme);
36 
37     const auto& padding = textOverlayTheme->GetMenuPadding();
38     auto left = padding.Left().ConvertToPx();
39     auto right = padding.Right().ConvertToPx();
40     auto top = padding.Top().ConvertToPx();
41     auto sideWidth = textOverlayTheme->GetMenuToolbarHeight().ConvertToPx() - padding.Top().ConvertToPx() -
42                      padding.Bottom().ConvertToPx();
43     auto buttonRadius = sideWidth / HALF;
44     auto tempY = static_cast<float>(buttonRadius + top);
45     if (GreatOrEqual(pipeline->GetFontScale(), AGING_MIN_SCALE)) {
46         tempY = static_cast<float>(selectMenuHeight_ / HALF);
47     }
48     auto offset = isReversePaint_ ? defaultMenuStartOffset_ + OffsetF(static_cast<float>(buttonRadius + left), tempY)
49                                   : defaultMenuEndOffset_ + OffsetF(static_cast<float>(-buttonRadius - right), tempY);
50 
51     CheckCirclesAndBackArrowIsShown();
52     selectOverlayModifier_->SetIsReverse(isReversePaint_);
53     selectOverlayModifier_->SetMenuOptionOffset(offset);
54     selectOverlayModifier_->SetFirstHandleIsShow(info_.firstHandle.isShow);
55     selectOverlayModifier_->SetSecondHandleIsShow(info_.secondHandle.isShow);
56     selectOverlayModifier_->SetIsNewAvoid(info_.isNewAvoid);
57 }
58 
UpdateContentModifier(PaintWrapper * paintWrapper)59 void SelectOverlayPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
60 {
61     CHECK_NULL_VOID(paintWrapper);
62     auto pipeline = PipelineContext::GetCurrentContextSafely();
63     CHECK_NULL_VOID(pipeline);
64     auto textOverlayTheme = pipeline->GetTheme<TextOverlayTheme>();
65     CHECK_NULL_VOID(textOverlayTheme);
66 
67     auto offset = paintWrapper->GetGeometryNode()->GetFrameOffset();
68     auto viewPort = paintWrapper->GetGeometryNode()->GetFrameRect() - offset;
69     info_.GetCallerNodeAncestorViewPort(viewPort);
70 
71     CheckHandleIsShown();
72 
73     selectOverlayContentModifier_->SetIsUsingMouse(info_.isUsingMouse);
74     if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
75         selectOverlayContentModifier_->SetHandleColor(textOverlayTheme->GetHandleColor());
76     } else {
77         selectOverlayContentModifier_->SetHandleColor(info_.handlerColor.value_or(textOverlayTheme->GetHandleColor()));
78     }
79     selectOverlayContentModifier_->SetInnerHandleColor(textOverlayTheme->GetHandleColorInner());
80     selectOverlayContentModifier_->SetHandleRadius(textOverlayTheme->GetHandleDiameter().ConvertToPx() / 2.0f);
81     selectOverlayContentModifier_->SetHandleStrokeWidth(textOverlayTheme->GetHandleDiameterStrokeWidth().ConvertToPx());
82     selectOverlayContentModifier_->SetInnerHandleRadius(
83         textOverlayTheme->GetHandleDiameterInner().ConvertToPx() / 2.0f);
84 
85     selectOverlayContentModifier_->SetInShowArea(SelectOverlayLayoutAlgorithm::CheckInShowArea(info_));
86     selectOverlayContentModifier_->SetHandleReverse(info_.handleReverse);
87     selectOverlayContentModifier_->SetIsSingleHandle(info_.isSingleHandle);
88     selectOverlayContentModifier_->SetFirstHandleIsShow(info_.firstHandle.isShow);
89     selectOverlayContentModifier_->SetSecondHandleIsShow(info_.secondHandle.isShow);
90     selectOverlayContentModifier_->SetIsHandleLineShow(info_.isHandleLineShow);
91     selectOverlayContentModifier_->SetIsHiddenHandle(isHiddenHandle_);
92 
93     selectOverlayContentModifier_->SetViewPort(viewPort);
94     auto isOverlayMode = (info_.handleLevelMode == HandleLevelMode::OVERLAY);
95     selectOverlayContentModifier_->SetPaintHandleUsePoints(
96         isOverlayMode && (info_.firstHandle.isPaintHandleWithPoints || info_.secondHandle.isPaintHandleWithPoints));
97     selectOverlayContentModifier_->SetFirstHandle(info_.GetFirstHandlePaintRect() - offset);
98     selectOverlayContentModifier_->SetFirstHandlePaintInfo(info_.firstHandle.paintInfo - offset);
99     selectOverlayContentModifier_->SetSecondHandle(info_.GetSecondHandlePaintRect() - offset);
100     selectOverlayContentModifier_->SetSecondHandlePaintInfo(info_.secondHandle.paintInfo - offset);
101     selectOverlayContentModifier_->SetIsOverlayMode(isOverlayMode);
102     selectOverlayContentModifier_->SetScale(info_.scale);
103     selectOverlayContentModifier_->SetFirstCircleIsShow(info_.firstHandle.isCircleShow);
104     selectOverlayContentModifier_->SetSecondCircleIsShow(info_.secondHandle.isCircleShow);
105     selectOverlayContentModifier_->SetClipHandleDrawRect(info_.clipHandleDrawRect && isOverlayMode);
106 }
107 
CheckCirclesAndBackArrowIsShown()108 void SelectOverlayPaintMethod::CheckCirclesAndBackArrowIsShown()
109 {
110     if (isCreated_) {
111         circlesAndBackArrowIsShown_ = true;
112     }
113 
114     if (!circlesAndBackArrowIsShown_) {
115         if (hasExtensionMenu_) {
116             if (hasShowAnimation_) {
117                 AnimationOption option;
118                 option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
119                 option.SetCurve(Curves::SHARP);
120 
121                 AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
122                     auto paintMethod = weak.Upgrade();
123                     CHECK_NULL_VOID(paintMethod);
124                     paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
125                 });
126             } else {
127                 selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
128             }
129         }
130         circlesAndBackArrowIsShown_ = true;
131     }
132     selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
133 }
134 
CheckHasExtensionMenu()135 void SelectOverlayPaintMethod::CheckHasExtensionMenu()
136 {
137     if (selectOverlayModifier_->GetHasExtensionMenu() != hasExtensionMenu_) {
138         if (hasExtensionMenu_) {
139             AnimationOption option;
140             option.SetDuration(MENU_SHOW_ANIMATION_DURATION);
141             option.SetCurve(Curves::SHARP);
142 
143             AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
144                 auto paintMethod = weak.Upgrade();
145                 CHECK_NULL_VOID(paintMethod);
146                 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(1.0);
147             });
148         } else {
149             AnimationOption option;
150             option.SetDuration(MENU_HIDE_ANIMATION_DURATION);
151             option.SetCurve(Curves::SHARP);
152 
153             AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
154                 auto paintMethod = weak.Upgrade();
155                 CHECK_NULL_VOID(paintMethod);
156                 paintMethod->selectOverlayModifier_->SetCirclesAndBackArrowOpacity(0.0);
157             });
158         }
159         selectOverlayModifier_->SetHasExtensionMenu(hasExtensionMenu_);
160     }
161 }
162 
CheckHandleIsShown()163 void SelectOverlayPaintMethod::CheckHandleIsShown()
164 {
165     if (isCreated_) {
166         handleIsShown_ = true;
167     }
168 
169     if (!handleIsShown_) {
170         if (hasShowAnimation_) {
171             AnimationOption option;
172             option.SetDuration(HANDLE_ANIMATION_DURATION);
173             option.SetCurve(Curves::SHARP);
174 
175             AnimationUtils::Animate(option, [weak = WeakClaim(this)]() {
176                 auto paintMethod = weak.Upgrade();
177                 CHECK_NULL_VOID(paintMethod);
178                 paintMethod->selectOverlayContentModifier_->SetHandleOpacity(1.0);
179             });
180         } else {
181             selectOverlayContentModifier_->SetHandleOpacity(1.0);
182         }
183         handleIsShown_ = true;
184     }
185 }
186 
187 } // namespace OHOS::Ace::NG