1 /*
2  * Copyright (c) 2021-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_ELEMENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_ELEMENT_H
18 
19 #include <list>
20 
21 #include "base/utils/macros.h"
22 #include "core/focus/focus_node.h"
23 #include "core/gestures/gesture_recognizer.h"
24 #include "core/pipeline/base/component.h"
25 #include "core/pipeline/base/element_register.h"
26 #include "core/pipeline/base/render_node.h"
27 
28 namespace OHOS::Ace {
29 
30 class PageElement;
31 class PipelineContext;
32 
33 // If no insertion location is specified, new child will be added to the end of children list by default.
34 constexpr int32_t DEFAULT_ELEMENT_SLOT = -1;
35 constexpr int32_t DEFAULT_RENDER_SLOT = -1;
36 
37 // Element is the key class in the UI framework, which presents a basic logic
38 // unit to construct a view hierarchy.
39 // There are two types inherited element: RenderElement and ComposedElement.
40 class ACE_EXPORT Element : public virtual AceType {
41     DECLARE_ACE_TYPE(Element, AceType);
42 
43 public:
44     Element() = default;
45     ~Element();
46 
47     void AddChild(const RefPtr<Element>& child, int32_t slot = DEFAULT_ELEMENT_SLOT);
48     void RemoveChild(const RefPtr<Element>& child);
49     RefPtr<Element> GetChildBySlot(int32_t slot);
50     void DeactivateChild(RefPtr<Element> child);
51     void Rebuild();
52 
53     // create a new child element and mount to element tree.
54     RefPtr<Element> InflateComponent(const RefPtr<Component>& newComponent, int32_t slot, int32_t renderSlot);
55     void Mount(
56         const RefPtr<Element>& parent, int32_t slot = DEFAULT_ELEMENT_SLOT, int32_t renderSlot = DEFAULT_RENDER_SLOT);
57     void AddToFocus();
58     virtual RefPtr<Element> UpdateChild(const RefPtr<Element>& child, const RefPtr<Component>& newComponent) = 0;
59     RefPtr<Element> UpdateChildWithSlot(
60         const RefPtr<Element>& child, const RefPtr<Component>& newComponent, int32_t slot, int32_t renderSlot);
61 
62     void DetachChild(const RefPtr<Element>&);
63     RefPtr<Element> RetakeDeactivateElement(const RefPtr<Component>& newComponent);
64 
OnMount()65     virtual void OnMount() {}
Detached()66     virtual void Detached() {}
Activate()67     virtual void Activate() {}
Deactivate()68     virtual void Deactivate() {}
UmountRender()69     virtual void UmountRender() {}
Prepare(const WeakPtr<Element> & parent)70     virtual void Prepare(const WeakPtr<Element>& parent) {}
PerformBuild()71     virtual void PerformBuild() {}
Update()72     virtual void Update() {}
73     virtual void DumpTree(int32_t depth);
74     virtual void Dump();
75     virtual bool CanUpdate(const RefPtr<Component>& newComponent);
76 
77     virtual void MarkDirty();
78 
NeedUpdateWithComponent(const RefPtr<Component> & newComponent)79     virtual bool NeedUpdateWithComponent(const RefPtr<Component>& newComponent)
80     {
81         return true;
82     }
83 
84     void SetUpdateComponent(const RefPtr<Component>& newComponent);
85 
NeedUpdate()86     bool NeedUpdate() const
87     {
88         return component_ != nullptr;
89     }
90 
SetDepth(int32_t depth)91     void SetDepth(int32_t depth)
92     {
93         depth_ = depth;
94     }
95 
GetDepth()96     int32_t GetDepth() const
97     {
98         return depth_;
99     }
100 
101     void SetPipelineContext(const WeakPtr<PipelineContext>& context);
102 
103     enum ElementType {
104         BASE_ELEMENT,
105         RENDER_ELEMENT,
106         COMPOSED_ELEMENT,
107     };
108 
GetType()109     virtual ElementType GetType() const
110     {
111         return type_;
112     }
113 
SetNewComponent(const RefPtr<Component> & newComponent)114     virtual void SetNewComponent(const RefPtr<Component>& newComponent)
115     {
116         component_ = newComponent;
117         if (newComponent) {
118             retakeId_ = newComponent->GetRetakeId();
119             componentTypeId_ = AceType::TypeId(component_);
120             ignoreInspector_ = newComponent->IsIgnoreInspector();
121             SetElementId(newComponent->GetElementId());
122             MarkNeedRebuild();
123         }
124     }
125 
126     RefPtr<FocusGroup> GetFocusScope();
127 
128     RefPtr<Element> GetFirstChild() const;
129     RefPtr<Element> GetLastChild() const;
130 
GetRenderNode()131     virtual RefPtr<RenderNode> GetRenderNode() const
132     {
133         if (children_.empty()) {
134             return nullptr;
135         } else {
136             return children_.front()->GetRenderNode();
137         }
138     }
139 
GetRenderRect()140     Rect GetRenderRect() const
141     {
142         auto renderNode = GetRenderNode();
143         if (renderNode) {
144             return renderNode->GetHidden() ? Rect() : renderNode->GetRectBasedWindowTopLeft();
145         }
146         return Rect();
147     }
148 
GetRenderRectInLocal()149     Rect GetRenderRectInLocal() const
150     {
151         auto renderNode = GetRenderNode();
152         if (renderNode) {
153             return renderNode->GetPaintRect();
154         }
155         return Rect();
156     }
157 
158     const std::list<RefPtr<Element>>& GetChildren() const;
159 
GetContext()160     const WeakPtr<PipelineContext>& GetContext() const
161     {
162         return context_;
163     }
164 
SetSlot(int32_t slot)165     void SetSlot(int32_t slot)
166     {
167         slot_ = slot;
168     }
169 
GetSlot()170     int32_t GetSlot() const
171     {
172         return slot_;
173     }
174 
SetRenderSlot(int32_t slot)175     void SetRenderSlot(int32_t slot)
176     {
177         renderSlot_ = slot;
178     }
179 
GetRenderSlot()180     int32_t GetRenderSlot() const
181     {
182         return renderSlot_;
183     }
184 
185     virtual int32_t CountRenderNode() const = 0;
186 
GetElementParent()187     const WeakPtr<Element>& GetElementParent() const
188     {
189         return parent_;
190     }
191 
192     RefPtr<PageElement> GetPageElement();
193 
IsAutoAccessibility()194     bool IsAutoAccessibility() const
195     {
196         return autoAccessibility_;
197     }
198 
SetAutoAccessibility(bool value)199     void SetAutoAccessibility(bool value)
200     {
201         autoAccessibility_ = value;
202     }
203 
SetRetakeId(int32_t retakeId)204     void SetRetakeId(int32_t retakeId)
205     {
206         retakeId_ = retakeId;
207     }
208 
GetRetakeId()209     int32_t GetRetakeId() const
210     {
211         return retakeId_;
212     }
213 
GetComponent()214     RefPtr<Component> GetComponent() const
215     {
216         return component_;
217     }
218 
219     void RebuildFocusTree();
220 
221     std::list<RefPtr<FocusNode>> RebuildFocusChild();
222 
SetParent(const WeakPtr<Element> & parent)223     void SetParent(const WeakPtr<Element>& parent)
224     {
225         parent_ = parent;
226     }
227 
228 #if defined(PREVIEW)
GetChildrenSize()229     int32_t GetChildrenSize() {
230         return children_.size();
231     }
232 #endif
233 
MarkNeedRebuild()234     void MarkNeedRebuild()
235     {
236         needRebuild_ = true;
237     }
238 
IsActive()239     bool IsActive() const
240     {
241         return active_;
242     }
243 
SetIgnoreInspector(bool ignoreInspector)244     void SetIgnoreInspector(bool ignoreInspector)
245     {
246         ignoreInspector_ = ignoreInspector;
247     }
248 
IsIgnoreInspector()249     bool IsIgnoreInspector() const
250     {
251         return ignoreInspector_;
252     }
253 
254     /* extra public members for partial update */
255 
256     /**
257      * perform a localized update with given pair of Components
258      * uses virtual LocalizedUpdate() for each Component to Element update
259      * in the chain mainComponent .... > parent > ... outmostWrappingComponent
260      */
261     void LocalizedUpdateWithComponent(
262         const RefPtr<Component>& newComponent, const RefPtr<Component>& outmostWrappingComponent);
263 
264     /*
265      * Element gets the elmtId from the
266      * Component on creation, never changes
267      * afterwards.
268      */
269     void SetElementId(int32_t elmtId);
GetElementId()270     int32_t GetElementId() const
271     {
272         return elmtId_;
273     }
274 
275     /**
276      * perform Component to Element localized update on 'this'
277      * does not recurse to children.
278      */
279     virtual void LocalizedUpdate();
280 
281     virtual void UnregisterForPartialUpdates();
282     void UnregisterChildrenForPartialUpdates();
283 
284 protected:
285     inline RefPtr<Element> DoUpdateChildWithNewComponent(
286         const RefPtr<Element>& child, const RefPtr<Component>& newComponent, int32_t slot, int32_t renderSlot);
287 
288     virtual void Apply(const RefPtr<Element>& child) = 0;
289 
OnContextAttached()290     virtual void OnContextAttached() {}
291 
292     void MarkActive(bool active);
293 
OnActive()294     virtual void OnActive() {}
295 
OnInactive()296     virtual void OnInactive() {}
297 
GetThemeManager()298     RefPtr<ThemeManager> GetThemeManager() const
299     {
300         auto context = context_.Upgrade();
301         if (!context) {
302             return nullptr;
303         }
304         return context->GetThemeManager();
305     }
306 
307     ElementType type_ = BASE_ELEMENT;
308     std::list<RefPtr<Element>> children_;
309     RefPtr<Component> component_;
310     WeakPtr<PipelineContext> context_;
311     IdType componentTypeId_ = 0;
312     bool active_ = false;
313 
314 protected:
315     void ChangeChildSlot(const RefPtr<Element>& child, int32_t slot);
316     void ChangeChildRenderSlot(const RefPtr<Element>& child, int32_t renderSlot, bool effectDescendant);
317 
318 private:
319     WeakPtr<Element> parent_;
320     int32_t depth_ = 0;
321     int32_t slot_ = DEFAULT_ELEMENT_SLOT;
322     int32_t renderSlot_ = DEFAULT_RENDER_SLOT;
323     bool autoAccessibility_ = true;
324     bool needRebuild_ = false;
325     // One-to-one correspondence with component through retakeId
326     int32_t retakeId_ = 0;
327     bool ignoreInspector_ = false;
328 
329 private:
330     // globally unique id for Elements, used by partial update
331     int32_t elmtId_ = ElementRegister::UndefinedElementId;
332 };
333 
334 } // namespace OHOS::Ace
335 
336 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_ELEMENT_H
337