1 /*
2  * Copyright (c) 2022-2024 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H
18 
19 #include <optional>
20 
21 #include "base/geometry/ng/offset_t.h"
22 #include "base/geometry/ng/size_t.h"
23 #include "base/memory/referenced.h"
24 #include "core/components/popup/popup_theme.h"
25 #include "core/components_ng/base/frame_node.h"
26 #include "core/components_ng/event/focus_hub.h"
27 #include "core/components_ng/manager/focus/focus_view.h"
28 #include "core/components_ng/pattern/bubble/bubble_accessibility_property.h"
29 #include "core/components_ng/pattern/bubble/bubble_event_hub.h"
30 #include "core/components_ng/pattern/bubble/bubble_layout_algorithm.h"
31 #include "core/components_ng/pattern/bubble/bubble_layout_property.h"
32 #include "core/components_ng/pattern/bubble/bubble_paint_method.h"
33 #include "core/components_ng/pattern/bubble/bubble_render_property.h"
34 #include "core/components_ng/pattern/overlay/popup_base_pattern.h"
35 
36 namespace OHOS::Ace::NG {
37 
38 enum class TransitionStatus {
39     INVISIABLE,
40     ENTERING,
41     NORMAL,
42     EXITING,
43 };
44 
45 enum class DismissReason {
46     BACK_PRESSED = 0,
47     TOUCH_OUTSIDE,
48     CLOSE_BUTTON,
49 };
50 class BubblePattern : public PopupBasePattern, public FocusView {
51     DECLARE_ACE_TYPE(BubblePattern, PopupBasePattern, FocusView);
52 
53 public:
54     BubblePattern() = default;
BubblePattern(int32_t id,const std::string & tag)55     BubblePattern(int32_t id, const std::string& tag) : targetNodeId_(id), targetTag_(tag) {}
56     ~BubblePattern() override = default;
57 
IsAtomicNode()58     bool IsAtomicNode() const override
59     {
60         return false;
61     }
62 
CreateNodePaintMethod()63     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
64     {
65         auto bubbleMethod = AceType::MakeRefPtr<BubblePaintMethod>();
66         bubbleMethod->SetArrowPosition(arrowPosition_);
67         bubbleMethod->SetChildOffset(childOffset_);
68         bubbleMethod->SetChildSize(childSize_);
69         bubbleMethod->SetShowArrow(showArrow_);
70         bubbleMethod->SetClipPath(clipPath_);
71         bubbleMethod->SetClipFrameNode(clipFrameNode_);
72         bubbleMethod->SetArrowOffsetsFromClip(arrowOffsetsFromClip_);
73         bubbleMethod->SetArrowWidth(arrowWidth_);
74         bubbleMethod->SetArrowHeight(arrowHeight_);
75         bubbleMethod->SetBorder(border_);
76         return bubbleMethod;
77     }
78 
CreateLayoutProperty()79     RefPtr<LayoutProperty> CreateLayoutProperty() override
80     {
81         auto bubbleProp = AceType::MakeRefPtr<BubbleLayoutProperty>();
82         bubbleProp->UpdatePropertyChangeFlag(PROPERTY_UPDATE_MEASURE);
83         return bubbleProp;
84     }
85 
CreateLayoutAlgorithm()86     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
87     {
88         return MakeRefPtr<BubbleLayoutAlgorithm>(targetNodeId_, targetTag_, targetOffset_, targetSize_);
89     }
90 
CreatePaintProperty()91     RefPtr<PaintProperty> CreatePaintProperty() override
92     {
93         return MakeRefPtr<BubbleRenderProperty>();
94     }
95 
CreateEventHub()96     RefPtr<EventHub> CreateEventHub() override
97     {
98         return MakeRefPtr<BubbleEventHub>();
99     }
100 
CreateAccessibilityProperty()101     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
102     {
103         return MakeRefPtr<BubbleAccessibilityProperty>();
104     }
105 
GetChildOffset()106     OffsetF GetChildOffset()
107     {
108         return childOffset_;
109     }
110 
GetChildSize()111     SizeF GetChildSize()
112     {
113         return childSize_;
114     }
115 
GetFocusPattern()116     FocusPattern GetFocusPattern() const override
117     {
118         return { FocusType::SCOPE, true };
119     }
120 
GetRouteOfFirstScope()121     std::list<int32_t> GetRouteOfFirstScope() override
122     {
123         return { 0, 0, 0 };
124     }
125 
126     void OnWindowHide() override;
127     void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) override;
128     void StartEnteringTransitionEffects(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish);
129     void StartExitingTransitionEffects(const RefPtr<FrameNode>& popupNode, const std::function<void()>& finish);
130     void StartEnteringAnimation(std::function<void()> finish);
131     void StartExitingAnimation(std::function<void()> finish);
132     bool IsOnShow();
133     bool IsExiting();
134     void OnColorConfigurationUpdate() override;
135     void UpdateBubbleText();
136     void UpdateText(const RefPtr<UINode>& node, const RefPtr<PopupTheme>& popupTheme);
137     void AddPipelineCallBack();
138     void UpdateAgingTextSize();
139 
SetMessageColor(bool isSetMessageColor)140     void SetMessageColor(bool isSetMessageColor)
141     {
142         isSetMessageColor_ = isSetMessageColor;
143     }
144 
SetMessageNode(RefPtr<FrameNode> messageNode)145     void SetMessageNode(RefPtr<FrameNode> messageNode)
146     {
147         messageNode_ = messageNode;
148     }
149 
SetCustomPopupTag(bool isCustomPopup)150     void SetCustomPopupTag(bool isCustomPopup)
151     {
152         isCustomPopup_ = isCustomPopup;
153     }
154 
SetTransitionStatus(TransitionStatus transitionStatus)155     void SetTransitionStatus(TransitionStatus transitionStatus)
156     {
157         transitionStatus_ = transitionStatus;
158     }
159 
GetTransitionStatus()160     TransitionStatus GetTransitionStatus() const
161     {
162         return transitionStatus_;
163     }
164 
SetInteractiveDismiss(bool interactiveDismiss)165     void SetInteractiveDismiss(bool interactiveDismiss)
166     {
167         interactiveDismiss_ = interactiveDismiss;
168     }
169 
GetInteractiveDismiss()170     bool GetInteractiveDismiss()
171     {
172         if (interactiveDismiss_) {
173             return true;
174         }
175         return false;
176     }
177 
UpdateOnWillDismiss(const std::function<void (int32_t)> && onWillDismiss)178     void UpdateOnWillDismiss(const std::function<void(int32_t)>&& onWillDismiss)
179     {
180         onWillDismiss_ = std::move(onWillDismiss);
181     }
182 
HasOnWillDismiss()183     bool HasOnWillDismiss()
184     {
185         if (onWillDismiss_) {
186             return true;
187         }
188         return false;
189     }
190 
CallOnWillDismiss(int32_t reason)191     void CallOnWillDismiss(int32_t reason)
192     {
193         if (onWillDismiss_) {
194             onWillDismiss_(reason);
195         }
196     }
SetHasTransition(bool hasTransition)197     void SetHasTransition(bool hasTransition)
198     {
199         hasTransition_ = hasTransition;
200     }
201 
GetHasTransition()202     bool GetHasTransition() const
203     {
204         return hasTransition_;
205     }
206 
ResetFocusState()207     void ResetFocusState()
208     {
209         FocusViewDidShow(nullptr);
210         SetIsViewRootScopeFocused(true);
211         SetIsViewHasFocused(false);
212     }
213 
GetHostWindowRect()214     Rect GetHostWindowRect() const
215     {
216         return hostWindowRect_;
217     }
218 
219 protected:
220     void OnDetachFromFrameNode(FrameNode* frameNode) override;
221 
AvoidKeyboard()222     bool AvoidKeyboard() const override
223     {
224         return false;
225     }
226 
AvoidBottom()227     bool AvoidBottom() const override
228     {
229         return false;
230     }
231 
232 private:
233     void OnModifyDone() override;
234     void OnAttachToFrameNode() override;
235     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, bool skipMeasure, bool skipLayout) override;
236 
237     RefPtr<FrameNode> GetButtonRowNode();
238     RefPtr<PopupTheme> GetPopupTheme();
239     void InitTouchEvent();
240     void HandleTouchEvent(const TouchEventInfo& info);
241     void HandleTouchDown(const Offset& clickPosition);
242     void RegisterButtonOnHover();
243     void RegisterButtonOnTouch();
244     void ButtonOnHover(bool isHover, const RefPtr<NG::FrameNode>& buttonNode);
245     void ButtonOnPress(const TouchEventInfo& info, const RefPtr<NG::FrameNode>& buttonNode);
246     void PopBubble();
247     void Animation(
248         RefPtr<RenderContext>& renderContext, const Color& endColor, int32_t duration, const RefPtr<Curve>& curve);
249 
250     OffsetT<Dimension> GetInvisibleOffset();
251     RefPtr<RenderContext> GetRenderContext();
252     void ResetToInvisible();
253     bool PostTask(const TaskExecutor::Task& task, const std::string& name);
254     void StartOffsetEnteringAnimation();
255     void StartAlphaEnteringAnimation(std::function<void()> finish);
256     void StartOffsetExitingAnimation();
257     void StartAlphaExitingAnimation(std::function<void()> finish);
258 
259     int32_t targetNodeId_ = -1;
260     std::string targetTag_;
261 
262     RefPtr<TouchEventImpl> touchEvent_;
263     bool mouseEventInitFlag_ = false;
264     bool touchEventInitFlag_ = false;
265     bool isHover_ = false;
266     bool interactiveDismiss_ = true;
267     std::function<void(int32_t)> onWillDismiss_;
268     OffsetF childOffset_;
269     OffsetF arrowPosition_;
270     SizeF childSize_;
271     RectF touchRegion_;
272     Rect hostWindowRect_;
273     // top right bottom left
274     std::vector<float> arrowOffsetByClips_ = { 0.0f, 0.0f, 0.0f, 0.0f };
275     std::optional<Placement> arrowPlacement_;
276     std::vector<std::vector<float>> arrowOffsetsFromClip_
277         = { {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f} };
278     float arrowWidth_ = Dimension(16.0_vp).ConvertToPx();
279     float arrowHeight_ = Dimension(8.0_vp).ConvertToPx();
280 
281     bool showArrow_ = false;
282     ColorMode colorMode_ = ColorMode::COLOR_MODE_UNDEFINED;
283     bool isSetMessageColor_ = false;
284     Border border_;
285 
286     TransitionStatus transitionStatus_ = TransitionStatus::INVISIABLE;
287 
288     bool delayShow_ = false;
289     std::function<void()> finish_;
290 
291     std::optional<OffsetF> targetOffset_;
292     std::optional<SizeF> targetSize_;
293 
294     bool isCustomPopup_ = false;
295     RefPtr<FrameNode> messageNode_;
296 
297     std::string clipPath_;
298     RefPtr<FrameNode> clipFrameNode_;
299     ACE_DISALLOW_COPY_AND_MOVE(BubblePattern);
300 
301     bool hasTransition_ = false;
302     bool hasOnAreaChange_ = false;
303 };
304 } // namespace OHOS::Ace::NG
305 
306 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_BUBBLE_BUBBLE_PATTERN_H
307