• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_BASE_UI_NODE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_UI_NODE_H
18 
19 #include <cstdint>
20 #include <list>
21 #include <memory>
22 #include <string>
23 #include <unordered_map>
24 
25 #include "base/geometry/ng/point_t.h"
26 #include "base/log/ace_performance_check.h"
27 #include "base/memory/ace_type.h"
28 #include "base/memory/referenced.h"
29 #include "base/utils/macros.h"
30 #include "core/components_ng/event/focus_hub.h"
31 #include "core/components_ng/event/gesture_event_hub.h"
32 #include "core/components_ng/layout/layout_wrapper.h"
33 #include "core/components_ng/layout/layout_wrapper_node.h"
34 #include "core/event/touch_event.h"
35 
36 namespace OHOS::Ace::NG {
37 
38 class PipelineContext;
39 constexpr int32_t DEFAULT_NODE_SLOT = -1;
40 
41 // UINode is the base class of FrameNode and SyntaxNode.
42 class ACE_EXPORT UINode : public virtual AceType {
43     DECLARE_ACE_TYPE(UINode, AceType);
44 
45 public:
46     UINode(const std::string& tag, int32_t nodeId, bool isRoot = false);
47     ~UINode() override;
48 
49     // atomic node is like button, image, custom node and so on.
50     // In ets UI compiler, the atomic node does not Add Pop function, only have Create function.
51     virtual bool IsAtomicNode() const = 0;
52 
53     virtual int32_t FrameCount() const;
54 
55     virtual RefPtr<LayoutWrapperNode> CreateLayoutWrapper(bool forceMeasure = false, bool forceLayout = false);
56 
57     // Tree operation start.
58     void AddChild(const RefPtr<UINode>& child, int32_t slot = DEFAULT_NODE_SLOT, bool silently = false);
59     std::list<RefPtr<UINode>>::iterator RemoveChild(const RefPtr<UINode>& child, bool allowTransition = false);
60     int32_t RemoveChildAndReturnIndex(const RefPtr<UINode>& child);
61     void ReplaceChild(const RefPtr<UINode>& oldNode, const RefPtr<UINode>& newNode);
62     void MovePosition(int32_t slot);
63     void MountToParent(const RefPtr<UINode>& parent, int32_t slot = DEFAULT_NODE_SLOT, bool silently = false);
64     RefPtr<FrameNode> GetFocusParent() const;
65     RefPtr<FocusHub> GetFirstFocusHubChild() const;
66     void GetFocusChildren(std::list<RefPtr<FrameNode>>& children) const;
67     void Clean(bool cleanDirectly = false, bool allowTransition = false);
68     void RemoveChildAtIndex(int32_t index);
69     RefPtr<UINode> GetChildAtIndex(int32_t index) const;
70     int32_t GetChildIndex(const RefPtr<UINode>& child) const;
71     void AttachToMainTree(bool recursive = false);
72     void DetachFromMainTree(bool recursive = false);
73     void UpdateConfigurationUpdate(const OnConfigurationChange& configurationChange);
OnConfigurationUpdate(const OnConfigurationChange & configurationChange)74     virtual void OnConfigurationUpdate(const OnConfigurationChange& configurationChange) {}
75 
76     // process offscreen process.
77     void ProcessOffscreenTask(bool recursive = false);
78 
79     int32_t TotalChildCount() const;
80 
81     // Returns index in the flatten tree structure
82     // of the node with given id and type
83     // Returns std::pair with
84     // boolean first - indication of node is found
85     // int32_t second - index of the node
86     std::pair<bool, int32_t> GetChildFlatIndex(int32_t id);
87 
GetChildren()88     virtual const std::list<RefPtr<UINode>>& GetChildren() const
89     {
90         return children_;
91     }
92 
GetLastChild()93     RefPtr<UINode> GetLastChild()
94     {
95         if (children_.empty()) {
96             return nullptr;
97         }
98         return children_.back();
99     }
100 
GetFirstChild()101     RefPtr<UINode> GetFirstChild()
102     {
103         if (children_.empty()) {
104             return nullptr;
105         }
106         return children_.front();
107     }
108 
109     void GenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& visibleList);
110     void GenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList);
111     void GenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>>& visibleList);
112 
113     int32_t GetChildIndexById(int32_t id);
114 
GetParent()115     RefPtr<UINode> GetParent() const
116     {
117         return parent_.Upgrade();
118     }
119 
SetNeedCallChildrenUpdate(bool needCallChildrenUpdate)120     void SetNeedCallChildrenUpdate(bool needCallChildrenUpdate)
121     {
122         needCallChildrenUpdate_ = needCallChildrenUpdate;
123     }
124 
SetParent(const WeakPtr<UINode> & parent)125     void SetParent(const WeakPtr<UINode>& parent)
126     {
127         parent_ = parent;
128     }
129     // Tree operation end.
130 
131     static RefPtr<PipelineContext> GetContext();
132 
133     // When FrameNode creates a layout task, the corresponding LayoutWrapper tree is created, and UINode needs to update
134     // the corresponding LayoutWrapper tree node at this time like add self wrapper to wrapper tree.
135     virtual void AdjustLayoutWrapperTree(const RefPtr<LayoutWrapperNode>& parent, bool forceMeasure, bool forceLayout);
136 
137     // DFX info.
138     void DumpTree(int32_t depth);
139 
GetTag()140     const std::string& GetTag() const
141     {
142         return tag_;
143     }
144 
GetId()145     int32_t GetId() const
146     {
147         return nodeId_;
148     }
149 
GetAccessibilityId()150     int32_t GetAccessibilityId() const
151     {
152         return accessibilityId_;
153     }
154 
SetDepth(int32_t depth)155     void SetDepth(int32_t depth)
156     {
157         depth_ = depth;
158         for (auto& child : children_) {
159             child->SetDepth(depth_ + 1);
160         }
161     }
162 
IsRootNode()163     bool IsRootNode() const
164     {
165         return isRoot_;
166     }
167 
GetDepth()168     int32_t GetDepth() const
169     {
170         return depth_;
171     }
172 
GetRootId()173     int32_t GetRootId() const
174     {
175         return hostRootId_;
176     }
177 
GetPageId()178     int32_t GetPageId() const
179     {
180         return hostPageId_;
181     }
182 
183     // TODO: SetHostRootId step on create node.
SetHostRootId(int32_t id)184     void SetHostRootId(int32_t id)
185     {
186         hostRootId_ = id;
187     }
188 
189     // TODO: SetHostPageId step on mount to page.
SetHostPageId(int32_t id)190     void SetHostPageId(int32_t id)
191     {
192         hostPageId_ = id;
193         for (auto& child : children_) {
194             child->SetHostPageId(id);
195         }
196     }
197 
SetRemoveSilently(bool removeSilently)198     void SetRemoveSilently(bool removeSilently)
199     {
200         removeSilently_ = removeSilently;
201     }
202 
SetUndefinedNodeId()203     void SetUndefinedNodeId()
204     {
205         nodeId_ = -1;
206     }
207 
IsRemoving()208     bool IsRemoving() const
209     {
210         return isRemoving_;
211     }
212 
GetLayoutPriority()213     int32_t GetLayoutPriority() const
214     {
215         return layoutPriority_;
216     }
217 
SetLayoutPriority(int32_t priority)218     void SetLayoutPriority(int32_t priority)
219     {
220         layoutPriority_ = priority;
221     }
222 
SetInDestroying()223     void SetInDestroying()
224     {
225         isInDestroying_ = true;
226     }
227 
IsInDestroying()228     bool IsInDestroying() const
229     {
230         return isInDestroying_;
231     }
232 
233     void SetChildrenInDestroying();
234 
235     virtual HitTestResult TouchTest(const PointF& globalPoint, const PointF& parentLocalPoint,
236         const PointF& parentRevertPoint, const TouchRestrict& touchRestrict,
237         TouchTestResult& result, int32_t touchId);
GetHitTestMode()238     virtual HitTestMode GetHitTestMode() const
239     {
240         return HitTestMode::HTMDEFAULT;
241     }
242 
243     virtual HitTestResult MouseTest(const PointF& globalPoint, const PointF& parentLocalPoint,
244         MouseTestResult& onMouseResult, MouseTestResult& onHoverResult, RefPtr<FrameNode>& hoverNode);
245 
246     virtual HitTestResult AxisTest(
247         const PointF& globalPoint, const PointF& parentLocalPoint, AxisTestResult& onAxisResult);
248 
249     // In the request to re-layout the scene, needs to obtain the changed state of the child node for the creation
250     // of parent's layout wrapper
251     virtual void UpdateLayoutPropertyFlag();
252 
ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag)253     virtual void ForceUpdateLayoutPropertyFlag(PropertyChangeFlag propertyChangeFlag) {}
254 
255     virtual void AdjustParentLayoutFlag(PropertyChangeFlag& flag);
256 
257     virtual void MarkDirtyNode(PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL);
258 
259     virtual void MarkNeedFrameFlushDirty(PropertyChangeFlag extraFlag = PROPERTY_UPDATE_NORMAL);
260 
FlushUpdateAndMarkDirty()261     virtual void FlushUpdateAndMarkDirty()
262     {
263         for (const auto& child : children_) {
264             child->FlushUpdateAndMarkDirty();
265         }
266     }
267 
268     virtual void MarkNeedSyncRenderTree(bool needRebuild = false);
269 
270     virtual void RebuildRenderContextTree();
271 
OnWindowShow()272     virtual void OnWindowShow() {}
273 
OnWindowHide()274     virtual void OnWindowHide() {}
275     virtual void Build();
276 
OnWindowFocused()277     virtual void OnWindowFocused() {}
278 
OnWindowUnfocused()279     virtual void OnWindowUnfocused() {}
280 
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)281     virtual void OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type) {}
282 
OnNotifyMemoryLevel(int32_t level)283     virtual void OnNotifyMemoryLevel(int32_t level) {}
284 
285     virtual void SetActive(bool active);
286 
287     virtual void SetJSViewActive(bool active);
288 
289     virtual void OnVisibleChange(bool isVisible);
290 
291     virtual bool MarkRemoving();
292 
IsOnMainTree()293     bool IsOnMainTree() const
294     {
295         return onMainTree_;
296     }
297 
UseOffscreenProcess()298     bool UseOffscreenProcess() const
299     {
300         return useOffscreenProcess_;
301     }
302 
ToJsonValue(std::unique_ptr<JsonValue> & json)303     virtual void ToJsonValue(std::unique_ptr<JsonValue>& json) const {}
304 
FromJson(const std::unique_ptr<JsonValue> & json)305     virtual void FromJson(const std::unique_ptr<JsonValue>& json) {}
306 
307     ACE_DEFINE_PROPERTY_ITEM_FUNC_WITHOUT_GROUP(InspectorId, std::string);
OnInspectorIdUpdate(const std::string &)308     virtual void OnInspectorIdUpdate(const std::string& /*unused*/) {}
309 
310     template<typename T>
FindChildNodeOfClass()311     RefPtr<T> FindChildNodeOfClass()
312     {
313         const auto& children = GetChildren();
314         for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
315             auto& child = *iter;
316 
317             auto target = child->FindChildNodeOfClass<T>();
318             if (target) {
319                 return target;
320             }
321         }
322 
323         RefPtr<UINode> uiNode = AceType::Claim<UINode>(this);
324         if (AceType::InstanceOf<T>(uiNode)) {
325             return AceType::DynamicCast<T>(uiNode);
326         }
327         return nullptr;
328     }
329 
330     void ChildrenUpdatedFrom(int32_t index);
GetChildrenUpdated()331     int32_t GetChildrenUpdated() const
332     {
333         return childrenUpdatedFrom_;
334     }
335 
336     // utility function for adding child to disappearingChildren_
337     void AddDisappearingChild(const RefPtr<UINode>& child, uint32_t index = UINT32_MAX);
338     // utility function for removing child from disappearingChildren_, return true if child is removed
339     bool RemoveDisappearingChild(const RefPtr<UINode>& child);
340     // return if we are in parent's disappearing children
IsDisappearing()341     bool IsDisappearing() const
342     {
343         return isDisappearing_;
344     }
345     RefPtr<UINode> GetDisappearingChildById(const std::string& id) const;
346 
347     // These two interfaces are only used for fast preview.
348     // FastPreviewUpdateChild: Replace the old child at the specified slot with the new created node.
349     // FastPreviewUpdateChildDone: the new created node performs some special operations.
FastPreviewUpdateChild(int32_t slot,const RefPtr<UINode> & newChild)350     virtual void FastPreviewUpdateChild(int32_t slot, const RefPtr<UINode>& newChild)
351     {
352         RemoveChildAtIndex(slot);
353         newChild->MountToParent(AceType::Claim(this), slot, false);
354     }
FastPreviewUpdateChildDone()355     virtual void FastPreviewUpdateChildDone() {}
356     virtual RefPtr<UINode> GetFrameChildByIndex(uint32_t index, bool needBuild);
357 
358 #ifdef PREVIEW
SetDebugLine(const std::string & line)359     void SetDebugLine(const std::string& line)
360     {
361         debugLine_ = line;
362     }
GetDebugLine()363     std::string GetDebugLine() const
364     {
365         return debugLine_;
366     }
367 
SetViewId(const std::string & viewId)368     void SetViewId(const std::string& viewId)
369     {
370         viewId_ = viewId;
371     }
372 
GetViewId()373     std::string GetViewId() const
374     {
375         return viewId_;
376     }
377 #endif
378 
SetRestoreId(int32_t restoreId)379     void SetRestoreId(int32_t restoreId)
380     {
381         restoreId_ = restoreId;
382     }
383 
GetRestoreId()384     int32_t GetRestoreId()
385     {
386         return restoreId_;
387     }
388 
UpdateRecycleElmtId(int32_t newElmtId)389     void UpdateRecycleElmtId(int32_t newElmtId)
390     {
391         nodeId_ = newElmtId;
392     }
393 
394     // --------------------------------------------------------------------------------
395     // performance check get child count, depth, flex layout times and layout time
396     void GetPerformanceCheckData(PerformanceCheckNodeMap& nodeMap);
SetLayoutTime(int64_t time)397     void SetLayoutTime(int64_t time)
398     {
399         if (nodeInfo_) {
400             nodeInfo_->layoutTime = time;
401         }
402     }
GetLayoutTime()403     int64_t GetLayoutTime()
404     {
405         if (nodeInfo_) {
406             return nodeInfo_->layoutTime;
407         }
408         return 0;
409     }
GetFlexLayouts()410     int32_t GetFlexLayouts()
411     {
412         if (nodeInfo_) {
413             return nodeInfo_->flexLayouts;
414         }
415         return 0;
416     }
GetRow()417     int32_t GetRow() const
418     {
419         if (nodeInfo_) {
420             return nodeInfo_->codeRow;
421         }
422         return 0;
423     }
GetCol()424     int32_t GetCol() const
425     {
426         if (nodeInfo_) {
427             return nodeInfo_->codeCol;
428         }
429         return 0;
430     }
SetRow(const int32_t row)431     void SetRow(const int32_t row)
432     {
433         if (nodeInfo_) {
434             nodeInfo_->codeRow = row;
435         }
436     }
SetCol(const int32_t col)437     void SetCol(const int32_t col)
438     {
439         if (nodeInfo_) {
440             nodeInfo_->codeCol = col;
441         }
442     }
SetForeachItem()443     void SetForeachItem()
444     {
445         if (nodeInfo_) {
446             nodeInfo_->isForEachItem = true;
447         }
448     }
AddFlexLayouts()449     void AddFlexLayouts()
450     {
451         if (nodeInfo_) {
452             nodeInfo_->flexLayouts++;
453         }
454     }
GetCustomTag()455     virtual std::string GetCustomTag()
456     {
457         return GetTag();
458     }
SetBuildByJs(bool isBuildByJS)459     void SetBuildByJs(bool isBuildByJS)
460     {
461         isBuildByJS_ = isBuildByJS;
462     }
AddAttachToMainTreeTask(std::function<void ()> && func)463     void AddAttachToMainTreeTask(std::function<void()>&& func)
464     {
465         attachToMainTreeTasks_.emplace_back(std::move(func));
466     }
467 
468     // --------------------------------------------------------------------------------
469 
470     virtual void DoRemoveChildInRenderTree(uint32_t index, bool isAll = false);
471     virtual void OnSetCacheCount(int32_t cacheCount, const std::optional<LayoutConstraintF>& itemConstraint);
472 
473     // return value: true if the node can be removed immediately.
474     virtual bool OnRemoveFromParent(bool allowTransition);
475 
476 protected:
ModifyChildren()477     std::list<RefPtr<UINode>>& ModifyChildren()
478     {
479         return children_;
480     }
481 
OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>> & visibleList)482     virtual void OnGenerateOneDepthVisibleFrame(std::list<RefPtr<FrameNode>>& visibleList)
483     {
484         for (const auto& child : GetChildren()) {
485             child->OnGenerateOneDepthVisibleFrame(visibleList);
486         }
487     }
488 
489     virtual void OnGenerateOneDepthVisibleFrameWithTransition(std::list<RefPtr<FrameNode>>& visibleList);
490 
OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>> & allList)491     virtual void OnGenerateOneDepthAllFrame(std::list<RefPtr<FrameNode>>& allList)
492     {
493         for (const auto& child : GetChildren()) {
494             child->OnGenerateOneDepthAllFrame(allList);
495         }
496     }
497 
OnContextAttached()498     virtual void OnContextAttached() {}
499     // dump self info.
DumpInfo()500     virtual void DumpInfo() {}
501 
502     // Mount to the main tree to display.
503     virtual void OnAttachToMainTree(bool recursive = false);
504     virtual void OnDetachFromMainTree(bool recursive = false);
505 
506     // run offscreen process.
OnOffscreenProcess(bool recursive)507     virtual void OnOffscreenProcess(bool recursive) {}
508 
509     bool isRemoving_ = false;
510 
511     virtual bool RemoveImmediately() const;
512     void ResetParent();
513 
514     // update visible change signal to children
515     void UpdateChildrenVisible(bool isVisible) const;
516 
517 protected:
518     bool needCallChildrenUpdate_ = true;
519 
520 private:
521     void DoAddChild(std::list<RefPtr<UINode>>::iterator& it, const RefPtr<UINode>& child, bool silently = false,
522         bool allowTransition = true);
523 
524     std::list<RefPtr<UINode>> children_;
525     std::list<std::pair<RefPtr<UINode>, uint32_t>> disappearingChildren_;
526     std::unique_ptr<PerformanceCheckNode> nodeInfo_;
527     WeakPtr<UINode> parent_;
528     std::string tag_ = "UINode";
529     int32_t depth_ = 0;
530     int32_t hostRootId_ = 0;
531     int32_t hostPageId_ = 0;
532     int32_t nodeId_ = 0;
533     int32_t accessibilityId_ = -1;
534     int32_t layoutPriority_ = 0;
535     bool isRoot_ = false;
536     bool onMainTree_ = false;
537     bool removeSilently_ = true;
538     bool isInDestroying_ = false;
539     bool isDisappearing_ = false;
540     bool isBuildByJS_ = false;
541 
542     int32_t childrenUpdatedFrom_ = -1;
543     static thread_local int32_t currentAccessibilityId_;
544     int32_t restoreId_ = -1;
545 
546     bool useOffscreenProcess_ = false;
547 
548     std::list<std::function<void()>> attachToMainTreeTasks_;
549 
550 #ifdef PREVIEW
551     std::string debugLine_;
552     std::string viewId_;
553 #endif
554     friend class RosenRenderContext;
555     ACE_DISALLOW_COPY_AND_MOVE(UINode);
556 };
557 
558 } // namespace OHOS::Ace::NG
559 
560 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_BASE_UI_NODE_H
561