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_PAGE_TRANSITION_PAGE_TRANSITION_COMPONENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PAGE_TRANSITION_PAGE_TRANSITION_COMPONENT_H
18 
19 #include <stack>
20 
21 #include "core/components/box/box_component.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/common/properties/alignment.h"
24 #include "core/components/page_transition/page_transition_element.h"
25 #include "core/components/page_transition/page_transition_info.h"
26 #include "core/components/stack/stack_component.h"
27 #include "core/components/tween/tween_component.h"
28 
29 namespace OHOS::Ace {
30 
31 class ACE_EXPORT PageTransitionComponent : public StackComponent {
32     DECLARE_ACE_TYPE(PageTransitionComponent, StackComponent);
33 
34 public:
PageTransitionComponent()35     PageTransitionComponent()
36         : StackComponent(Alignment::TOP_LEFT, StackFit::INHERIT, Overflow::CLIP, std::list<RefPtr<Component>>())
37     {}
38 
39     ~PageTransitionComponent() override = default;
40 
CreateElement()41     RefPtr<Element> CreateElement() override
42     {
43         return AceType::MakeRefPtr<PageTransitionElement>();
44     }
45 
46     RefPtr<RenderNode> CreateRenderNode() override;
47 
48     // set page background box. set background, width and height in BoxComponent and set it
SetBackground(const RefPtr<BoxComponent> & background)49     void SetBackground(const RefPtr<BoxComponent>& background)
50     {
51         if (!background) {
52             LOGE("background is empty when set back decoration.");
53             return;
54         }
55         background_ = background;
56     }
57 
58     // get the user's background box
GetBackground()59     const RefPtr<BoxComponent>& GetBackground() const
60     {
61         return background_;
62     }
63 
64     // set page content component, usually begin with StackComponent
SetContent(const RefPtr<Component> & content)65     void SetContent(const RefPtr<Component>& content)
66     {
67         if (!content) {
68             LOGE("content is empty when set content.");
69             return;
70         }
71         content_ = content;
72     }
73 
74     // get the user's content box
GetContent()75     const RefPtr<Component>& GetContent() const
76     {
77         return content_;
78     }
79 
SetContentTransitionOption(const TweenOption & in,const TweenOption & out)80     void SetContentTransitionOption(const TweenOption& in, const TweenOption& out)
81     {
82         isSetOption_ = true;
83         contentInOption_ = in;
84         contentOutOption_ = out;
85     }
86 
GetContentTransitionInOption()87     const TweenOption& GetContentTransitionInOption() const
88     {
89         return contentInOption_;
90     }
91 
GetContentTransitionOutOption()92     const TweenOption& GetContentTransitionOutOption() const
93     {
94         return contentOutOption_;
95     }
96 
97     // element only support page now
HasTransitionComponent(const RefPtr<Component> & component)98     static bool HasTransitionComponent(const RefPtr<Component>& component)
99     {
100         // first try with page element.
101         RefPtr<PageComponent> pageComponent = AceType::DynamicCast<PageComponent>(component);
102         if (!pageComponent) {
103             LOGW("Page is null.");
104             return false;
105         }
106         return AceType::InstanceOf<PageTransitionComponent>(pageComponent->GetChild());
107     }
108 
SetSeparation(bool isSeparate)109     void SetSeparation(bool isSeparate)
110     {
111         isSeparation_ = isSeparate;
112     }
113 
GetSeparation()114     bool GetSeparation() const
115     {
116         return isSeparation_;
117     }
118 
GetIsSetOption()119     bool GetIsSetOption() const
120     {
121         return isSetOption_;
122     }
123 
PushPageTransition(const RefPtr<PageTransition> & pageTransition)124     void PushPageTransition(const RefPtr<PageTransition>& pageTransition)
125     {
126         pageTransitionStack_.push(pageTransition);
127     }
128 
PopPageTransition()129     void PopPageTransition()
130     {
131         if (pageTransitionStack_.empty()) {
132             return;
133         }
134         auto pageTransition = pageTransitionStack_.top();
135         pageTransitionStack_.pop();
136         if (pageTransition) {
137             PageTransition::ProcessPageTransitionType(pageTransition);
138             pageTransitions_[pageTransition->GetType()] = pageTransition;
139         }
140     }
141 
ClearPageTransitionStack()142     void ClearPageTransitionStack()
143     {
144         while (!pageTransitionStack_.empty()) {
145             auto pageTransition = pageTransitionStack_.top();
146             if (pageTransition) {
147                 PageTransition::ProcessPageTransitionType(pageTransition);
148                 pageTransitions_[pageTransition->GetType()] = pageTransition;
149             }
150             pageTransitionStack_.pop();
151         }
152     }
153 
ClearPageTransition()154     void ClearPageTransition()
155     {
156         ClearPageTransitionStack();
157         pageTransitions_.clear();
158     }
159 
GetTopPageTransition()160     RefPtr<PageTransition> GetTopPageTransition()
161     {
162         if (pageTransitionStack_.empty()) {
163             return nullptr;
164         }
165         return pageTransitionStack_.top();
166     }
167 
GetPageTransitions()168     const std::unordered_map<PageTransitionType, RefPtr<PageTransition>>& GetPageTransitions() const
169     {
170         return pageTransitions_;
171     }
172 
173 private:
174     bool isSetOption_ = false;
175     bool isSeparation_ = false;       // true means that the content of the page is separated from the background
176     RefPtr<Component> content_;       // page content component, will be wrapped with animation component
177     RefPtr<BoxComponent> background_; // page background box, will be wrapped with animation component
178     TweenOption contentInOption_;
179     TweenOption contentOutOption_;
180     std::unordered_map<PageTransitionType, RefPtr<PageTransition>> pageTransitions_;
181     std::stack<RefPtr<PageTransition>> pageTransitionStack_;
182 };
183 
184 } // namespace OHOS::Ace
185 
186 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PAGE_TRANSITION_PAGE_TRANSITION_COMPONENT_H
187