1 /*
2  * Copyright (c) 2021 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_DIALOG_DIALOG_COMPONENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_DIALOG_DIALOG_COMPONENT_H
18 
19 #include "base/utils/device_type.h"
20 #include "core/components/box/box_component.h"
21 #include "core/components/button/button_component.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components/common/properties/edge.h"
24 #include "core/components/dialog/dialog_properties.h"
25 #include "core/components/dialog/dialog_theme.h"
26 #include "core/components/dialog_tween/dialog_tween_component.h"
27 #include "core/components/flex/flex_component.h"
28 #include "core/components/flex/flex_item_component.h"
29 #include "core/components/focus_animation/focus_animation_component.h"
30 #include "core/components/focus_collaboration/focus_collaboration_component.h"
31 #include "core/components/padding/padding_component.h"
32 #include "core/components/text/text_component.h"
33 #include "core/components/transition/transition_component.h"
34 #include "core/components/tween/tween_component.h"
35 #include "core/pipeline/base/sole_child_component.h"
36 #include "core/pipeline/pipeline_context.h"
37 
38 namespace OHOS::Ace {
39 
40 // constants of dialog component
41 extern const char CALLBACK_SUCCESS[];
42 extern const char CALLBACK_CANCEL[];
43 extern const char CALLBACK_COMPLETE[];
44 extern const char DIALOG_TWEEN_NAME[];
45 
46 class DialogComponent : public SoleChildComponent {
47     DECLARE_ACE_TYPE(DialogComponent, SoleChildComponent);
48 
49 public:
50     DialogComponent();
51     ~DialogComponent() override = default;
52 
53     RefPtr<Element> CreateElement() override;
54     RefPtr<RenderNode> CreateRenderNode() override;
55     virtual void BuildChild(const RefPtr<ThemeManager>& themeManager);
56 
SetTitle(const RefPtr<TextComponent> & title)57     void SetTitle(const RefPtr<TextComponent>& title)
58     {
59         title_ = title;
60     }
61 
SetTitlePadding(const Edge & titlePadding)62     void SetTitlePadding(const Edge& titlePadding)
63     {
64         titlePadding_ = titlePadding;
65     }
66 
SetContent(const RefPtr<TextComponent> & content)67     void SetContent(const RefPtr<TextComponent>& content)
68     {
69         content_ = content;
70     }
71 
SetContentPadding(const Edge & contentPadding)72     void SetContentPadding(const Edge& contentPadding)
73     {
74         contentPadding_ = contentPadding;
75     }
76 
SetBackgroundColor(const Color & backgroundColor)77     void SetBackgroundColor(const Color& backgroundColor)
78     {
79         backgroundColor_ = backgroundColor;
80     }
81 
SetActions(const std::list<RefPtr<ButtonComponent>> & actions)82     void SetActions(const std::list<RefPtr<ButtonComponent>>& actions)
83     {
84         actions_ = actions;
85     }
86 
SetAutoCancel(bool autoCancel)87     void SetAutoCancel(bool autoCancel)
88     {
89         autoCancel_ = autoCancel;
90     }
91 
SetAnimator(const RefPtr<Animator> & animator)92     void SetAnimator(const RefPtr<Animator>& animator)
93     {
94         animator_ = animator;
95     }
96 
SetDialogTween(const RefPtr<DialogTweenComponent> & dialogTween)97     void SetDialogTween(const RefPtr<DialogTweenComponent>& dialogTween)
98     {
99         dialogTween_ = dialogTween;
100     }
101 
SetDialogTweenBox(const RefPtr<BoxComponent> & dialogTweenBox)102     void SetDialogTweenBox(const RefPtr<BoxComponent>& dialogTweenBox)
103     {
104         dialogTweenBox_ = dialogTweenBox;
105     }
106 
SetOnSuccessId(const EventMarker & onSuccessId)107     void SetOnSuccessId(const EventMarker& onSuccessId)
108     {
109         // Before update event marker, remove old marker from manager.
110         BackEndEventManager<void(int32_t)>::GetInstance().RemoveBackEndEvent(onSuccessId_);
111         onSuccessId_ = onSuccessId;
112     }
113 
SetOnCancelId(const EventMarker & onCancelId)114     void SetOnCancelId(const EventMarker& onCancelId)
115     {
116         onCancelId_ = onCancelId;
117     }
118 
SetOnCompleteId(const EventMarker & onCompleteId)119     void SetOnCompleteId(const EventMarker& onCompleteId)
120     {
121         onCompleteId_ = onCompleteId;
122     }
123 
GetTitle()124     const RefPtr<TextComponent>& GetTitle() const
125     {
126         return title_;
127     }
128 
GetTitlePadding()129     const Edge& GetTitlePadding() const
130     {
131         return titlePadding_;
132     }
133 
GetContent()134     const RefPtr<TextComponent>& GetContent() const
135     {
136         return content_;
137     }
138 
GetContentPadding()139     const Edge& GetContentPadding() const
140     {
141         return contentPadding_;
142     }
143 
GetBackgroundColor()144     const Color& GetBackgroundColor() const
145     {
146         return backgroundColor_;
147     }
148 
GetActions()149     const std::list<RefPtr<ButtonComponent>>& GetActions() const
150     {
151         return actions_;
152     }
153 
GetAutoCancel()154     bool GetAutoCancel() const
155     {
156         return autoCancel_;
157     }
158 
GetMenuSuccessId()159     std::vector<EventMarker>& GetMenuSuccessId()
160     {
161         return menuSuccessId_;
162     }
163 
GetOnPositiveSuccessId()164     const EventMarker& GetOnPositiveSuccessId() const
165     {
166         return onPositiveSuccessId_;
167     }
168 
GetOnNegativeSuccessId()169     const EventMarker& GetOnNegativeSuccessId() const
170     {
171         return onNegativeSuccessId_;
172     }
173 
GetOnNeutralSuccessId()174     const EventMarker& GetOnNeutralSuccessId() const
175     {
176         return onNeutralSuccessId_;
177     }
178 
GetAnimator()179     const RefPtr<Animator>& GetAnimator() const
180     {
181         return animator_;
182     }
183 
GetDialogTweenComponent()184     const RefPtr<DialogTweenComponent>& GetDialogTweenComponent() const
185     {
186         return dialogTween_;
187     }
188 
GetDialogTweenBox()189     const RefPtr<BoxComponent>& GetDialogTweenBox() const
190     {
191         return dialogTweenBox_;
192     }
193 
HasCustomChild()194     bool HasCustomChild() const
195     {
196         return customComponent_ != nullptr;
197     }
198 
SetCustomChild(const RefPtr<Component> & customChild)199     void SetCustomChild(const RefPtr<Component>& customChild)
200     {
201         customComponent_ = customChild;
202     }
203 
GetDialogId()204     int32_t GetDialogId() const
205     {
206         return dialogId_;
207     }
208 
SetDialogTweenComposedId(int32_t dialogTweenComposeId)209     void SetDialogTweenComposedId(int32_t dialogTweenComposeId)
210     {
211         dialogTweenComposedId_ = dialogTweenComposeId;
212     }
213 
SetContext(const WeakPtr<PipelineContext> & context)214     void SetContext(const WeakPtr<PipelineContext>& context)
215     {
216         context_ = context;
217     }
218 
SetData(const std::string & data)219     void SetData(const std::string& data)
220     {
221         data_ = data;
222     }
223 
224     // This method is design for unit test, please call this method seriously.
SetDeviceType(DeviceType deviceType)225     void SetDeviceType(DeviceType deviceType)
226     {
227         deviceType_ = deviceType;
228         isDeviceTypeSet_ = true;
229     }
230 
SetHeight(const Dimension & height)231     void SetHeight(const Dimension& height)
232     {
233         height_ = height;
234     }
235 
GetHeight()236     const Dimension& GetHeight() const
237     {
238         return height_;
239     }
240 
SetWidth(const Dimension & width)241     void SetWidth(const Dimension& width)
242     {
243         width_ = width;
244     }
245 
GetWidth()246     const Dimension& GetWidth() const
247     {
248         return width_;
249     }
250 
SetMargin(const Edge & margin)251     void SetMargin(const Edge& margin)
252     {
253         margin_ = margin;
254         isSetMargin_ = true;
255     }
256 
GetMargin()257     const Edge& GetMargin() const
258     {
259         return margin_;
260     }
261 
SetIsDragable(bool isDragable)262     void SetIsDragable(bool isDragable)
263     {
264         dragable_ = isDragable;
265     }
266 
IsDragable()267     bool IsDragable() const
268     {
269         return dragable_;
270     }
271 
IsSetMargin()272     bool IsSetMargin() const
273     {
274         return isSetMargin_;
275     }
276 
277     // used for inspector node in PC preview
SetCustomDialogId(int32_t dialogId)278     void SetCustomDialogId(int32_t dialogId)
279     {
280         customDialogId_ = dialogId;
281     }
282 
SetIsMenu(bool isMenu)283     void SetIsMenu(bool isMenu)
284     {
285         isMenu_ = isMenu;
286     }
287 
SetDialogProperties(const DialogProperties & properties)288     void SetDialogProperties(const DialogProperties& properties)
289     {
290         properties_ = properties;
291     }
292 
GetDialogProperties()293     const DialogProperties& GetDialogProperties() const
294     {
295         return properties_;
296     }
297 
HasStopListenerAdded()298     bool HasStopListenerAdded() const
299     {
300         return hasStopListenerAdded_;
301     }
302 
SetHasStopListenerAdded(bool hasStopListenerAdded)303     void SetHasStopListenerAdded(bool hasStopListenerAdded)
304     {
305         hasStopListenerAdded_ = hasStopListenerAdded;
306     }
307 
308 protected:
309     static int32_t GenerateDialogId();
310 
311     RefPtr<BoxComponent> BuildBox(bool& isLimit);
312     void BuildFocusChild(const RefPtr<Component>& child, const RefPtr<FocusCollaborationComponent>& collaboration);
313     void BuildTitle(const RefPtr<ColumnComponent>& column);
314     virtual void BuildContent(const RefPtr<ColumnComponent>& column);
315     virtual void BuildActions(const RefPtr<ThemeManager>& themeManager, const RefPtr<ColumnComponent>& column);
316     void BuildActionsForWatch(const RefPtr<ColumnComponent>& column);
317     virtual void BuildMenu(const RefPtr<ColumnComponent>& column);
318     RefPtr<Component> BuildButton(const RefPtr<ButtonComponent>& button, const EventMarker& callbackId,
319         const Edge& edge, bool isAutoFocus = false);
320     RefPtr<TransitionComponent> BuildAnimation(const RefPtr<BoxComponent>& child);
321     RefPtr<TransitionComponent> BuildAnimationForPhone(const RefPtr<Component>& child);
322     RefPtr<Component> GenerateComposed(
323         const std::string& name, const RefPtr<Component>& child, bool isDialogTweenChild);
324     void BuildDialogTween(const RefPtr<TransitionComponent>& transition, bool isLimit, Edge margin);
325     RefPtr<Component> BuildDivider(const RefPtr<ThemeManager>& themeManager);
326     void BuildDragBar(const RefPtr<FocusCollaborationComponent>& collaboration);
327 
328     std::string data_; // date is used for accessibility.
329     int32_t dialogId_ = -1;
330     int32_t dialogTweenComposedId_ = 0;
331     RefPtr<TextComponent> title_;
332     Edge titlePadding_;
333     RefPtr<TextComponent> content_;
334     Edge contentPadding_;
335     bool autoCancel_ = true;
336     Color backgroundColor_;
337     std::list<RefPtr<ButtonComponent>> actions_;
338     RefPtr<DialogTheme> dialogTheme_;
339     RefPtr<DialogTweenComponent> dialogTween_;
340     RefPtr<BoxComponent> dialogTweenBox_;
341     RefPtr<Animator> animator_;
342     EventMarker onSuccessId_;
343     EventMarker onCancelId_;
344     EventMarker onCompleteId_;
345     EventMarker onPositiveSuccessId_ = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
346     EventMarker onNegativeSuccessId_ = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
347     EventMarker onNeutralSuccessId_ = BackEndEventManager<void()>::GetInstance().GetAvailableMarker();
348     std::vector<EventMarker> menuSuccessId_;
349     WeakPtr<PipelineContext> context_;
350     DeviceType deviceType_ = DeviceType::PHONE;
351     bool isDeviceTypeSet_ = false;
352     bool isMenu_ = false;
353     bool dragable_ = false;
354     DialogProperties properties_;
355 
356     RefPtr<Component> customComponent_;
357     Dimension height_;
358     Dimension width_;
359     Edge margin_;
360     bool isSetMargin_ = false;
361     bool hasStopListenerAdded_ = false;
362     // used for inspector node in PC preview
363     int32_t customDialogId_ = -1;
364 };
365 
366 class DialogBuilder {
367 public:
368     static RefPtr<DialogComponent> Build(
369         const DialogProperties& dialogProperties, const WeakPtr<PipelineContext>& context);
370 
371 private:
372     static RefPtr<DialogComponent> BuildDialogWithType(DialogType type);
373     static void BuildTitleAndContent(const RefPtr<DialogComponent>& dialog, const DialogProperties& dialogProperties,
374         const RefPtr<DialogTheme>& dialogTheme, std::string& data);
375     static void BuildButtons(const RefPtr<ThemeManager>& themeManager, const RefPtr<DialogComponent>& dialog,
376         const std::vector<ButtonInfo>& buttons, const RefPtr<DialogTheme>& dialogTheme,
377         std::string& data);
378     static void BuildButtonsForWatch(
379         const RefPtr<ThemeManager>& themeManager, const RefPtr<DialogComponent>& dialog, std::string& data);
380     static RefPtr<DialogComponent> BuildAnimation(
381         const RefPtr<DialogComponent>& dialogChild, const RefPtr<DialogTheme>& dialogTheme);
382 };
383 
384 } // namespace OHOS::Ace
385 
386 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_DIALOG_DIALOG_COMPONENT_H
387