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